Komivoyazh.cs 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6. namespace Komivoyaz
  7. {
  8. class MetodKomivoyazher
  9. {
  10. public int Komivoyzher(int[,] matrix, int size, int[] dj, int[] di, int[,] outputMatrix)
  11. {
  12. for (int i = 0; i < size; i++)
  13. {
  14. for (int j = 0; j < size; j++)
  15. {
  16. matrix[i, j] = outputMatrix[i, j];
  17. }
  18. }
  19. int lowerBorder = 0;
  20. int[] rows = new int[size];
  21. int[] columns = new int[size];
  22. for (int i = 0; i < size; i++)
  23. {
  24. rows[i] = i;
  25. columns[i] = i;
  26. }
  27. while (matrix.GetLength(0) > 1)
  28. {
  29. int[,] constants = new int[matrix.GetLength(1), matrix.GetLength(0)];
  30. di = new int[size]; //массив минимумов строк
  31. dj = new int[size]; //массив минимумов столбцов
  32. int minElimentReducton = int.MaxValue;
  33. //редукция
  34. for (int i = 0; i < matrix.GetLength(0); i++)
  35. {
  36. minElimentReducton = int.MaxValue;
  37. for (int j = 0; j < matrix.GetLength(1); j++)
  38. {
  39. if (matrix[i, j] < minElimentReducton)
  40. {
  41. minElimentReducton = matrix[i, j];
  42. }
  43. }
  44. di[i] = minElimentReducton;
  45. }
  46. for (int i = 0; i < matrix.GetLength(0); i++)
  47. {
  48. for (int j = 0; j < matrix.GetLength(1); j++)
  49. {
  50. if (matrix[i, j] != int.MaxValue)
  51. {
  52. matrix[i, j] -= di[i];
  53. }
  54. }
  55. }
  56. for (int j = 0; j < matrix.GetLength(1); j++)
  57. {
  58. minElimentReducton = int.MaxValue;
  59. for (int i = 0; i < matrix.GetLength(0); i++)
  60. {
  61. if (matrix[i, j] < minElimentReducton)
  62. {
  63. minElimentReducton = matrix[i, j];
  64. }
  65. }
  66. dj[j] = minElimentReducton;
  67. }
  68. for (int j = 0; j < matrix.GetLength(1); j++)
  69. {
  70. for (int i = 0; i < matrix.GetLength(0); i++)
  71. {
  72. if (matrix[i, j] != int.MaxValue)
  73. {
  74. matrix[i, j] -= dj[j];
  75. }
  76. }
  77. }
  78. lowerBorder += di.Sum() + dj.Sum(); //нулевая граница
  79. for (int i = 0; i < matrix.GetLength(0); i++)
  80. {
  81. for (int j = 0; j < matrix.GetLength(1); j++)
  82. {
  83. if (matrix[i, j] == 0)
  84. {
  85. //коэфиценты нулевых ячеек
  86. constants[i, j] = MinEl(Column(matrix, j), Column(matrix, j).Length, i) + MinEl(Row(matrix, i), Row(matrix, i).Length, j);
  87. }
  88. }
  89. }
  90. int minCoeffI = 0;
  91. int minCoeffJ = 0;
  92. int maxElementCoeff = int.MinValue;
  93. for (int i = constants.GetLength(0) - 1; i >= 0; i--)
  94. {
  95. for (int j = constants.GetLength(1) - 1; j >= 0; j--)
  96. {
  97. if (constants[i, j] >= maxElementCoeff)
  98. {
  99. maxElementCoeff = constants[i, j];
  100. minCoeffI = i;
  101. minCoeffJ = j;
  102. }
  103. }
  104. }
  105. Console.WriteLine(rows[minCoeffI]);
  106. Console.WriteLine(columns[minCoeffJ]);
  107. try
  108. {
  109. //"М"
  110. matrix[Array.IndexOf(rows, columns[minCoeffJ]), Array.IndexOf(columns, rows[minCoeffI])] = int.MaxValue;
  111. }
  112. catch { }
  113. //матрица вспомогательная
  114. int[,] matrix2 = new int[--size, size];
  115. for (int i = 0, i1 = 0; i < size && i1 < size + 1; i++, i1++)
  116. {
  117. for (int j = 0, j1 = 0; j < size && j1 < size + 1; j++, j1++)
  118. {
  119. if (minCoeffI == i1) i1++;
  120. if (minCoeffJ == j1) j1++;
  121. matrix2[i, j] = matrix[i1, j1];
  122. }
  123. }
  124. //копирование матрицы в текущую
  125. matrix = matrix2.Clone() as int[,];
  126. int[] remRows = new int[size];
  127. int[] remColumns = new int[size];
  128. //вычеркивание из матрицы лишних строк
  129. for (int i = 0, i1 = 0; i < size && i1 < size + 1; i++, i1++)
  130. {
  131. if (minCoeffI == i1) i1++;
  132. remRows[i] = rows[i1];
  133. }
  134. for (int j = 0, j1 = 0; j < size && j1 < size + 1; j++, j1++)
  135. {
  136. if (minCoeffJ == j1) j1++;
  137. remColumns[j] = columns[j1];
  138. }
  139. columns = new int[size];
  140. Array.Copy(remColumns, columns, remColumns.Length);
  141. rows = new int[size];
  142. Array.Copy(remRows, rows, remRows.Length);
  143. }
  144. return lowerBorder;
  145. }
  146. int[] Row(int[,] matrix, int i)
  147. {
  148. int[] Row = new int[matrix.GetLength(0)];
  149. for (int j = 0; j < Row.Length; j++)
  150. {
  151. Row[j] = matrix[i, j];
  152. }
  153. return Row;
  154. }
  155. int[] Column(int[,] matrix, int j)
  156. {
  157. int[] Column = new int[matrix.GetLength(1)];
  158. for (int i = 0; i < Column.Length; i++)
  159. {
  160. Column[i] = matrix[i, j];
  161. }
  162. return Column;
  163. }
  164. int MinEl(int[] arr, int len, int ind)
  165. {
  166. int min = int.MaxValue;
  167. for (int i = 0; i < len; i++)
  168. {
  169. if (i == ind) continue;
  170. if (min > arr[i]) min = arr[i];
  171. }
  172. return min;
  173. }
  174. }
  175. }