Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.Linq;
- namespace ConsoleApp6
- {
- class Program
- {
- /*
- 程序由规划器(Main),分配器(DoTest)和数据结构组成。
- 规划器目前是直接手写的常量,是自己试出来的,具体规律尚未发现,需要改成程序自动计算的,
- 我有N个master和N个worker
- worker有两种状态,可用和不可用(worker.isWorking)
- master可以被指定到worker上,并且设置优先级(通过EffectToInfo的worker和priority)
- 一个master会被指定到多个worker(通过master.effectList)
- 然后分配器会根据master对worker的优先级,以及worker是否可用来把master分配给worker(具体实现参考DoTest)
- 目标:给出任意masterCount,workerCount的情况下,计算出master对应的每个worker的优先级
- 并且能使用这套优先级,在任意一个或多个worker离线的情况下,master都能被dotest平均分配到每一个worker上
- 需要注意:
- 1.规划器并不知道Worker是否离线,只知道master和worker的数量(也就是worker.isWorking不能被你的算法访问)
- 2.平均分配是指可以整除的情况下,比如说8个master分配到2个worker,就是4,4,如果不能被整除,比如说8个master分配到3个worker,3,3,2是可以接受的,但是比如说1,0,3、2,2,0、3,4,1就肯定错了
- 3.实现平均分配的唯一办法就是设置优先级,也就是通过算法自动调用master[xxx].effectList.Add(new EffectToInfo(xxxx, workers[xxxx]));,其他地方不应修改
- 4.优先级每个Master对每个worker的优先级,只能设置一次,不能在中途重新设置优先级(比如说在worker.isWorking改变后重新计算优先级都是不可以的),我已经提供了一个在master =8,worker=3的情况下的正确例子。
- */
- //数据结构
- public class EffectToInfo
- {
- public int priority = 0;
- public Worker Worker;
- public EffectToInfo(int priority, Worker worker)
- {
- this.priority = priority;
- this.Worker = worker;
- }
- }
- static int masterCount = 0;
- static int workerCount = 0;
- static List<Master> master = new List<Master>();
- static List<Worker> workers = new List<Worker>();
- public class Master
- {
- public int name;
- public List<EffectToInfo> effectList = new List<EffectToInfo>();
- public Worker currentWorker;
- public Master(int index)
- {
- name = index;
- }
- }
- public class Worker
- {
- public int name;
- public bool isWorking = true;
- public Worker(int index)
- {
- name = index;
- }
- }
- static void TestDisableWorker(int Index)
- {
- workers[Index].isWorking = false;
- }
- static void TestEnableWorker(int Index)
- {
- workers[Index].isWorking = true;
- }
- static void OnlineAllWorker()
- {
- foreach (var worker in workers)
- {
- worker.isWorking = true;
- }
- }
- static void TestScript()
- {
- //主测试逻辑
- Console.WriteLine("masterCount:" + masterCount + " workerCount:" + workerCount);
- int OkTest = 0;
- int FailedTest = 0;
- var workerStatusTarget = "";
- for (int i = 0; i < workerCount; i++)
- {
- workerStatusTarget += "1";
- }
- int StatusCount = Convert.ToInt32(workerStatusTarget, 2) + 1;
- for (int i = 1; i < StatusCount; i++)
- {
- OnlineAllWorker();
- var currentStateString =Convert.ToString(i, 2);
- int zeroToFill = workerCount - currentStateString.Length;
- for (int j = 0; j < zeroToFill; j++)
- {
- currentStateString = "0" + currentStateString;
- }
- int CurrentLocation = currentStateString.Length - 1;
- foreach (var singleStateChar in currentStateString.ToCharArray().Reverse())
- {
- if (singleStateChar == '0')
- {
- TestDisableWorker(CurrentLocation);
- }
- else
- {
- TestEnableWorker(CurrentLocation);
- }
- CurrentLocation--;
- }
- if (DoTest())
- OkTest++;
- else
- {
- FailedTest++;
- }
- }
- //for (int i = 0; i <= workerCount; i++)
- //{
- // int workerToDisable = workerCount - i;
- // if (workerToDisable != workerCount)
- // {
- // if (DoTest())
- // OkTest++;
- // else
- // {
- // FailedTest++;
- // }
- // TestDisableWorker(workerToDisable);
- // }
- //}
- Console.WriteLine("测试结果: 成功:" + OkTest +" 失败:" + FailedTest);
- }
- static bool DoTest()
- {
- //测试代码,不应修改
- int maxCount = 0;
- int minCount = 9999;
- int totalCount = 0;
- Console.WriteLine("");
- Console.WriteLine("---------测试----------");
- master.ForEach((master) =>
- {
- var workersByPri = master.effectList.Where(effect=>effect.Worker.isWorking).OrderByDescending((effect) => effect.priority).ToList();
- master.currentWorker = workersByPri.FirstOrDefault()?.Worker;
- });
- Console.WriteLine("分配情况:");
- workers.ForEach((worker) =>
- {
- if (worker.isWorking)
- {
- var workermasters = master.Where((master) => master?.currentWorker?.name == worker.name);
- Console.WriteLine("");
- Console.WriteLine("Worker:" + worker.name + ":master数量:" + workermasters.Count() );
- totalCount += workermasters.Count();
- maxCount = Math.Max(workermasters.Count(), maxCount);
- minCount = Math.Min(workermasters.Count(), minCount);
- foreach (var workermaster in workermasters)
- {
- Console.Write(workermaster.name + ",");
- }
- Console.WriteLine("");
- }
- });
- if (maxCount - minCount <= 1)
- {
- if (totalCount == masterCount)
- {
- Console.WriteLine("测试通过");
- return true;
- }
- }
- Console.WriteLine("测试失败");
- return false;
- }
- static void MakeData(int masterCount, int workerCount)
- {
- master.Clear();
- for (int i = 0; i < masterCount; i++)
- {
- master.Add(new Master(i));
- }
- workers.Clear();
- for (int i = 0; i < workerCount; i++)
- {
- workers.Add(new Worker(i));
- }
- }
- static void Main(string[] args)
- {
- //在这里实现逻辑
- masterCount = 8;
- workerCount = 3;
- MakeData(masterCount, workerCount);
- //这套常量已经测试通过,可以在master=8,worker=3的情况下离线任何一个或多个worker,master都能被平均分配给剩下的worker
- master[0].effectList.Add(new EffectToInfo(1000, workers[0]));
- master[0].effectList.Add(new EffectToInfo(999, workers[1]));
- master[0].effectList.Add(new EffectToInfo(998, workers[2]));
- master[1].effectList.Add(new EffectToInfo(999, workers[0]));
- master[1].effectList.Add(new EffectToInfo(1000, workers[1]));
- master[1].effectList.Add(new EffectToInfo(998, workers[2]));
- master[2].effectList.Add(new EffectToInfo(998, workers[0]));
- master[2].effectList.Add(new EffectToInfo(999, workers[1]));
- master[2].effectList.Add(new EffectToInfo(1000, workers[2]));
- master[3].effectList.Add(new EffectToInfo(1000, workers[0]));
- master[3].effectList.Add(new EffectToInfo(999, workers[1]));
- master[3].effectList.Add(new EffectToInfo(998, workers[2]));
- master[4].effectList.Add(new EffectToInfo(998, workers[0]));
- master[4].effectList.Add(new EffectToInfo(1000, workers[1]));
- master[4].effectList.Add(new EffectToInfo(999, workers[2]));
- master[5].effectList.Add(new EffectToInfo(998, workers[0]));
- master[5].effectList.Add(new EffectToInfo(999, workers[1]));
- master[5].effectList.Add(new EffectToInfo(1000, workers[2]));
- master[6].effectList.Add(new EffectToInfo(1000, workers[0]));
- master[6].effectList.Add(new EffectToInfo(998, workers[1]));
- master[6].effectList.Add(new EffectToInfo(999, workers[2]));
- master[7].effectList.Add(new EffectToInfo(999, workers[0]));
- master[7].effectList.Add(new EffectToInfo(998, workers[1]));
- master[7].effectList.Add(new EffectToInfo(1000, workers[2]));
- TestScript();
- Console.ReadKey();
- }
- }
- }
Add Comment
Please, Sign In to add comment