Пример #1
0
        /*
         * После подготовки системы ограничений, отбрасывая столбцы добавленных переменных
         * и последнюю строку получаем первую симплекс таблицу
         */
        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;
        }
Пример #2
0
        /*
         * Составляем новую таблицу методом искусственного базиса
         * для решения задачи симплекс-методом
         */
        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);
        }
Пример #3
0
        //Добавляем переменные в таблицу
        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;
        }
Пример #4
0
        //Строим двойственную задачу
        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);
        }
Пример #5
0
        /*
         * Составляем новую симплекс таблицу для решения задачи методом больших штрафов
         * вводим базисные переменные в уравнения, в которых их нет, вычисляем новую целевую
         * функцию
         */
        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);
        }
Пример #6
0
        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();
        }