using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace MathModTasks
{
///
/// Производит решение задачи симплекс-методом
///
public class Simplex
{
string savePath;
double[,] table; //симплекс таблица
int m, n;
List basis; //список базисных переменных
///
/// Инициализирует новый экземпляр класса Simplex и преобразует исходные данные для обработки
///
/// Путь для сохранения файла
/// Симплекс таблица без базисных переменных
public Simplex(string savePath, double[,] source)
{
this.savePath = savePath;
m =source.GetLength(0);
n = source.GetLength(1);
table = new double[m, n + m - 1];
basis = new List();
for (int i = 0; i < m; i++)
{
for (int j = 0; j < table.GetLength(1); j++)
{
if (j < n)
table[i, j] = source[i, j];
else
table[i, j] = 0;
}
//выставляем коэффициент 1 перед базисной переменной в строке
if ((n + i) < table.GetLength(1))
{
table[i, n + i] = 1;
basis.Add(n + i);
}
}
n = table.GetLength(1);
}
///
/// Вычисление симплекс-метода в массив
///
/// Массив полученных значений Х
///
double[,] Calculate(double[] result)
{
int mainCol, mainRow; //ведущие столбец и строка
while (!IsItEnd())
{
mainCol = findMainCol();
mainRow = findMainRow(mainCol);
basis[mainRow] = mainCol;
double[,] new_table = new double[m, n];
for (int j = 0; j < n; j++)
new_table[mainRow, j] = table[mainRow, j] / table[mainRow, mainCol];
for (int i = 0; i < m; i++)
{
if (i == mainRow)
continue;
for (int j = 0; j < n; j++)
new_table[i, j] = table[i, j] - table[i, mainCol] * new_table[mainRow, j];
}
table = new_table;
}
//заносим в result найденные значения X
for (int i = 0; i < result.Length; i++)
{
int k = basis.IndexOf(i + 1);
if (k != -1)
result[i] = table[k, 0];
else
result[i] = 0;
}
return table;
}
///
/// Вычисляет результаты методом Calculate() и записывает результаты в файл
///
public void MakeResult()
{
double[] result = new double[2];
double[,] table_result;
table_result = Calculate(result);
for (int i = 0; i < table_result.GetLength(0); i++)
{
for (int j = 0; j < table_result.GetLength(1); j++)
Console.Write(table_result[i, j] + "\t");
Console.WriteLine();
}
ReadSaveData.WriteToFile(savePath, result);
}
///
/// Осуществляет проверку строки оценок симплекс-таблицы на наличие положительных значений. Если их нет, возвращает false.
///
///
private bool IsItEnd()
{
bool flag = true;
for (int j = 1; j < n; j++)
{
if (table[m - 1, j] < 0)
{
flag = false;
break;
}
}
return flag;
}
///
/// Находит разрешающий столбец симплекс-таблицы
///
///
private int findMainCol()
{
int mainCol = 1;
for (int j = 2; j < n; j++)
if (table[m - 1, j] < table[m - 1, mainCol])
mainCol = j;
return mainCol;
}
///
/// Находит разрешающую строку симплекс-таблицы
///
/// Разрешающий столбец симплекс-таблицы
///
private int findMainRow(int mainCol)
{
int mainRow = 0;
for (int i = 0; i < m - 1; i++)
if (table[i, mainCol] > 0)
{
mainRow = i;
break;
}
for (int i = mainRow + 1; i < m - 1; i++)
if ((table[i, mainCol] > 0) && ((table[i, 0] / table[i, mainCol]) < (table[mainRow, 0] / table[mainRow, mainCol])))
mainRow = i;
return mainRow;
}
}
}