1. 程式人生 > 其它 >權重輪詢排程演算法(Weighted Round-Robin Scheduling)-C#實現

權重輪詢排程演算法(Weighted Round-Robin Scheduling)-C#實現

參考: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();
    }
}