Simplex.cs 5.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. /// Производит решение задачи симплекс-методом
  10. /// </summary>
  11. public class Simplex
  12. {
  13. string savePath;
  14. double[,] table; //симплекс таблица
  15. int m, n;
  16. List<int> basis; //список базисных переменных
  17. /// <summary>
  18. /// Инициализирует новый экземпляр класса Simplex и преобразует исходные данные для обработки
  19. /// </summary>
  20. /// <param name="savePath">Путь для сохранения файла</param>
  21. /// <param name="source">Симплекс таблица без базисных переменных</param>
  22. public Simplex(string savePath, double[,] source)
  23. {
  24. this.savePath = savePath;
  25. m =source.GetLength(0);
  26. n = source.GetLength(1);
  27. table = new double[m, n + m - 1];
  28. basis = new List<int>();
  29. for (int i = 0; i < m; i++)
  30. {
  31. for (int j = 0; j < table.GetLength(1); j++)
  32. {
  33. if (j < n)
  34. table[i, j] = source[i, j];
  35. else
  36. table[i, j] = 0;
  37. }
  38. //выставляем коэффициент 1 перед базисной переменной в строке
  39. if ((n + i) < table.GetLength(1))
  40. {
  41. table[i, n + i] = 1;
  42. basis.Add(n + i);
  43. }
  44. }
  45. n = table.GetLength(1);
  46. }
  47. /// <summary>
  48. /// Вычисление симплекс-метода в массив
  49. /// </summary>
  50. /// <param name="result">Массив полученных значений Х</param>
  51. /// <returns></returns>
  52. double[,] Calculate(double[] result)
  53. {
  54. int mainCol, mainRow; //ведущие столбец и строка
  55. while (!IsItEnd())
  56. {
  57. mainCol = findMainCol();
  58. mainRow = findMainRow(mainCol);
  59. basis[mainRow] = mainCol;
  60. double[,] new_table = new double[m, n];
  61. for (int j = 0; j < n; j++)
  62. new_table[mainRow, j] = table[mainRow, j] / table[mainRow, mainCol];
  63. for (int i = 0; i < m; i++)
  64. {
  65. if (i == mainRow)
  66. continue;
  67. for (int j = 0; j < n; j++)
  68. new_table[i, j] = table[i, j] - table[i, mainCol] * new_table[mainRow, j];
  69. }
  70. table = new_table;
  71. }
  72. //заносим в result найденные значения X
  73. for (int i = 0; i < result.Length; i++)
  74. {
  75. int k = basis.IndexOf(i + 1);
  76. if (k != -1)
  77. result[i] = table[k, 0];
  78. else
  79. result[i] = 0;
  80. }
  81. return table;
  82. }
  83. /// <summary>
  84. /// Вычисляет результаты методом Calculate() и записывает результаты в файл
  85. /// </summary>
  86. public void MakeResult()
  87. {
  88. double[] result = new double[2];
  89. double[,] table_result;
  90. table_result = Calculate(result);
  91. for (int i = 0; i < table_result.GetLength(0); i++)
  92. {
  93. for (int j = 0; j < table_result.GetLength(1); j++)
  94. Console.Write(table_result[i, j] + "\t");
  95. Console.WriteLine();
  96. }
  97. ReadSaveData.WriteToFile(savePath, result);
  98. }
  99. /// <summary>
  100. /// Осуществляет проверку строки оценок симплекс-таблицы на наличие положительных значений. Если их нет, возвращает false.
  101. /// </summary>
  102. /// <returns></returns>
  103. private bool IsItEnd()
  104. {
  105. bool flag = true;
  106. for (int j = 1; j < n; j++)
  107. {
  108. if (table[m - 1, j] < 0)
  109. {
  110. flag = false;
  111. break;
  112. }
  113. }
  114. return flag;
  115. }
  116. /// <summary>
  117. /// Находит разрешающий столбец симплекс-таблицы
  118. /// </summary>
  119. /// <returns></returns>
  120. private int findMainCol()
  121. {
  122. int mainCol = 1;
  123. for (int j = 2; j < n; j++)
  124. if (table[m - 1, j] < table[m - 1, mainCol])
  125. mainCol = j;
  126. return mainCol;
  127. }
  128. /// <summary>
  129. /// Находит разрешающую строку симплекс-таблицы
  130. /// </summary>
  131. /// <param name="mainCol">Разрешающий столбец симплекс-таблицы</param>
  132. /// <returns></returns>
  133. private int findMainRow(int mainCol)
  134. {
  135. int mainRow = 0;
  136. for (int i = 0; i < m - 1; i++)
  137. if (table[i, mainCol] > 0)
  138. {
  139. mainRow = i;
  140. break;
  141. }
  142. for (int i = mainRow + 1; i < m - 1; i++)
  143. if ((table[i, mainCol] > 0) && ((table[i, 0] / table[i, mainCol]) < (table[mainRow, 0] / table[mainRow, mainCol])))
  144. mainRow = i;
  145. return mainRow;
  146. }
  147. }
  148. }