예제 #1
0
        public Tableau(double[] min, double[][] constraintsLE)
        {
            Rows = new TableauRow[constraintsLE.Length];
            int vars = min.Length;

            mColNames = new string[vars + constraintsLE.Length + 1];
            for (int i = 0; i < vars; i++)
            {
                mColNames[i] = "x" + (i + 1);
            }
            for (int i = 0; i < constraintsLE.Length; i++)
            {
                mColNames[vars + i] = "s" + (i + 1);
            }
            mColNames[vars + constraintsLE.Length] = "p";

            for (int i = 0; i < constraintsLE.Length; i++)
            {
                if (constraintsLE[i].Length != vars + 1)
                {
                    throw new Exception();
                }

                List <double> values = new List <double>(constraintsLE[i]);
                values.RemoveAt(vars);
                for (int j = 0; j < i; j++)
                {
                    values.Add(0);
                }
                values.Add(1);
                for (int j = i; j < constraintsLE.Length; j++)
                {
                    values.Add(0);
                }

                Rows[i] = new TableauRow(vars + i, values.ToArray(), constraintsLE[i][vars]);
            }

            List <double> eqValues = new List <double>(min);

            for (int i = 0; i < constraintsLE.Length; i++)
            {
                eqValues.Add(0);
            }
            eqValues.Add(1);

            ResultRow = new TableauRow(vars + constraintsLE.Length, eqValues.ToArray(), 0);
        }
예제 #2
0
        static void SolveWithSimplex(Tableau tableau, double e)
        {
            while (tableau.ResultRow.Values.Any(v => v < 0))
            {
                tableau.Print(Console.WriteLine);
                Console.WriteLine();
                Console.WriteLine();
                Console.WriteLine();

                int pivotColumn = tableau.ResultRow.Values.Select((v, i) => new { idx = i, value = v })
                                  .OrderBy(vi => vi.value).FirstOrDefault(vi => vi.value < 0)?.idx ?? -1;
                if (pivotColumn == -1)
                {
                    break;
                }

                int pivotRowIdx = tableau.Rows.Select((row, i) => new { row, i })
                                  .Where(ri => ri.row.Values[pivotColumn] > 0)
                                  .MinBy(ri => ri.row.Answer / ri.row.Values[pivotColumn])
                                  .FirstOrDefault()?.i ?? -1;
                if (pivotRowIdx == -1)
                {
                    break;
                }

                tableau.Rows[pivotRowIdx].PivotIndex = pivotColumn;
                TableauRow pivotRow = tableau.Rows[pivotRowIdx];
                for (int i = 0; i < tableau.Rows.Length; i++)
                {
                    if (i != pivotRowIdx)
                    {
                        ClearCell(ref tableau.Rows[i], pivotRow, pivotColumn, e);
                    }
                }
                ClearCell(ref tableau.ResultRow, pivotRow, pivotColumn, e);
            }
            tableau.Print(Console.WriteLine);
        }
예제 #3
0
        private static void ClearCell(ref TableauRow thisRow, TableauRow pivotRow, int pivotColumn, double e)
        {
            if (Math.Abs(thisRow.Values[pivotColumn]) > e)
            {
                double thisValue  = thisRow.Values[pivotColumn];
                double pivotValue = pivotRow.Values[pivotColumn];

                if (Math.Sign(thisValue) == Math.Sign(pivotValue))
                {
                    pivotValue = -Math.Abs(pivotValue);
                }
                else
                {
                    pivotValue = Math.Abs(pivotValue);
                }
                thisValue = Math.Abs(thisValue);

                for (int j = 0; j < pivotRow.Values.Length; j++)
                {
                    thisRow.Values[j] = pivotValue * thisRow.Values[j] + thisValue * pivotRow.Values[j];
                }
                thisRow.Answer = pivotValue * thisRow.Answer + thisValue * pivotRow.Answer;
            }
        }