using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleModeling
{
class TaskManagement
{
//Переменные принадлежащие классу
int numberOfTasks;
int workUnitNumber;
double time = 0;
int numberOfUsers;
int numberOfChecks;
double EV;
double sigma;
// процент отказа
int failure;
Random random = new Random();
// массив заданий
public List<int[]> unfinishedTasks = new List<int[]>();
// массив текущих заданий (обсчитываются сейчас)
public List<int[]> currentTasks = new List<int[]>();
// массив посчитанных заданий
public List<int[]> finishedTasks = new List<int[]>();
// массив проваленых заданий (недосчитались)
//public List<List<int>> failedTasks = new List<List<int>>();
// массив вычислительных аппаратов (пользователи), хранит время работы каждого вычислительного аппарата
public double[] users;
//public int[] successCheck;
public int failedTasks;
// конструктор принимает число заданий, число 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.failure = failure;
//мат ожидание
this.EV = EV;
//отклонение
this.sigma = sigma;
//массив пользователей
this.users = new double[numberOfUsers];
for (int i = 0; i < numberOfTasks; i++)
//Parallel.For(0, numberOfTasks, delegate(int i)
{
unfinishedTasks.Add(new int[workUnitNumber]);
for (int j = 0; j < workUnitNumber; j++)
//Parallel.For(0, workUnitNumber, delegate(int j)
{
//unfinishedTasks.Last().AddFirst(numberOfChecks);
unfinishedTasks.Last()[j] = numberOfChecks;
}
}
this.failedTasks = 0;
for (int i = 0; i < numberOfUsers; i++)
{
this.users[i] = 0;
}
//this.successCheck = new int[numberOfTasks];
//for (int i = 0; i < numberOfTasks; i++)
//{
// successCheck[i] = 0;
//}
}
//вычисляем к какой из 3х групп пользователь принадлежит
double GetTime()
{
double workUnitTime;
int type = random.Next(1, 4);
switch (type)
{
case 1:
workUnitTime = 1;
break;
case 2:
workUnitTime = 2;
break;
case 3:
workUnitTime = 3;
break;
default:
workUnitTime = 4;
break;
}
workUnitTime = NormalDistribution(1, 0);
return workUnitTime;
}
// Основная функция приложения, считает время,
public void CalculateTime()
{
for (int i = 0; i < numberOfUsers; i++)
{
//users[i] = GetTime();
currentTasks.Add(unfinishedTasks.First());
unfinishedTasks.RemoveAt(0);
}
int userCounter = 0;
while (unfinishedTasks.Count != 0 || currentTasks.Count != 0)
{
//if (userCounter >= numberOfUsers)
// userCounter = 0;
userCounter = 0;
//while (currentTasks.Count != 0)
{
for (int i = 0; i < currentTasks.Count; i++)
{
//double taskTime = GetTime();
//users[i] += taskTime;
int progress = 0;
int success = 0;
for (int j = 0; j < workUnitNumber; j++)
{
if (currentTasks.ElementAt(i)[j] == 0)
progress++;
}
if (progress == workUnitNumber)
progress--;
for (int j = 0; j < numberOfChecks; j++)
{
if (CheckFailure()) // успешно
{
currentTasks.ElementAt(i)[progress]--;
success++;
users[userCounter] += GetTime();
}
else
{
users[i] += GetTime();
}
}
//if (success == 0 && unfinishedTasks.Count == 0)
//{
// currentTasks.RemoveAt(0);
// failedTasks++;
//}
if (success == 0)
{
currentTasks.RemoveAt(0);
currentTasks.Add(unfinishedTasks.First());
unfinishedTasks.RemoveAt(0);
failedTasks++;
}
else if ((progress == workUnitNumber - 1) && unfinishedTasks.Count != 0)
{
finishedTasks.Add(currentTasks.First());
currentTasks.RemoveAt(0);
currentTasks.Add(unfinishedTasks.First());
unfinishedTasks.RemoveAt(0);
}
else if (progress == workUnitNumber - 1)
{
finishedTasks.Add(currentTasks.First());
currentTasks.RemoveAt(0);
}
userCounter++;
}
}
}
}
// Проверяем успешность подсчета work-unit'a
public bool CheckFailure()
{
//Random b = new Random();
int check = 0;
check = random.Next(1, 101);
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 = random.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 || failedTasks[randomtask] != 0)
// {
// randomtask = rand.Next(0, numberOfTasks);
// }
// users[i] = randomtask;
// }
// else
// {
// while ((users.Contains(randomtask)) || (tasks[randomtask][workUnitNumber - 1] == 1) || failedTasks[randomtask] != 0)
// {
// randomtask = rand.Next(0, numberOfTasks);
// //rand.Next(
// }
// users[i] = randomtask;
// }
// }
// return users;
//}
//public int[] GenerateIteration()
//{
// int[] users = new int[numberOfUsers];
// for (int i = 0; i < users.Length; i++)
// {
// users[i] = -1;
// }
// int randomtask = 0;
// int counter = 0;
// while (((tasks[randomtask][workUnitNumber - 1] == 1) || failedTasks[randomtask] != 0))
// {
// randomtask++;
// }
// users[counter] = randomtask;
// while (users[counter] != numberOfTasks && counter != numberOfUsers - 1)
// {
// users[counter + 1] = users[counter] + 1;
// counter++;
// }
// return users;
//}
// функция считает количество выполненных заданий
//public int ShowFailedTasks()
//{
//int failedTasks = 0;
//for (int i = 0; i < this.failedTasks.Length; i++)
//{
// if (this.failedTasks[i] != 0)
// failedTasks++;
//}
//return failedTasks;
//}
//функция проверяет выполнены ли все задания
//bool CompletionCheck()
//{
// int counter = 0;
// for (int i = 0; i < numberOfTasks; i++)
// {
// if (tasks[i][workUnitNumber - 1] == 1 || failedTasks[i] != 0)
// counter++;
// }
// if (counter == numberOfTasks)
// return true;
// else
// {
// tasksLeft = numberOfTasks - counter;
// if (tasksLeft < numberOfUsers)
// numberOfUsers = tasksLeft;
// return false;
// }
//}
//bool CompletionCheck()
//{
// int counter = 0;
// if (tasks[numberOfTasks - 1][workUnitNumber - 1] == 1 || failedTasks[numberOfTasks - 1] != 0)
// return true;
// else
// {
// int border = numberOfTasks - 2 * numberOfUsers;
// for (int i = numberOfTasks - 1; i > border; i--)
// {
// if (tasks[i][workUnitNumber - 1] == 1 || failedTasks[i] != 0)
// {
// counter = i;
// break;
// }
// }
// tasksLeft = numberOfTasks - counter - 1;
// if (tasksLeft < numberOfUsers)
// numberOfUsers = tasksLeft;
// return false;
// }
//}
//функция считает время которое необходимо на просчет всех заданий
//а также вносит в массив в какой момент времени каждое задание было завершено
//public double CalcTime()
//{
// 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;
//}
// public double CalcTime()
// {
// while (!this.CompletionCheck())
// {
// int[] iteration = this.GenerateIteration();
// //Array.Sort(iteration);
// for (int i = 0; i < iteration.Length; i++)
// //Parallel.For(0, iteration.Length, delegate(int 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 (this.CheckFailure())
// {
// //successCheck[iteration[i]]
// successCheck[iteration[i]][progress]++;
// }
// if (successCheck[iteration[i]][progress] == 0 && tasks[iteration[i]][progress] == 1)
// {
// failedTasks[iteration[i]] = progress;
// //goto Failed;
// }
// if (progress == workUnitNumber - 1 || failedTasks[iteration[i]] != 0)
// {
// //if (failedTasks[iteration[i]] != 1)
// tasksTime[iteration[i]] = time + workUnitTime;
// }
// }
// }
// }
// //Failed:
// time = time + workUnitTime;
// }
// return time;
// }
}
class Program
{
static void Main(string[] args)
{
//количество заданий, количество work-unit'ов, количество участников, количество проверок, процент отказа, мат ожидание, отклонение
TaskManagement a = new TaskManagement(77447, 30, 227, 5, -1, 1, 1);
a.CalculateTime();
}
}
}