/* * После подготовки системы ограничений, отбрасывая столбцы добавленных переменных * и последнюю строку получаем первую симплекс таблицу */ private void TransformTableToFirstSimplexTable(Fraction[,] oldTable) { //Составляем новую таблицу размерами, как изначальная Fraction[,] newTable = new Fraction[oldTable.GetLength(0), oldTable.GetLength(1)]; int celRow = newTable.GetLength(0) - 1; //Последнюю строку копируем из oldTable for (int j = 0; j < newTable.GetLength(1); j++) { newTable[celRow, j] = oldTable[celRow, j]; } /* * Копируем все строки кроме последней из текущей таблицы * и выводим их из целевой функции */ for (int i = 0; i < newTable.GetLength(0) - 1; i++) { Fraction factor = newTable[celRow, basic[i]]; for (int j = 0; j < newTable.GetLength(1); j++) { newTable[i, j] = table[i, j]; newTable[celRow, j] -= newTable[i, j] * factor; } } table = newTable; }
/* * Составляем новую таблицу методом искусственного базиса * для решения задачи симплекс-методом */ private Fraction[,] TableForMethodArtificialBasis() { //Проходимся по массиву с базисными переменными не затрагивая последний элемент(целевая функция) //считаем, сколько нам понадобится добавлять переменных int count = 0; for (int k = 0; k < basic.Length - 1; k++) { if (basic[k] == 0) { count++; } } //Добавлять новые переменные будем начиная с номера int countN = table.GetLength(1); //Создаем таблицу нового размера, чтобы добавить новые переменные Fraction[,] newTable = new Fraction[table.GetLength(0), countN + count]; //обнуляем таблицу for (int i = 0; i < newTable.GetLength(0); i++) { for (int j = 0; j < newTable.GetLength(1); j++) { newTable[i, j] = new Fraction(); } } //поднимаемся по таблице снизу (не затрагивая строку целевой функции) for (int i = table.GetLength(0) - 2; i >= 0; i--) { //Копируем строку из старой таблицы for (int j = 0; j < table.GetLength(1); j++) { newTable[i, j] = table[i, j]; } if (i < basic.Length - 1) { //Если мы уже проходимся по строке с базовым элементом if (basic[i] == 0) { //Если не было базовой переменной, то добавляем ее и отнимаем ее от нижней строки basic[i] = countN; newTable[i, countN] = new Fraction(1); countN++; for (int j = 0; j < table.GetLength(1); j++) { newTable[table.GetLength(0) - 1, j] -= newTable[i, j]; } } } } return(newTable); }
//Добавляем переменные в таблицу private void newTableDV(ref Fraction[,] table, ref int[] basic, bool isMax) { //Проходимся по массиву с базисными переменными не затрагивая последний элемент(целевая функция) //считаем, сколько нам понадобится добавлять переменных int count = 0; for (int k = 0; k < basic.Length - 1; k++) { if (basic[k] == 0) { count++; } } //Добавлять новые переменные будем начиная с номера int countN = table.GetLength(1); //Создаем таблицу нового размера, чтобы добавить новые переменные Fraction[,] newTable = new Fraction[table.GetLength(0), countN + count]; //обнуляем таблицу for (int i = 0; i < newTable.GetLength(0); i++) { for (int j = 0; j < newTable.GetLength(1); j++) { newTable[i, j] = new Fraction(); } } //проходим по таблице for (int i = 0; i < table.GetLength(0); i++) { //копируем строку из старой таблицы for (int j = 0; j < table.GetLength(1); j++) { newTable[i, j] = table[i, j]; } if (i < basic.Length - 1) { if (basic[i] == 0) { basic[i] = countN; newTable[i, countN] = new Fraction(isMax ? 1 : -1); countN++; } } } table = newTable; }
//Строим двойственную задачу private Fraction[,] DV() { Fraction[,] tableDvoistv = new Fraction[this.table.GetLength(1), this.table.GetLength(0)]; //обнуляем таблицу for (int i = 0; i < tableDvoistv.GetLength(0); i++) { for (int j = 0; j < tableDvoistv.GetLength(1); j++) { tableDvoistv[i, j] = new Fraction(); } } //Значение целевой функции tableDvoistv[tableDvoistv.GetLength(0) - 1, 0] = this.table[this.table.GetLength(0) - 1, 0]; //Коэфициенты целевой функции for (int i = 0; i < this.table.GetLength(0) - 1; i++) { tableDvoistv[tableDvoistv.GetLength(0) - 1, 1 + i] = table[i, 0]; } //Свободные члены for (int i = 1; i < this.table.GetLength(1); i++) { tableDvoistv[i - 1, 0] = table[table.GetLength(0) - 1, i]; } //Коэффициенты for (int j = 0; j < tableDvoistv.GetLength(0) - 1; j++) { for (int i = 1; i < tableDvoistv.GetLength(1); i++) { tableDvoistv[j, i] = table[i - 1, j + 1]; } } return(tableDvoistv); }
/* * Составляем новую симплекс таблицу для решения задачи методом больших штрафов * вводим базисные переменные в уравнения, в которых их нет, вычисляем новую целевую * функцию */ private Fraction[,] TableForMSolution(Fraction M) { //Проходимся по массиву с базисными переменными не затрагивая последний элемент(целевая функция) //считаем, сколько нам понадобится добавлять переменных int count = 0; for (int k = 0; k < basic.Length - 1; k++) { if (basic[k] == 0) { count++; } } //Добавлять новые переменные будем начиная с номера int countN = table.GetLength(1); //Создаем таблицу нового размера, чтобы добавить новые переменные Fraction[,] newTable = new Fraction[table.GetLength(0), countN + count]; //обнуляем таблицу for (int i = 0; i < newTable.GetLength(0); i++) { for (int j = 0; j < newTable.GetLength(1); j++) { newTable[i, j] = new Fraction(); } } //поднимаемся по таблице снизу for (int i = table.GetLength(0) - 1; i >= 0; i--) { //Копируем строку из старой таблицы for (int j = 0; j < table.GetLength(1); j++) { newTable[i, j] = table[i, j]; } if (i < basic.Length - 1) { //Если мы уже проходимся по строке с базовым элементом Fraction mnojitel; if (basic[i] == 0) { //Если не было базовой переменной, то добавляем ее и множитель будет равен М basic[i] = countN; newTable[i, countN] = new Fraction(1); mnojitel = M; countN++; } else { //Иначе, множитель будет равен коэффициенту при данной переменной в начальной целевой функции mnojitel = table[table.GetLength(0) - 1, basic[i]]; } //Умножаем строку на множитель и отнимаем от новой целевой функции for (int j = 0; j < table.GetLength(1); j++) { newTable[table.GetLength(0) - 1, j] -= mnojitel * newTable[i, j]; } } } return(newTable); }
public static void convert(StreamReader inp, StreamWriter outp) { int m, n; string[] line = inp.ReadLine().Split(' '); m = Int32.Parse(line[0]); n = Int32.Parse(line[1]); outp.WriteLine("{0} {1}", m, n); for (int i = 0; i <= m; i++) { outp.Write("{0}", 0); if (i != n) { outp.Write(" "); } } outp.WriteLine(); Fraction[,] table = new Fraction[n, m]; Fraction min = new Fraction(1); for (int i = 0; i < n; i++) { string l = inp.ReadLine(); if (l != null && l.Length > 0) { string[] part = l.Split(' '); for (int j = 0; j < m; j++) { if (part[j].Contains("/")) { string[] tmp = part[j].Split('/'); table[i, j] = new Fraction(Int32.Parse(tmp[0]), Int32.Parse(tmp[1])); } else { table[i, j] = new Fraction(Int32.Parse(part[j])); } if (table[i, j] < min) { min = table[i, j]; } } } } if (min != 1) { min *= -1; Fraction d = new Fraction(1); min += d; for (int i = 0; i < table.GetLength(0); i++) { for (int j = 0; j < table.GetLength(1); j++) { table[i, j] += min; } } } for (int i = 0; i < table.GetLength(1); i++) { outp.Write("1 "); for (int j = 0; j < table.GetLength(0); j++) { outp.Write("{0} ", (String)table[j, i]); } outp.WriteLine(); } outp.Write("{0} ", 0); for (int i = 0; i < n; i++) { outp.Write("{0}", -1); if (i != n - 1) { outp.Write(" "); } } outp.WriteLine(); }