Ejemplo n.º 1
0
        private void PrintSolveLog(TextBox txtBox)
        {
            try
            {
                LockWindowUpdate(TaskInfotextBox.Handle);

                TaskInfotextBox.Clear();

                if (IsNewTask)
                {
                    CanonicalN        = SourceN;
                    CanonicalM        = SourceM;
                    CanonicalTaskType = SourceTaskType;
                    for (int i = 0; i < SourceM; i++)
                    {
                        CanonicalSign[i]    = SourceSign[i];
                        CanonicalVectorb[i] = SourceVectorb[i];
                        for (int j = 0; j < SourceN; j++)
                        {
                            CanonicalVectorc[j]    = SourceVectorc[j];
                            CanonicalMatrixA[i, j] = SourceMatrixA[i, j];
                        }
                    }

                    txtBox.AppendText("Исходная задача:");
                    txtBox.AppendText(Environment.NewLine);
                    txtBox.AppendText(Environment.NewLine);

                    for (int i = 0; i < SourceM; i++)
                    {
                        PrintRest(txtBox, SourceMatrixA, SourceSign, SourceVectorb, i, SourceN);
                    }

                    txtBox.AppendText(Environment.NewLine);
                    PrintF(txtBox, SourceVectorc, SourceN, SourceTaskType);
                    txtBox.AppendText(Environment.NewLine);
                    txtBox.AppendText("Приводим к каноническому виду: ");

                    int  LStepCount     = 1;
                    bool LCanonicalForm = true;
                    for (int i = 0; i < SourceM; i++)
                    {
                        switch (SourceSign[i])
                        {
                        case 0:     // '='
                            LCanonicalForm = false;

                            txtBox.AppendText(Environment.NewLine);
                            txtBox.AppendText(String.Format("{0}. Избавляемся от знака равенства в {1} - ограничении. Что бы поменять знак '=' на неравенство '<=', вводим в задачу еще одно такое же ограничение, но с противоположенными знаками: ", LStepCount, i + 1));
                            txtBox.AppendText(Environment.NewLine);

                            CanonicalM++;
                            for (int j = 0; j < CanonicalN; j++)
                            {
                                CanonicalMatrixA[CanonicalM - 1, j] = -CanonicalMatrixA[i, j];
                            }

                            CanonicalVectorb[CanonicalM - 1] = -CanonicalVectorb[i];
                            CanonicalSign[i] = 2;
                            CanonicalSign[CanonicalM - 1] = 2;

                            txtBox.AppendText(Environment.NewLine);
                            PrintRest(txtBox, CanonicalMatrixA, CanonicalSign, CanonicalVectorb, CanonicalM - 1, CanonicalN);

                            LStepCount++;
                            break;

                        case 1:     // '>='
                            LCanonicalForm = false;

                            txtBox.AppendText(Environment.NewLine);
                            txtBox.AppendText(String.Format("{0}. Избавляемся от знака больше-равно в {1} - ограничении. Что бы поменять неравенство '>=' на неравенство '<=', меняем знаки в этом ограничении на противоположенные: ", LStepCount, i + 1));
                            txtBox.AppendText(Environment.NewLine);

                            CanonicalVectorb[i] = -CanonicalVectorb[i];
                            for (int j = 0; j < CanonicalN; j++)
                            {
                                CanonicalMatrixA[i, j] = -CanonicalMatrixA[i, j];
                            }

                            CanonicalSign[i] = 2;

                            txtBox.AppendText(Environment.NewLine);
                            PrintRest(txtBox, CanonicalMatrixA, CanonicalSign, CanonicalVectorb, i, CanonicalN);

                            LStepCount++;
                            break;
                        }
                    }

                    // Меняем знаки при целевой функции
                    if (SourceTaskType == 0)
                    {
                        for (int i = 0; i < CanonicalN; i++)
                        {
                            CanonicalVectorc[i] = -CanonicalVectorc[i];
                        }

                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText(String.Format("{0}. Т.к. задача на максимизацию, то меняем знаки при целевой функции:", LStepCount));
                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText(Environment.NewLine);
                        PrintF(txtBox, CanonicalVectorc, CanonicalN, CanonicalTaskType);
                        LStepCount++;
                    }

                    if (LCanonicalForm)
                    {
                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText("Задача уже записана в каноническом виде, и не требует дополнительных преобразований.");
                        txtBox.AppendText(Environment.NewLine);
                    }
                    else
                    {
                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText("Записываем канонический вид задачи, после преобразований: ");
                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText(Environment.NewLine);

                        for (int i = 0; i < CanonicalM; i++)
                        {
                            PrintRest(txtBox, CanonicalMatrixA, CanonicalSign, CanonicalVectorb, i, CanonicalN);
                        }

                        txtBox.AppendText(Environment.NewLine);
                        PrintF(txtBox, CanonicalVectorc, CanonicalN, CanonicalTaskType);
                        txtBox.AppendText(Environment.NewLine);
                    }
                }
                else
                {
                    txtBox.AppendText("Исходная задача:");
                    txtBox.AppendText(Environment.NewLine);
                    txtBox.AppendText(Environment.NewLine);

                    for (int i = 0; i < CanonicalM; i++)
                    {
                        PrintRest(txtBox, CanonicalMatrixA, CanonicalSign, CanonicalVectorb, i, CanonicalN);
                    }

                    txtBox.AppendText(Environment.NewLine);
                    PrintF(txtBox, CanonicalVectorc, CanonicalN, CanonicalTaskType);
                    txtBox.AppendText(Environment.NewLine);

                    txtBox.AppendText(Environment.NewLine);
                    txtBox.AppendText("Задача уже записана в каноническом виде, и не требует дополнительных преобразований.");
                    txtBox.AppendText(Environment.NewLine);
                }

                for (int i = 0; i < SimplexTables.Count; i++)
                {
                    SimplexTable smptbl = SimplexTables[i];
                    txtBox.AppendText(Environment.NewLine);
                    txtBox.AppendText("----------------------------");

                    if (smptbl.Solved)
                    {
                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText("Среди значений коэффициентов целевой функции нет отрицательных. Поэтому задача решена!");
                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText(Environment.NewLine);

                        for (int j = 0; j < smptbl.N; j++)
                        {
                            txtBox.AppendText(String.Format("x{0} = {1}", j + 1, smptbl.Roots(j)));
                            txtBox.AppendText(Environment.NewLine);
                        }

                        txtBox.AppendText(Environment.NewLine);
                        if (smptbl.TaskType == 1)
                        {
                            txtBox.AppendText("Так как исходной задачей был поиск минимума, оптимальное решение есть свободный член строки F, взятый с противоположным знаком.");
                            txtBox.AppendText(Environment.NewLine);
                            txtBox.AppendText(String.Format("Значение целевой функции: Fmin = {0}", -smptbl.FunctionValue()));
                        }
                        else
                        {
                            txtBox.AppendText(String.Format("Значение целевой функции: Fmin = {0}", smptbl.FunctionValue()));
                        }

                        return;
                    }

                    if (smptbl.Infinity)
                    {
                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText("Оптимального решения не существует! Т.к. данная задача не ограничена.");
                        return;
                    }

                    if (smptbl.Unsolvable)
                    {
                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText("Так как в строке с отрицательным свободным членом нет отрицательных элементов, то система ограничений не совместна и задача не имеет решения.");
                        return;
                    }

                    if (smptbl.NonIntegerSolved)
                    {
                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText("Среди значений коэффициентов целевой функции нет отрицательных. Поэтому найдено оптимальное решение.");
                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText(Environment.NewLine);

                        for (int j = 0; j < smptbl.N; j++)
                        {
                            txtBox.AppendText(String.Format("x{0} = {1}", j + 1, smptbl.RootsFraction(j).ToString()));
                            txtBox.AppendText(Environment.NewLine);
                        }

                        txtBox.AppendText(Environment.NewLine);
                        if (smptbl.TaskType == 1)
                        {
                            txtBox.AppendText("Так как исходной задачей был поиск минимума, оптимальное решение есть свободный член строки F, взятый с противоположным знаком.");
                            txtBox.AppendText(Environment.NewLine);
                            txtBox.AppendText(String.Format("Значение целевой функции: Fmin = {0}", (-smptbl.FunctionValueFraction()).ToString()));
                        }
                        else
                        {
                            txtBox.AppendText(String.Format("Значение целевой функции: Fmin = {0}", smptbl.FunctionValueFraction().ToString()));
                        }

                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText("Получившееся оптимальное решение нецелочисленное. Среди свободных членов находим переменную с максимальным дробным числом:");
                        txtBox.AppendText(Environment.NewLine);

                        double value    = 0;
                        int    MaxIndex = 0;
                        double MaxValue = 0;
                        txtBox.AppendText(Environment.NewLine);
                        for (int j = 0; j < smptbl.M; j++)
                        {
                            if (smptbl.BaseVector(j) <= smptbl.N)
                            {
                                value = Math.Abs(smptbl.Table(j, 0)) - Math.Abs(Math.Floor(smptbl.Table(j, 0)));
                                if (MaxValue < value)
                                {
                                    MaxValue = value;
                                    MaxIndex = j;
                                }
                                txtBox.AppendText(String.Format("x{0} = {1} = {2}", smptbl.BaseVector(j), smptbl.FractionTable(j, 0).ToString(), smptbl.Table(j, 0)));
                                txtBox.AppendText(Environment.NewLine);
                            }
                        }

                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText("x" + smptbl.BaseVector(MaxIndex).ToString() + " - свободный член с максимальным дробным числом. Поэтому вводим дополнительное ограничение по " + (MaxIndex + 1) + " строке:");
                        txtBox.AppendText(Environment.NewLine);

                        string LLineStr = "";
                        txtBox.AppendText(Environment.NewLine);

                        double   sign          = smptbl.Table(MaxIndex, 0) / smptbl.Table(MaxIndex, 0);
                        Fraction FractionValue = new Fraction(smptbl.FractionTable(MaxIndex, 0));

                        if (FractionValue < 0)
                        {
                            FractionValue = FractionValue * -1;
                        }

                        FractionValue = FractionValue - Math.Truncate(Math.Abs(smptbl.FractionTable(MaxIndex, 0).ToDouble()));

                        bool isfirst = true;
                        FractionValue = FractionValue * sign * -1;
                        LLineStr      = LLineStr + FractionValue.ToString() + " = ";
                        for (int j = 1; j < smptbl.Сols; j++)
                        {
                            if (smptbl.FractionTable(MaxIndex, j) >= 0)
                            {
                                value         = Math.Truncate(smptbl.FractionTable(MaxIndex, j).ToDouble());
                                FractionValue = -(smptbl.FractionTable(MaxIndex, j) - value);
                            }
                            else
                            {
                                value         = Math.Abs(Math.Truncate(smptbl.FractionTable(MaxIndex, j).ToDouble()));
                                FractionValue = -(smptbl.FractionTable(MaxIndex, j) + value + 1);
                            }

                            if (FractionValue > 0)
                            {
                                if (isfirst)
                                {
                                    LLineStr = LLineStr + FractionValue.ToString() + "x" + j;
                                }
                                else
                                {
                                    LLineStr = LLineStr + " + " + FractionValue.ToString() + "x" + j;
                                }
                                isfirst = false;
                            }
                            else
                            {
                                LLineStr = LLineStr + " - " + (FractionValue * -1).ToString() + "x" + j;
                                isfirst  = false;
                            }
                        }

                        LLineStr = LLineStr + " + " + "x" + (smptbl.N + smptbl.M + 1);

                        txtBox.AppendText(LLineStr);
                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText(Environment.NewLine);

                        txtBox.AppendText("Пересчитываем получившуюся таблицу:");

                        continue;
                    }

                    if ((smptbl.PivotCol != -1) & (smptbl.PivotRow != -1))
                    {
                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText(String.Format("Итерация {0}:", i + 1));
                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText(String.Format("Ведущий столбец: {0}", SimplexTables[i].PivotCol));
                        txtBox.AppendText(Environment.NewLine);
                        txtBox.AppendText(String.Format("Ведущая строка: {0}", SimplexTables[i].PivotRow + 1));
                    }
                }
            }
            finally
            {
                LockWindowUpdate(IntPtr.Zero);
            }
        }