Stank.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace MathModTasks
  7. {
  8. /// <summary>
  9. /// Класс для оптимального распределения m-го количества работ среди n-го количества станков
  10. /// </summary>
  11. class Stank
  12. {
  13. int n;
  14. int[] minData = new int[3];
  15. int[] summ;
  16. int[,] data;
  17. List<List<int[]>> vari = new List<List<int[]>>();
  18. bool[,] checkMin;
  19. bool[] checkI;
  20. bool[] checkJ;
  21. /// <summary>
  22. /// Инициализирует объект класса Stank с чтением исходных данных по указанному пути path
  23. /// </summary>
  24. /// <param name="path">Путь к файлу с исходными данными</param>
  25. public Stank(string path)
  26. {
  27. List<string[]> ls = ReadSaveData.ReadData(path);
  28. n = ls.Count;
  29. checkI = new bool[n];
  30. checkJ = new bool[n];
  31. data = new int[n, n];
  32. checkMin = new bool[n, n];
  33. for (int i = 0; i < n; i++)
  34. for (int j = 0; j < n; j++)
  35. data[i, j] = Convert.ToInt32(ls[i][j]);
  36. }
  37. /// <summary>
  38. /// Находит оптимальное распределение работ между станками
  39. /// </summary>
  40. public void MainSolution()
  41. {
  42. //пока все минимумы не будут использованы, цикл продолжается
  43. while (AllTrue(checkMin) == true)
  44. {
  45. //находит минимум во всей матрице
  46. FindMin();
  47. List<int[]> temp = new List<int[]>();
  48. for (int i = 0; i < n; i++)
  49. {
  50. //добавляет первый минимум и потом "вырезает" его индексы, чтобы они не использовались для нахождения других минимумов
  51. temp.Add(new int[] {data[minData[1],minData[2]], minData[1], minData[2] });
  52. checkI[minData[1]] = true;
  53. checkJ[minData[2]] = true;
  54. FindMinInNotUsedElements();
  55. }
  56. //добавляется вариант распределения, после чего минимум ищется снова, но другой
  57. vari.Add(temp);
  58. checkI = new bool[n];
  59. checkJ = new bool[n];
  60. }
  61. //подсчет суммы всех вариантов и нахождение минимальной
  62. summ = new int[vari.Count];
  63. for (int i = 0; i < vari.Count; i++)
  64. for (int j = 0; j < n; j++)
  65. summ[i] += vari[i][j][0];
  66. int min = FindMin(summ);
  67. //подготовка результатов для записи в файл
  68. int k = 2;
  69. string[] m = new string[n+2];
  70. m[0] = "Оптимальное распределение имеет временные затраты: " + min;
  71. m[1] = "Распределение станков следующее";
  72. for (int i = 0; i < n; i++)
  73. {
  74. m[k] = vari[Array.IndexOf(summ, min)][i][0] + ";" + vari[Array.IndexOf(summ, min)][i][1] + ";" + vari[Array.IndexOf(summ, min)][i][2];
  75. k++;
  76. }
  77. ReadSaveData.WriteToFile("result.csv", m);
  78. }
  79. /// <summary>
  80. /// Устанавливает флаг проверки использованных элементов в матрице. Если хотя бы один элемент будет равен false, метод вернет true
  81. /// </summary>
  82. /// <param name="arr"></param>
  83. /// <returns></returns>
  84. bool AllTrue(bool[,] arr)
  85. {
  86. bool flag = true;
  87. for (int i = 0; i < n; i++)
  88. for (int j = 0; j < n; j++)
  89. {
  90. flag = flag && arr[i, j] ;
  91. }
  92. return !flag;
  93. }
  94. /// <summary>
  95. /// Нахождение минимального элемента среди неиспользованных элементов матрицы и запись их (использованные) как true в булевой матрице checkMin + 1 перегрузка
  96. /// </summary>
  97. void FindMin()
  98. {
  99. DefaultMin();
  100. for (int i = 0; i < n; i++)
  101. for (int j = 0; j < n; j++)
  102. if (minData[0] > data[i, j] && checkMin[i, j] == false)
  103. {
  104. minData[0] = data[i, j];
  105. minData[1] = i;
  106. minData[2] = j;
  107. }
  108. checkMin[minData[1], minData[2]] = true;
  109. }
  110. /// <summary>
  111. /// Нахождение минимального элемента среди элементов матрицы, где индексы не совпадают с использованными ранее с помощью массивов checkI и checkJ для индексов i и j соответственно
  112. /// </summary>
  113. void FindMinInNotUsedElements()
  114. {
  115. DefaultMinInNotUsedElements();
  116. for (int i = 0; i < n; i++)
  117. for (int j = 0; j < n; j++)
  118. if (minData[0] > data[i, j] && checkI[i] == false && checkJ[j] == false)
  119. {
  120. minData[0] = data[i, j];
  121. minData[1] = i;
  122. minData[2] = j;
  123. }
  124. }
  125. /// <summary>
  126. /// Нахождение минимальной суммы среди всех полученных вариантов распределения работ между станками
  127. /// </summary>
  128. /// <param name="ar">Последовательность всех вариантов распределения работ между станками</param>
  129. /// <returns></returns>
  130. int FindMin(int[] ar)
  131. {
  132. int min = ar[0];
  133. for (int i = 0; i < n; i++)
  134. if (min > ar[i])
  135. {
  136. min = ar[i];
  137. }
  138. return min;
  139. }
  140. /// <summary>
  141. /// Задает значение минимуму перед нахождением самого минимума в матрице для метода FindMin()
  142. /// </summary>
  143. void DefaultMin()
  144. {
  145. for (int i = 0; i < n; i++)
  146. for (int j = 0; j < n; j++)
  147. if (checkMin[i, j] == false)
  148. {
  149. minData[0] = data[i, j];
  150. minData[1] = i;
  151. minData[2] = j;
  152. }
  153. }
  154. /// <summary>
  155. /// Задает значение минимуму перед нахождением самого минимума в матрице для метода FindMinInNotUsedElements()
  156. /// </summary>
  157. void DefaultMinInNotUsedElements()
  158. {
  159. for (int i = 0; i < n; i++)
  160. for (int j = 0; j < n; j++)
  161. if (checkI[i] == false && checkJ[j] == false)
  162. {
  163. minData[0] = data[i, j];
  164. minData[1] = i;
  165. minData[2] = j;
  166. }
  167. }
  168. }
  169. }