Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace DO_Lab1_Rect
- {
- enum Sign
- {
- LE = -1,
- EQ = 0,
- GE = 1
- }
- internal class DualSimplexMethod
- {
- private void printArr()
- {
- for (int i = 0; i < array.GetLength(0); i++)
- {
- for (int j = 0; j < array.GetLength(1); j++)
- {
- Console.Write($"{array[i, j]} ");
- }
- Console.WriteLine();
- }
- }
- private double[,] array;
- private double[,] oldArray;
- private readonly List<int> basis;
- private double[] assistCof;
- public DualSimplexMethod(string path)
- {
- basis = new List<int>();
- List<string> task = File.ReadAllLines(path).ToList();
- //Визначаємо знак в і-тому рядку і забиаємо його зі стрічки
- /*
- List<Sign> sign = new List<Sign>();
- for (int i = 0; i < task.Count - 1; i++)
- {
- string current = task[i].Split(' ').Reverse().Skip(1).First();
- if (current == "<=")
- {
- sign.Add(Sign.LE);
- }
- else sign.Add(Sign.GE);
- int indexToRemove = task[i].Split(' ').Length - 2; //Забираємо передостанній елемент
- List<string> tmp = task[i].Split(" ").ToList();
- tmp.Remove(current);
- task[i] = string.Join(" ", tmp);
- }
- */
- //!!!!!!!!!!!!!!!!!!!!!!!!
- /*
- int variables = task.Count - 1;
- int rows = task[0].Split(' ').Count() - 1;
- array = new double[rows + 1, rows + variables + 1];
- assistCof = new double[array.GetLength(1) - 1];
- //Обраховуємо коефіцієнти функції
- for (int j = 0; j < array.GetLength(1); j++)
- {
- if (j < variables)
- {
- array[array.GetLength(0) - 1, j] = double.Parse(task[j].Split(' ').Last());
- }
- else
- {
- array[array.GetLength(0) - 1, j] = 0;
- }
- }
- //обраховуємо коефіцієнти обмежень
- for (int i = 0; i < array.GetLength(0) - 1; i++)
- {
- for (int j = 0; j < array.GetLength(1); j++)
- {
- if (j == variables + i)
- {
- array[i, j] = 1;
- }
- else if (j == array.GetLength(1) - 1)
- {
- array[i, j] = -double.Parse(task[task.Count - 1].Split(' ')[i]);
- }
- else if (j >= variables)
- {
- array[i, j] = 0;
- }
- else
- {
- array[i, j] = -double.Parse(task[j].Split(' ')[i]);
- }
- }
- }
- */
- getData(path);
- convertToDual();
- //PrintCanonicalView();
- printArr();
- }
- private void convertToDual()
- {
- oldArray = (double[,])array.Clone();
- calcBasis();
- int rows = array.GetLength(1) - basis.Count;
- int variables = array.GetLength(0) - 1;
- array = new double[rows, rows + variables];
- basis.Clear();
- //Обраховуємо коефіцієнти функції
- for (int j = 0; j < array.GetLength(1); j++)
- {
- if (j < variables)
- {
- array[array.GetLength(0) - 1, j] = oldArray[j, oldArray.GetLength(1) - 1];
- }
- else
- {
- array[array.GetLength(0) - 1, j] = 0;
- }
- }
- //Транспонуємо
- //обраховуємо коефіцієнти обмежень
- for (int i = 0; i < array.GetLength(0) - 1; i++)
- {
- for (int j = 0; j < array.GetLength(1); j++)
- {
- if (j == variables + i)
- {
- array[i, j] = 1;
- }
- else if (j == array.GetLength(1) - 1)
- {
- array[i, j] = oldArray[oldArray.GetLength(0) - 1, i];
- }
- else if (j >= variables)
- {
- array[i, j] = 0;
- }
- else
- {
- if (oldArray[j, i] == 0)
- {
- array[i, j] = 0; //Щоб не виходило -0
- }
- else
- {
- array[i, j] = -oldArray[j, i];
- }
- }
- }
- }
- }
- private void getData(string path)
- {
- List<string> task = File.ReadAllLines(path).ToList();
- List<Sign> signs = new List<Sign>();
- for (int i = 0; i < task.Count - 1; i++)
- {
- string currentSign = task[i].Split(' ').Reverse().Skip(1).First();
- if (currentSign == "<=")
- {
- signs.Add(Sign.LE);
- }
- else if (currentSign == ">=")
- {
- signs.Add(Sign.GE);
- }
- else signs.Add(Sign.EQ);
- int indexToRemove = task[i].Split(' ').Length - 2; //Забираємо передостанній елемент
- List<string> tmp = task[i].Split(" ").ToList();
- tmp.Remove(currentSign);
- task[i] = string.Join(" ", tmp);
- }
- string[] current = task.Last().Split(' ');
- int variables = task.Last().Split(' ').Count();
- array = new double[task.Count, task[0].Split(' ').Count()];
- assistCof = new double[array.GetLength(0) - 1];
- for (int i = 0; i < array.GetLength(1); i++)
- {
- if (i < current.Length)
- {
- array[array.GetLength(0) - 1, i] = double.Parse(current[i]);
- }
- else array[array.GetLength(0) - 1, i] = double.NaN;
- }
- for (int i = 0; i < array.GetLength(0) - 1; i++)
- {
- current = task[i].Split(' ');
- for (int j = 0; j < array.GetLength(1); j++)
- {
- array[i, j] = double.Parse(current[j]);
- }
- }
- toCanonical(signs);
- }
- private void toCanonical(List<Sign> signs)
- {
- for (int i = 0; i < array.GetLength(0); i++)
- {
- if (array[i, array.GetLength(1) - 1] < 0)
- {
- for (int j = 0; j < array.GetLength(1); j++)
- {
- array[i, j] *= -1;
- }
- signs[i] = (Sign)((int)signs[i] * -1);
- }
- }
- int additionalVariables = 0;
- for (int i = 0; i < signs.Count; i++)
- {
- if (signs[i] == Sign.LE)
- {
- //!!!!!!!!!!!!!!!!
- //LE_COUNT
- additionalVariables++;
- }
- else if (signs[i] == Sign.GE)
- {
- additionalVariables += 2;
- }
- }
- int variables = array.GetLength(1) - 1;
- oldArray = (double[,])array.Clone();
- array = new double[array.GetLength(0), array.GetLength(1) + additionalVariables];
- List<int> toAddM = new List<int>();
- for (int i = 0; i < array.GetLength(0) - 1; i++)
- {
- for (int j = 0; j < array.GetLength(1) - 1; j++)
- {
- if (j < oldArray.GetLength(1) - 1)
- {
- array[i, j] = oldArray[i, j];
- }
- else
- {
- // int tst = variables + additionalVariables;
- if (signs[i] == Sign.LE)
- {
- if (j == variables + i)
- {
- array[i, j] = 1;
- }
- else array[i, j] = 0;
- }
- else if (signs[i] == Sign.GE)
- {
- if (j == variables + i)
- {
- array[i, j] = -1;
- }
- else if (j == variables + i + array.GetLength(0) - 1)
- {
- /*Рахуємо базисні змінні для рядків із знаком>=
- * array.GetLength(0)-1 -- кількість рядків(базових змінних)
- */
- toAddM.Add(j);
- array[i, j] = 1;
- }
- else array[i, j] = 0;
- }
- }
- }
- array[i, array.GetLength(1) - 1] = oldArray[i, oldArray.GetLength(1) - 1];
- }
- //Обраховуємо останній рядок
- for (int j = 0; j < array.GetLength(1); j++)
- {
- if (j < oldArray.GetLength(1) - 1)
- {
- array[array.GetLength(0) - 1, j] = -oldArray[oldArray.GetLength(0) - 1, j];
- }
- else if (toAddM.Contains(j))
- {
- // array[array.GetLength(0) - 1, j] = double.NaN;
- array[array.GetLength(0) - 1, j] = 1;
- }
- }
- //printArr();
- }
- private void printCurrentElement(int row, int column)
- {
- if (column < array.GetLength(1) - 2)
- {
- string sym = "";
- if (array[row, column + 1] >= 0) { sym = "+"; }
- else { sym = "-"; }
- if (column != 0)
- {
- Console.Write($"{Math.Abs(array[row, column])}*Y{column + 1} {sym} ");
- }
- else
- {
- Console.Write($"{array[row, column]}*Y{column + 1} {sym} ");
- }
- }
- else if (column == array.GetLength(1) - 2)
- {
- Console.Write($"{array[row, column]}*Y{column + 1} = ");
- }
- else
- {
- Console.Write($"{array[row, column]}");
- }
- }
- private void printMainFunc()
- {
- Console.Write($"F* = ");
- string sym = "";
- for (int j = 0; j < array.GetLength(1) - 1; j++)
- {
- if (-array[array.GetLength(0) - 1, j + 1] >= 0)
- {
- sym = "+";
- }
- else
- {
- sym = "-";
- }
- if (j == 0)
- {
- Console.Write($"{-array[array.GetLength(0) - 1, j]}*Y{j + 1} ");
- }
- else
- {
- Console.Write($"{Math.Abs(array[array.GetLength(0) - 1, j])}*Y{j + 1} ");
- }
- if (j != array.GetLength(1) - 2) Console.Write($"{sym} ");
- }
- Console.Write("-> Max");
- }
- public void PrintCanonicalView()
- {
- printMainFunc();
- for (int j = 0; j < array.GetLength(1); j++)
- {
- }
- Console.WriteLine("\n-----------------------------------");
- for (int i = 0; i < array.GetLength(0) - 1; i++)
- {
- for (int j = 0; j < array.GetLength(1); j++)
- {
- printCurrentElement(i, j);
- }
- Console.WriteLine();
- }
- }
- private void calcBasis(int mainRow = -1, int mainColumn = -1)
- {
- if (basis.Count == 0)
- {
- for (int i = 0; i < array.GetLength(0); i++)
- {
- for (int j = array.GetLength(1) - 2; j >= 0; j--)
- {
- if (array[i, j] == 1)
- {
- basis.Add(j + 1);
- break;
- }
- }
- }
- }
- else
- {
- //int toInsertIndex = basis.IndexOf(mainRow);
- int toInsertIndex = mainRow;
- basis.RemoveAt(toInsertIndex);
- basis.Insert(toInsertIndex, mainColumn + 1);
- }
- }
- private void printFinalTable()
- {
- Console.Write("Basis ");
- for (int i = 0; i < array.GetLength(1) - 1; i++)
- {
- Console.Write($"x{i + 1,-4}");
- }
- Console.WriteLine("Bi ");
- for (int i = 0; i < array.GetLength(0); i++)
- {
- if (i < basis.Count)
- {
- Console.Write($"X{basis[i],-7}");
- }
- else
- {
- Console.Write("{0,-8}", "Q");
- }
- for (int j = 0; j < array.GetLength(1); j++)
- {
- Console.Write($"{array[i, j],-7}");
- }
- Console.WriteLine();
- }
- double[] answer = new double[array.GetLength(1) - 1];
- for (int j = 0; j < answer.Length; j++)
- {
- if (basis.Contains(j + 1))
- {
- int index = basis.IndexOf(j + 1);
- answer[j] = array[index, array.GetLength(1) - 1];
- }
- else
- {
- answer[j] = 0;
- }
- }
- Console.WriteLine("Answer:");
- for (int i = 0; i < answer.Length; i++)
- {
- Console.Write($"Y{i + 1} = {answer[i]} ");
- }
- }
- private void printTable()
- {
- Console.Write("Basis ");
- for (int i = 0; i < array.GetLength(1) - 1; i++)
- {
- Console.Write($"x{i + 1,-4}");
- }
- Console.WriteLine("Bi ");
- for (int i = 0; i < array.GetLength(0); i++)
- {
- if (i < basis.Count)
- {
- Console.Write($"X{basis[i],-7}");
- }
- else
- {
- Console.Write("{0,-8}", "Q");
- }
- for (int j = 0; j < array.GetLength(1); j++)
- {
- Console.Write($"{array[i, j],-7}");
- }
- Console.WriteLine();
- }
- Console.Write("{0, -8}", "rel");
- for (int i = 0; i < assistCof.Length; i++)
- {
- if (!double.IsNaN(assistCof[i]))
- {
- Console.Write($"{assistCof[i],-4} ");
- }
- else
- {
- Console.Write("{0, -5}", "-");
- }
- }
- Console.WriteLine();
- }
- public void Solve()
- {
- bool isSolved = true;
- for (int i = 0; i < array.GetLength(0) - 1; i++)
- {
- if (array[i, array.GetLength(1) - 1] < 0)
- {
- isSolved = false;
- break;
- }
- }
- //Знайдемо базисні елемент
- calcBasis();
- int iter = 0;
- while (!isSolved)
- {
- double max = -1;
- int mainRow = -1;
- for (int i = 0; i < array.GetLength(0) - 1; i++)
- {
- double tst = array[i, array.GetLength(1) - 1];
- if (array[i, array.GetLength(1) - 1] < 0 && Math.Abs(array[i, array.GetLength(1) - 1]) > max)
- {
- max = Math.Abs(array[i, array.GetLength(1) - 1]);
- mainRow = i;
- }
- }
- //Обрахуємо допоміжні коефіцієнти
- for (int j = 0; j < assistCof.Length; j++)
- {
- if (array[mainRow, j] >= 0)
- {
- assistCof[j] = double.NaN;
- }
- else
- {
- assistCof[j] = -array[array.GetLength(0) - 1, j] / array[mainRow, j];
- }
- }
- double min = -1;
- int mainColumn = -1;
- for (int i = 0; i < assistCof.Length; i++)
- {
- if (!double.IsNaN(assistCof[i]))
- {
- if (Math.Abs(min + 1) < 1e-5)
- {
- min = assistCof[i];
- mainColumn = i;
- }
- else if (assistCof[i] < min)
- {
- min = assistCof[i];
- mainColumn = i;
- }
- }
- }
- Console.WriteLine("\n******************");
- Console.WriteLine($"Table {iter + 1} -- Main row {mainRow + 1} -- Main column {mainColumn + 1} -- Main element {array[mainRow, mainColumn]}");
- Console.WriteLine("******************");
- printTable();
- calcBasis(mainRow, mainColumn);
- oldArray = (double[,])array.Clone();
- double mainElement = array[mainRow, mainColumn];
- for (int i = 0; i < array.GetLength(0); i++)
- {
- for (int j = 0; j < array.GetLength(1); j++)
- {
- if (i == mainRow)
- {
- array[i, j] = oldArray[i, j] / mainElement;
- }
- else
- {
- if (j == mainColumn)
- {
- array[i, j] = 0;
- }
- else
- {
- //array[i, j] = oldArray[i, j] * mainElement - oldArray[mainRow, j] * oldArray[i, mainColumn];
- array[i, j] = oldArray[i, j] - (oldArray[i, mainColumn] * oldArray[mainRow, j]) / mainElement;
- }
- }
- }
- }
- //перевіряємо на вирішеність
- isSolved = true;
- for (int i = 0; i < array.GetLength(0) - 1; i++)
- {
- double tst = array[i, array.GetLength(1) - 1];
- if (array[i, array.GetLength(1) - 1] < 0)
- {
- isSolved = false;
- break;
- }
- }
- iter++;
- if (isSolved)
- {
- calcBasis(mainRow, mainColumn);
- }
- }
- Console.WriteLine("******************");
- Console.WriteLine($"Table {iter + 1}");
- Console.WriteLine("******************");
- printFinalTable();
- }
- /*
- public void Solve1()
- {
- bool isSolved = true;
- for (int i = 0; i < array.GetLength(1); i++)
- {
- if (array[array.GetLength(0) - 1, i] < 0)
- {
- isSolved = false;
- break;
- }
- }
- int iter = 0;
- while (!isSolved)
- {
- //Знайдемо базисні елемент
- calcBasis1();
- //Знайдемо ведучий стовпець
- double max = -1;
- int mainColumn = -1;
- for (int j = 0; j < array.GetLength(1); j++)
- {
- if (array[array.GetLength(0) - 1, j] < 0 && Math.Abs(array[array.GetLength(0) - 1, j]) > max)
- {
- max = Math.Abs(array[array.GetLength(0) - 1, j]);
- mainColumn = j;
- }
- }
- //Обрахуємо допоміжні коефіцієнти
- for (int i = 0; i < assistCof.Length; i++)
- {
- if (array[i, mainColumn] == 0)
- {
- assistCof[i] = -1;
- }
- else
- {
- assistCof[i] = array[i, array.GetLength(1) - 1] / array[i, mainColumn];
- }
- }
- double min = -1;
- int mainRow = -1;
- for (int i = 0; i < assistCof.Length; i++)
- {
- if (assistCof[i] > 0)
- {
- if (min == -1)
- {
- min = assistCof[i];
- mainRow = i;
- }
- else
- {
- if (assistCof[i] < min)
- {
- min = assistCof[i];
- mainRow = i;
- }
- }
- }
- }
- Console.WriteLine("******************");
- Console.WriteLine($"Table {iter + 1} -- Main row {mainRow + 1} -- Main column {mainColumn + 1} -- Main element {array[mainRow, mainColumn]}");
- Console.WriteLine("******************");
- printTable1();
- oldArray = (double[,])array.Clone();
- double mainElement = array[mainRow, mainColumn];
- for (int i = 0; i < array.GetLength(0); i++)
- {
- for (int j = 0; j < array.GetLength(1); j++)
- {
- if (i == mainRow)
- {
- array[i, j] = oldArray[i, j] / mainElement;
- }
- else
- {
- if (j == mainColumn)
- {
- array[i, j] = 0;
- }
- else
- {
- //array[i, j] = oldArray[i, j] * mainElement - oldArray[mainRow, j] * oldArray[i, mainColumn];
- array[i, j] = oldArray[i, j] - (oldArray[i, mainColumn] * oldArray[mainRow, j]) / mainElement;
- }
- }
- }
- }
- //перевіряємо на вирішеність
- isSolved = true;
- for (int i = 0; i < array.GetLength(1); i++)
- {
- if (array[array.GetLength(0) - 1, i] < 0)
- {
- isSolved = false;
- break;
- }
- }
- iter++;
- }
- Console.WriteLine("******************");
- Console.WriteLine($"Table {iter + 1}");
- Console.WriteLine("******************");
- calcBasis1();
- printFinalTable1();
- }
- */
- private void printTable1()
- {
- Console.Write("Basis ");
- for (int i = 0; i < array.GetLength(1) - 1; i++)
- {
- Console.Write($"x{i + 1,-4}");
- }
- Console.Write("Bi ");
- Console.WriteLine("Bi/mainColumn");
- for (int i = 0; i < array.GetLength(0); i++)
- {
- if (i < basis.Count)
- {
- Console.Write($"X{basis[i]} ");
- }
- else
- {
- Console.Write("{0,-8}", "Q");
- }
- for (int j = 0; j < array.GetLength(1); j++)
- {
- Console.Write($"{array[i, j]:g2} ");
- }
- if (i < assistCof.Length)
- {
- if (assistCof[i] < 0)
- {
- Console.WriteLine($"<0");
- }
- else
- {
- Console.WriteLine($"{assistCof[i]}");
- }
- }
- else
- {
- Console.WriteLine();
- }
- }
- }
- private void printFinalTable1()
- {
- Console.Write("Basis ");
- for (int i = 0; i < array.GetLength(1) - 1; i++)
- {
- Console.Write($"x{i + 1,-4}");
- }
- Console.WriteLine("Bi");
- for (int i = 0; i < array.GetLength(0); i++)
- {
- if (i < basis.Count)
- {
- Console.Write($"X{basis[i],-7}");
- }
- else
- {
- Console.Write("{0,-8}", "Q");
- }
- for (int j = 0; j < array.GetLength(1); j++)
- {
- Console.Write($"{array[i, j],-5}");
- }
- Console.WriteLine();
- }
- double[] answer = new double[array.GetLength(1) - 1];
- for (int j = 0; j < answer.Length; j++)
- {
- if (basis.Contains(j + 1))
- {
- int index = basis.IndexOf(j + 1);
- answer[j] = array[index, array.GetLength(1) - 1];
- }
- else
- {
- answer[j] = 0;
- }
- }
- Console.WriteLine("Answer:");
- for (int i = 0; i < answer.Length; i++)
- {
- Console.Write($"X{i + 1} = {answer[i]} ");
- }
- Console.WriteLine($"\nQ = {array[array.GetLength(0) - 1, array.GetLength(1) - 1]}");
- }
- /*
- private void calcBasis1()
- {
- if (basis.Count == 0)
- {
- for (int i = 0; i < array.GetLength(1); i++)
- {
- int zeroCount = 0;
- double other = -1;
- for (int j = 0; j < array.GetLength(0)-1; j++)
- {
- double cur = array[j, i];
- if (i == 4)
- {
- ;
- }
- if (array[j, i] == 0)
- {
- zeroCount++;
- }
- else other = array[j, i];
- }
- if (zeroCount == array.GetLength(0) - 2 && Math.Abs(other - 1) < 1e-3)
- {
- basis.Add(i + 1);
- }
- }
- }
- else
- {
- int insertIndex = -1, toInsert = -1;
- for (int i = 0; i < array.GetLength(1); i++)
- {
- int zeroCount = 0;
- for (int j = 0; j < array.GetLength(0); j++)
- {
- if (array[j, i] == 0)
- {
- zeroCount++;
- }
- }
- if (zeroCount != array.GetLength(0) - 1 && basis.Contains(i + 1))
- {
- insertIndex = basis.IndexOf(i + 1);
- }
- else if (zeroCount == array.GetLength(0) - 1 && !basis.Contains(i + 1))
- {
- toInsert = i + 1;
- }
- }
- basis.RemoveAt(insertIndex);
- basis.Insert(insertIndex, toInsert);
- }
- }
- */
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment