|
@@ -1,341 +0,0 @@
|
|
|
-using System;
|
|
|
-using System.Collections.Generic;
|
|
|
-using System.Linq;
|
|
|
-using System.Text;
|
|
|
-using System.Threading.Tasks;
|
|
|
-
|
|
|
-namespace Симлекс_метод
|
|
|
-{
|
|
|
- internal class Simplex
|
|
|
- {
|
|
|
- public double[,] main; // Расход сырья на единицу продуции
|
|
|
- public double[] res; // Запасы сырья
|
|
|
- public double[] dohod; // Доход от реализации единицы продукции
|
|
|
- public int n; // Количество продукции
|
|
|
- public int m ; // Количество ресурсов
|
|
|
- public int temp; // Дополнительная переменная в СО
|
|
|
- public int dop; // Дополнительная переменная для вывода в граничных условиях
|
|
|
- public double[,] Table; // Массив симплекс-таблицы
|
|
|
- public double[] x; // Значение x в симплекс таблицах
|
|
|
- public void Vvod(ref double[] dohod) // Ввод прибыли от продукции
|
|
|
- {
|
|
|
- for (int i = 0; i < dohod.Length; i++)
|
|
|
- {
|
|
|
- while (true)
|
|
|
- {
|
|
|
- try
|
|
|
- {
|
|
|
- while (true)
|
|
|
- {
|
|
|
- Console.Write($"Введите прибыль с реалзации продукта №{i + 1}: ");
|
|
|
- double h = Convert.ToDouble(Console.ReadLine());
|
|
|
- if (h >= 0)
|
|
|
- {
|
|
|
- dohod[i] = h;
|
|
|
- break;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- Console.WriteLine("Прибыль должна быть больше нуля\nПовторите ввод");
|
|
|
- }
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- catch
|
|
|
- {
|
|
|
- Console.WriteLine("Необходимо ввести целое число!\nПовторите ввод");
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- public void MatModel() // Вывод математической модели
|
|
|
- {
|
|
|
- Console.WriteLine("Математическая модель:");
|
|
|
- Console.Write("\tF = ");
|
|
|
- for (int i = 0; i < dohod.Length; i++)
|
|
|
- {
|
|
|
- if (i != dohod.Length - 1)
|
|
|
- {
|
|
|
- Console.Write($"{dohod[i]}x{i + 1} + ");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- Console.Write($"{dohod[i]}x{i + 1} -> max\n");
|
|
|
- }
|
|
|
- }
|
|
|
- for (int i = 0; i < main.GetLength(0); i++)
|
|
|
- {
|
|
|
- Console.Write("\t");
|
|
|
- for (int j = 0; j < main.GetLength(1); j++)
|
|
|
- {
|
|
|
- if (j != main.GetLength(1) - 1)
|
|
|
- {
|
|
|
- Console.Write($"{main[i, j]}x{j + 1} + ");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- Console.Write($"{main[i, j]}x{j + 1} <= {res[i]}");
|
|
|
- }
|
|
|
- }
|
|
|
- Console.WriteLine();
|
|
|
- }
|
|
|
- Console.Write($"\tx");
|
|
|
- for (int i = 0; i < main.GetLength(1); i++)
|
|
|
- {
|
|
|
- if (i != main.GetLength(1) - 1)
|
|
|
- {
|
|
|
- Console.Write($"{i + 1},");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- Console.Write($"{i + 1}");
|
|
|
- }
|
|
|
- }
|
|
|
- Console.WriteLine($" >= 0\n");
|
|
|
- }
|
|
|
- public void KanModel() // Вывод кананической модели
|
|
|
- {
|
|
|
- Console.WriteLine("Каноническая задача минимизации, составленная по условию задачи:");
|
|
|
- Console.Write("\tF' = -(");
|
|
|
- for (int i = 0; i < dohod.Length; i++)
|
|
|
- {
|
|
|
- if (i != dohod.Length - 1)
|
|
|
- {
|
|
|
- Console.Write($"{dohod[i]}x{i + 1} + ");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- Console.Write($"{dohod[i]}x{i + 1}) -> min\n");
|
|
|
- }
|
|
|
- }
|
|
|
- for (int i = 0; i < main.GetLength(0); i++)
|
|
|
- {
|
|
|
- Console.Write("\t");
|
|
|
- for (int j = 0; j < main.GetLength(1); j++)
|
|
|
- {
|
|
|
- if (j != main.GetLength(1) - 1)
|
|
|
- {
|
|
|
- Console.Write($"{main[i, j]}x{j + 1} + ");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- Console.Write($"{main[i, j]}x{j + 1} + x{temp++} = {res[i]}");
|
|
|
- }
|
|
|
- }
|
|
|
- Console.WriteLine();
|
|
|
- }
|
|
|
- Console.Write($"\tx");
|
|
|
- for (int i = 0; i < main.GetLength(1); i++)
|
|
|
- {
|
|
|
- if (i == main.GetLength(1) - 1)
|
|
|
- {
|
|
|
- Console.Write($"{i + 1}");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- Console.Write($"{i + 1},");
|
|
|
- }
|
|
|
- }
|
|
|
- Console.Write($" >= 0; x");
|
|
|
- while (dop != temp)
|
|
|
- {
|
|
|
- if (dop + 1 != temp)
|
|
|
- {
|
|
|
- Console.Write($"{dop},");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- Console.Write($"{dop}");
|
|
|
- }
|
|
|
- dop++;
|
|
|
- }
|
|
|
- Console.WriteLine(" - любое\n");
|
|
|
- }
|
|
|
- public void finalResults(double r) // Вывод оканчательных результатов
|
|
|
- {
|
|
|
- Console.WriteLine("\nОкончательные результаты:");
|
|
|
- for (int i = 0; i < r; i++)
|
|
|
- {
|
|
|
- Console.WriteLine($"x{i + 1} = {x[i]}");
|
|
|
- }
|
|
|
- Console.WriteLine($"F = {Math.Round(Math.Abs(Table[Table.GetLength(0) - 1, Table.GetLength(1) - 1]), 3)}");
|
|
|
- }
|
|
|
- public void solve(int r, int c) // Преобразование столбца к единичному
|
|
|
- {
|
|
|
- double var = Table[r, c]; // Разрешающий элемент
|
|
|
- for (int j = 0; j < Table.GetLength(1); j++) // Разделение строки с разрешающим элементом на разрешающий элемент
|
|
|
- {
|
|
|
- Table[r, j] = (double)(Table[r, j] / var);
|
|
|
- }
|
|
|
- double del; // Переменная для хранеия элемента в строке, которую юудем занулять
|
|
|
- for (int i = 0; i < Table.GetLength(0); i++)
|
|
|
- {
|
|
|
- del = Table[i, c];
|
|
|
- for (int j = 0; j < Table.GetLength(1); j++) // Зануляем эелемент на главном столбце
|
|
|
- {
|
|
|
- if (i != r) // Если это не разрешающая строка
|
|
|
- {
|
|
|
- var = Table[r, j];
|
|
|
- var *= -del;
|
|
|
- Table[i, j] += var;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- public int decisiveRow(double[,] a, int b) // Нахождение разрешающей строки
|
|
|
- {
|
|
|
- double[,] a1 = new double[a.GetLength(0), a.GetLength(1)];
|
|
|
- for (int i = 0; i < a1.GetLength(0); i++)
|
|
|
- {
|
|
|
- for (int j = 0; j < a1.GetLength(1); j++)
|
|
|
- {
|
|
|
- a1[i, j] = Convert.ToDouble(a[i, j]);
|
|
|
- }
|
|
|
- }
|
|
|
- double min = double.MaxValue;
|
|
|
- int temp = 0;
|
|
|
- for (int i = 0; i < a1.GetLength(0) - 1; i++)
|
|
|
- {
|
|
|
- if (a1[i, a1.GetLength(1) - 1] != 0 && a1[i, b] > 0)
|
|
|
- {
|
|
|
- if ((a1[i, a1.GetLength(1) - 1] / a1[i, b]) < min)
|
|
|
- {
|
|
|
- min = a1[i, a1.GetLength(1) - 1] / a1[i, b];
|
|
|
- temp = i;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return temp;
|
|
|
- }
|
|
|
-
|
|
|
- public int decisiveColumn(double[,] a) // Нахождение разрешающего столбца
|
|
|
- {
|
|
|
- double max = double.MinValue;
|
|
|
- int temp = 0;
|
|
|
- for (int j = 0; j < a.GetLength(1); j++)
|
|
|
- {
|
|
|
- if (a[a.GetLength(0) - 1, j] >= 0)
|
|
|
- {
|
|
|
- if (a[a.GetLength(0) - 1, j] > max)
|
|
|
- {
|
|
|
- max = a[a.GetLength(0) - 1, j];
|
|
|
- temp = j;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return temp;
|
|
|
- }
|
|
|
-
|
|
|
- public void FirstTable() // Формирование первой симплекс таблицы
|
|
|
- {
|
|
|
- for (int i = 0; i < main.GetLength(0); i++)
|
|
|
- {
|
|
|
- for (int j = 0; j < main.GetLength(1); j++)
|
|
|
- {
|
|
|
- if (j != main.GetLength(1) - 1)
|
|
|
- {
|
|
|
- Table[i, j] = main[i, j];
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- Table[i, j] = main[i, j];
|
|
|
- Table[i, temp++] = 1;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- for (int i = 0; i < res.Length; i++) // Вывод в столбец свободных членов
|
|
|
- {
|
|
|
- Table[i, Table.GetLength(1) - 1] = res[i];
|
|
|
- }
|
|
|
- for (int i = 0; i < dohod.Length; i++) // Вывод в строку оценок
|
|
|
- {
|
|
|
- Table[Table.GetLength(0) - 1, i] = dohod[i];
|
|
|
- }
|
|
|
- }
|
|
|
- public void intermediate(ref double[] b, int o) // Вывод симплекс-таблицы и промежуточных результатов
|
|
|
- {
|
|
|
- Array.Resize(ref b, 0);
|
|
|
- if (o == 0)
|
|
|
- {
|
|
|
- Console.WriteLine($"\n1-ая симплекс-таблица:");
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- Console.WriteLine($"\n{o + 1}-я Симплекс-таблица:");
|
|
|
- }
|
|
|
- for (int i = 0; i < Table.GetLength(0); i++) // Вывод симлекс-таблицы
|
|
|
- {
|
|
|
- for (int j = 0; j < Table.GetLength(1); j++)
|
|
|
- {
|
|
|
- Console.Write($"{Table[i, j]:f3} ");
|
|
|
- }
|
|
|
- Console.WriteLine();
|
|
|
- }
|
|
|
- Console.WriteLine("\nРезультаты таблицы:");
|
|
|
- for (int j = 0; j < Table.GetLength(1) - 1; j++) // Зполнение дополниетельной переменной значениями x
|
|
|
- {
|
|
|
- int temp = 0; // Количество 0 в столбце
|
|
|
- int temp1 = 0; // Количество 1 в столбце
|
|
|
- for (int i = 0; i < Table.GetLength(0) - 1; i++) // Подсчёт количества 0 и 1 в столбце
|
|
|
- {
|
|
|
- if (Table[i, j] == 0)
|
|
|
- temp++;
|
|
|
- if (Table[i, j] == 1)
|
|
|
- temp1++;
|
|
|
- }
|
|
|
- if (temp == Table.GetLength(0) - 2 && temp1 == 1) // Если столбец единичный
|
|
|
- {
|
|
|
- for (int i = 0; i < Table.GetLength(0) - 1; i++)
|
|
|
- {
|
|
|
- if (Table[i, j] == 1)
|
|
|
- {
|
|
|
- temp = i;
|
|
|
- }
|
|
|
- }
|
|
|
- Array.Resize(ref b, b.Length + 1);
|
|
|
- b[b.Length - 1] = Math.Round(Table[temp, Table.GetLength(1) - 1],3);
|
|
|
- }
|
|
|
- else // Если столбец не единичный
|
|
|
- {
|
|
|
- Array.Resize(ref b, b.Length + 1);
|
|
|
- b[b.Length - 1] = 0;
|
|
|
- }
|
|
|
- }
|
|
|
- for (int i = 0; i < b.Length; i++) // Вывод значений x
|
|
|
- {
|
|
|
- Console.WriteLine($"x{i + 1} = {b[i]}");
|
|
|
- }
|
|
|
- Console.WriteLine($"F' = {Math.Round(Table[Table.GetLength(0) - 1, Table.GetLength(1) - 1], 3)}");
|
|
|
- Console.WriteLine($"F = {Math.Round(Math.Abs(Table[Table.GetLength(0) - 1, Table.GetLength(1) - 1]), 3)}");
|
|
|
- }
|
|
|
- public void GetSolition()
|
|
|
- {
|
|
|
- int check = 0; // Переменная для проверки что все элементы в строке оценок < 0
|
|
|
- int c, r; // Разрешающий столбец и строка
|
|
|
- int o = 0;
|
|
|
- while (true)
|
|
|
- {
|
|
|
- c = decisiveColumn(Table); // Нахождение разрешающего столбца
|
|
|
- r = decisiveRow(Table, c); // Нахождение разрешающей строки
|
|
|
- Console.WriteLine($"Разрешающий столбец: {c + 1}");
|
|
|
- Console.WriteLine($"Разрешающая строка: {r + 1}");
|
|
|
- solve(r, c); // Преобразование симплекс-таблицы
|
|
|
- intermediate(ref x, o + 1); // Вывод промежуточных результатов
|
|
|
- for (int j = 0; j < Table.GetLength(1) - 1; j++)
|
|
|
- {
|
|
|
- if (Table[Table.GetLength(0) - 1, j] <= 0)
|
|
|
- {
|
|
|
- check++; ;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- if (check == Table.GetLength(0) - 1)
|
|
|
- {
|
|
|
- break;
|
|
|
- }
|
|
|
- o++;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-}
|