using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace consoleKNIR { class TaskManagement { int tasksLeft = 0; int numberOfTasks; int workUnitNumber; double time = 0; int numberOfUsers; int numberOfChecks; // массив заданий, инициализируется нулями в конструкторе, по мере выполнения заданий заполняется единицами public int[][] tasks; // массив, в котором хранится время выполнения каждого задания public double[] tasksTime; int failure; double workUnitTime; // конструктор принимает число заданий, число work-unit'ов на которые делятся задания, количество пользователей // которым выдается задания и шанс на отказ в процентах public TaskManagement(int numberOfTasks, int workUnitNumber, int numberOfUsers, int numberOfChecks, int failure, double EV, double sigma) { this.numberOfTasks = numberOfTasks; this.workUnitNumber = workUnitNumber; this.numberOfChecks = numberOfChecks; this.numberOfUsers = numberOfUsers; this.tasks = new int[numberOfTasks][]; this.tasksTime = new double[numberOfTasks]; for (int i = 0; i < tasks.Length; i++) { tasks[i] = new int[workUnitNumber]; for (int j = 0; j < tasks[i].Length; j++) { tasks[i][j] = numberOfChecks+1; } tasksTime[i] = 0; } this.failure = failure; this.workUnitTime = this.NormalDistribution(EV, sigma); //this.tasksLeft = numberOfTasks * workUnitNumber * numberOfChecks; } // Проверяем успешность подсчета work-unit'a public bool CheckFailure() { Random random = new Random(); int check = random.Next(0, 100); if (check > failure) return true; else return false; } // Вычисляем время вычисления с помощью нормального распределения(ЦПТ) // параметрами является математичесок ожидание и отклонение public double NormalDistribution(double mo, double sigma) { double Sum = 0; double ndValue = 0; Random rand = new Random(); for (int i = 0; i <= 12; i++) { double R = rand.NextDouble(); Sum = Sum + R; } ndValue = Math.Round((mo + sigma * (Sum - 6)), 3); return ndValue; } //функция генерирует одну итерацию (раздачу пользователям заданий) public int[] GenerateIteration() { Random rand = new Random(); int[] users = new int[numberOfUsers]; for (int i = 0; i < users.Length; i++) { users[i] = -1; } for (int i = 0; i < users.Length; i++) { int randomtask = rand.Next(0, numberOfTasks); // если задание выполнено не полностью (у последнего work-unit'а задания индекс не равен 1) if (tasks[randomtask][workUnitNumber - 1] != 1) { while (users.Contains(randomtask) || tasks[randomtask][workUnitNumber - 1] == 1) { randomtask = rand.Next(0, numberOfTasks); } users[i] = randomtask; } else { while ((users.Contains(randomtask)) || (tasks[randomtask][workUnitNumber - 1] == 1)) { randomtask = rand.Next(0, numberOfTasks); //rand.Next( } users[i] = randomtask; } } return users; } //функция проверяет выполнены ли все задания bool CompletionCheck() { int counter = 0; for (int i = 0; i < numberOfTasks; i++) { if (tasks[i][workUnitNumber - 1] == 1) counter++; } if (counter == numberOfTasks) return true; else { tasksLeft = numberOfTasks - counter; if (tasksLeft < numberOfUsers) numberOfUsers = tasksLeft; return false; } } //функция считает время которое необходимо на просчет всех заданий //а также вносит в массив в какой момент времени каждое задание было завершено public double CalcTime() { //double time = 0; while (!this.CompletionCheck()) { int[] iteration = this.GenerateIteration(); Array.Sort(iteration); for (int i = 0; i < iteration.Length; i++) { if (this.CheckFailure() && iteration[i] != -1) { int progress = 0; for (int j = 0; j < workUnitNumber; j++) { if (tasks[iteration[i]][j] == 1) progress++; } if (progress != workUnitNumber) { tasks[iteration[i]][progress] = tasks[iteration[i]][progress] - 1; if (progress == workUnitNumber-1) { tasksTime[iteration[i]] = time + workUnitTime; } } } } time = time + workUnitTime; } return time; } } class Program { static void Main(string[] args) { //количество заданий, количество work-unit'ов, количество участников, количество проверок, процент отказа, мат ожидание, отклонение TaskManagement a = new TaskManagement(1000, 2, 250, 2, 25, 5, 0.15); double time = a.CalcTime(); double[] taskTime = a.tasksTime; Console.WriteLine("{0:f3}", time); Console.ReadLine(); } } }