權重輪詢排程演算法(Weighted Round-Robin Scheduling)-C#實現
阿新 • • 發佈:2022-06-06
參考:https://www.cnblogs.com/yunh/p/3172716.html
/// <summary> /// 權重輪詢演算法 /// </summary> public static class WeightedRoundRobin { private static readonly List<Server> s = new List<Server>() { new Server() { IP = "192.168.0.100", Weight = 3 }, new Server() { IP = "192.168.0.101", Weight = 2 }, new Server() { IP = "192.168.0.102", Weight = 6 }, new Server() { IP = "192.168.0.103", Weight = 4 }, new Server() { IP = "192.168.0.104", Weight = 1 }, }.OrderBy(a => a.Weight).ToList(); private static int i = -1;//代表上一次選擇的伺服器 private static readonly int gcd = GetGcd(s);//表示集合S中所有伺服器權值的最大公約數 private static int cw = 0;//當前排程的權值 private static readonly int max = GetMaxWeight(s); private static readonly int n = s.Count;//伺服器個數 /** * 演算法流程: * 假設有一組伺服器 S = {S0, S1, …, Sn-1} (n>1)(Sn-1的權重<Sn的權重) * 變數i表示上次選擇的伺服器,如上次所選為權重最大伺服器,則本次所選為權重最小伺服器,所有伺服器權值的最大公約數為每次步長 * 權值cw初始化為0,i初始化為-1 ,當第一次的時候 權值取最大的那個伺服器, * 通過權重的不斷遞減 只要伺服器權重大於等於當前權重 則伺服器返回(即權重越大的伺服器,被選擇的機會越多),直到輪詢結束,權值返回為0 */ public static Server? GetServer() { while (true) { i = (i + 1) % n; if (i == 0) { cw -= gcd; if (cw <= 0) { cw = max; if (cw == 0) return default; } } if (s[i].Weight >= cw) { return s[i]; } } } /// <summary> /// 獲取伺服器所有權值的最大公約數 /// </summary> /// <param name="servers"></param> /// <returns></returns> private static int GetGcd(List<Server> servers) { return servers.Select(s => s.Weight).Aggregate(GCD); } private static int GCD(int a, int b) { return b == 0 ? Math.Abs(a) : GCD(b, a % b); } /// <summary> /// 獲取最大的權值 /// </summary> /// <param name="servers"></param> /// <returns></returns> private static int GetMaxWeight(List<Server> servers) { return servers.Max(s => s.Weight); } } /// <summary> /// 伺服器結構 /// </summary> public class Server { public string? IP; public int Weight; } class Program { static void Main(string[] args) { Dictionary<string, int> dic = new(); Server? s; for (int j = 0; j < 100; j++) { s = WeightedRoundRobin.GetServer(); Console.WriteLine("{0},weight:{1}", s.IP, s.Weight); if (!dic.ContainsKey("伺服器" + s.IP + ",權重:" + s.Weight)) { dic.Add("伺服器" + s.IP + ",權重:" + s.Weight, 0); } dic["伺服器" + s.IP + ",權重:" + s.Weight]++; } foreach (var i1 in dic) { Console.WriteLine("{0}共處理請求{1}次", i1.Key, i1.Value); } Console.ReadLine(); } }