using System using System Collections Generic using System Linq using

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
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);
}
// Проверяем успешность подсчета 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()
{
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();
}
}
}