示例#1
0
        public LPSolution Solve()
        {
            LinearProgram.VerifyVariables();

            Tableau previousTableau = new Tableau();

            ConstraintRow[] constraints = new ConstraintRow[LinearProgram.Constraints.Length];
            for (int i = 0; i < constraints.Length; i++)
            {
                constraints[i] = new ConstraintRow(i, constraints.Length, LinearProgram.Constraints[i].GetVars(), LinearProgram.Constraints[i].Constant);
            }

            previousTableau.Constraints  = constraints;
            previousTableau.ObjectiveRow = new ObjectiveRow(constraints.Length, LinearProgram.ObjectiveFunction.GetVars());

            Variable[] emptyVars      = previousTableau.ObjectiveRow.Vars.Where(var => !var.IsSlack).Select(var => var.Empty).ToArray();
            Tableau    currentTableau = Tableau.EmptyTableau(previousTableau.Constraints.Length, emptyVars);

            while (MostNegitive(previousTableau, out Variable mostNegitive))
            {
                int    index         = 0;
                double leastPositive = previousTableau.Constraints.Length > 0 ? previousTableau.Constraints[index].RatioTest(mostNegitive) : -1;
                for (int i = 0; i < previousTableau.Constraints.Length; i++)
                {
                    double rt = previousTableau.Constraints[i].RatioTest(mostNegitive);
                    if (rt > 0 && rt < leastPositive)
                    {
                        leastPositive = rt; index = i;
                    }
                }

                if (leastPositive == 0)
                {
                    throw new Exception("Least Positive is Unchanged");
                }

                currentTableau.Constraints[index] = previousTableau.Constraints[index].PivotRow(mostNegitive.Index);

                currentTableau.ObjectiveRow = previousTableau.ObjectiveRow.Normalize(mostNegitive.Index, currentTableau.Constraints[index].Vars, currentTableau.Constraints[index].RHS);

                for (int i = 0; i < currentTableau.Constraints.Length; i++)
                {
                    if (i != index)
                    {
                        currentTableau.Constraints[i] = previousTableau.Constraints[i].Normalize(mostNegitive.Index, currentTableau.Constraints[index].Vars, currentTableau.Constraints[index].RHS);
                    }
                }

                previousTableau = currentTableau.Copy();
                currentTableau  = Tableau.EmptyTableau(previousTableau.Constraints.Length, emptyVars);
            }

            Console.WriteLine(previousTableau);
            return(new LPSolution(previousTableau));
        }
示例#2
0
 public Tableau Copy()
 {
     ConstraintRow[] constraintRow = new ConstraintRow[Constraints.Length];
     Constraints.CopyTo(constraintRow, 0);
     return(new Tableau()
     {
         Constraints = constraintRow, ObjectiveRow = new ObjectiveRow()
         {
             Vars = new List <Variable>(ObjectiveRow.Vars).ToArray(), RHS = ObjectiveRow.RHS
         }
     });
 }
示例#3
0
 public static Tableau EmptyTableau(int constraintCount, Variable[] emptyVariables)
 {
     ConstraintRow[] constraints = new ConstraintRow[constraintCount];
     for (int i = 0; i < constraints.Length; i++)
     {
         constraints[i] = new ConstraintRow(i, constraintCount, new List <Variable>(emptyVariables).ToArray(), 0);
     }
     return(new Tableau()
     {
         Constraints = constraints, ObjectiveRow = new ObjectiveRow(constraints.Length, new List <Variable>(emptyVariables).ToArray())
     });
 }
示例#4
0
            public static ConstraintRowParser Create(Constraint constraint)
            {
                if (constraint == null || constraint.ElementaryConstraints.Length == 0)
                {
                    return(null);
                }

                ConstraintRowParser constraintRowParser = new ConstraintRowParser();

                System.Action <ConstraintRow[], ElementaryConstraint, int, int> AssignRow = (rows, ec, constraintRow, localRow) =>
                {
                    if (rows[constraintRow] != null)
                    {
                        throw new Exception("Row index " + constraintRow + " already assigned: " + rows[constraintRow].ElementaryConstraint.NativeName);
                    }

                    rows[constraintRow] = new ConstraintRow(ec, localRow);
                };

                ElementaryConstraint[] ordinaryElementaryConstraints = constraint.GetOrdinaryElementaryConstraints();
                foreach (ElementaryConstraint ec in ordinaryElementaryConstraints)
                {
                    if (ec.NumRows > 1)
                    {
                        // Only rotational QuatLock ("QL") and translational SphericalRel ("SR") with three rows.
                        ConstraintRow[] rows = ec.NativeName == "QL" ? constraintRowParser.RotationalRows :
                                               ec.NativeName == "SW" ? constraintRowParser.RotationalRows :
                                               ec.NativeName == "SR" ? constraintRowParser.TranslationalRows :
                                               null;
                        if (rows == null)
                        {
                            throw new Exception("Unknown elementary constraint with name: " + ec.NativeName);
                        }

                        // For Swing we should assign rows 0 and 1.
                        for (int row = 0; row < ec.NumRows; ++row)
                        {
                            AssignRow(rows, ec, row, row);
                        }
                    }
                    else if (ec.NumRows == 1)
                    {
                        // Dot2 for single translational row ("D2_U" along U and "D2_V" along V).
                        int translationalRow = ec.NativeName == "D2_U" ? 0 :
                                               ec.NativeName == "D2_V" ? 1 :
                                               ec.NativeName == "D2_N" ? 2 :
                                               ec.NativeName == "CN"   ? 2 :
                                               -1;
                        // Dot1 for single rotational row ("D1_VN" about U and "D1_UN" about V ).
                        int rotationalRow = ec.NativeName == "D1_VN" ? 0 :
                                            ec.NativeName == "D1_UN" ? 1 :
                                            ec.NativeName == "D1_UV" ? 2 :
                                            -1;

                        if (translationalRow < 0 && rotationalRow < 0)
                        {
                            throw new Exception("Unknown single row elementary constraint with name: " + ec.NativeName);
                        }

                        if (translationalRow >= 0)
                        {
                            AssignRow(constraintRowParser.TranslationalRows, ec, translationalRow, 0);
                        }
                        else
                        {
                            AssignRow(constraintRowParser.RotationalRows, ec, rotationalRow, 0);
                        }
                    }
                }

                return(constraintRowParser);
            }