internal static void CreatePhaseOneObjective(this SimplexModelDecorator model) { if (!model.IsTwoPhase) { return; } //Steps //#.Modify the constraints so that the RHS of each constraint is nonnegative (This requires that each constraint with a negative RHS be multiplied by - 1.Remember that if you multiply an inequality by any negative number, the direction of the inequality is reversed!). After modification, identify each constraint as a ≤, ≥ or = constraint. //#.Convert each inequality constraint to standard form(If constraint i is a ≤ constraint, we add a slack variable si; and if constraint i is a ≥ constraint, we subtract an excess variable ei). //Steps //1.Add an artificial variable ai to the constraints identified as ≥ or = constraints at the end of Step 1.Also add the sign restriction ai ≥ 0. //2.In the phase I, ignore the original LP’s objective function, instead solve an LP whose objective function is minimizing w = ai(sum of all the artificial variables).The act of solving the Phase I LP will force the artificial variables to be zero. //3.Since each artificial variable will be in the starting basis, all artificial variables must be eliminated from row 0 before beginning the simplex. Now solve the transformed problem by the simplex. //1) add all of artificial variables in orginal objective function to the phaseonefunction //copy the objective function foreach (Term item in model.ObjectiveFunction.Terms) { if (item.VarType == VariableType.Artificial) { model.PhaseObjectiveFunction.Terms.Add(new Term() { Factor = 1, Core = item.Core }); } else { model.PhaseObjectiveFunction.Terms.Add(new Term() { Factor = 0, Core = item.Core }); } } ////2) change signt the factor value of term in new objective fonction terms and add positive balance variable ("w") //foreach (Term term in model.PhaseObjectiveFunction.Terms) //{ // term.Factor *= -1; //} //3) add balance type variable ("w") to the new objective function //model.PhaseObjectiveFunction.Terms.Insert(0, new Term() { Factor = 1, VarType = VariableType.Balance, Vector = "w", Index = 0 }); //Let us define new objective function as negative (-w) model.PhaseObjectiveFunction.RightHandValue = 0; //4) find all artificial variable that has factor value is equal to 0 in cosntarint terms and put the artificial variable value in the new objective function; // all artificial variables must be eliminated from row 0 before we can solve Phase I foreach (Subject constraint in model.Subjects) { if (constraint.Terms.Any(term => term.VarType == VariableType.Artificial && term.Factor == 1)) { for (int i = 0; i < constraint.Terms.Count; i++) { model.PhaseObjectiveFunction.Terms[i].Factor -= constraint.Terms[i].Factor; } model.PhaseObjectiveFunction.RightHandValue -= constraint.RightHandValue; } //if (constraint.Terms.Any(term => term.Basic && term.Factor == 1)) //{ // //Find // List<Term> tmp_willaddedterms = constraint.Terms.Where(term => term.Factor != 0).ToList(); // foreach (Term item in tmp_willaddedterms) // { // //tmp_term = null; // tmp_term = model.PhaseObjectiveFunction.Terms.Find(term => term.Vector.Equals(item.Vector)); // //if (tmp_term != null) // tmp_term.Factor -= item.Factor; // //else // // model.PhaseObjectiveFunction.Terms.Add(new Term() { Factor = item.Factor, VarType = item.VarType, Vector = item.Vector }); // } // if (tmp_willaddedterms.Count > 0) // { // model.PhaseObjectiveFunction.RightHandValue -= constraint.RightHandValue; // } //} } //6) sort the terms of new objective TermComparer tc = new TermComparer(); model.PhaseObjectiveFunction.Terms.Sort(tc); }
public static void ConvertStandardModel(this ISimplexModel model) { //Steps //1.Modify the constraints so that the RHS of each constraint is nonnegative (This requires that each constraint with a negative RHS be multiplied by - 1.Remember that if you multiply an inequality by any negative number, the direction of the inequality is reversed!). After modification, identify each constraint as a ≤, ≥ or = constraint. //2.Convert each inequality constraint to standard form(If constraint i is a ≤ constraint, we add a slack variable si; and if constraint i is a ≥ constraint, we subtract an excess variable ei). //Two phase standardization #region Phase I //1) Check and update Right Hand Side- RHS value for positive UpdateNegativeRHSValues(model); //2) Add variables for BFS //2.1) add slack,excess and artificial Term to constarints string m_slackPrefix = "s"; int m_slackcount = 1; string m_excessPrefix = "e"; int m_excesscount = 1; string m_artificialPrefix = "a"; int m_artificialcount = 1; foreach (Subject constarint in model.Subjects) { //1) add slack Term for not equal constarint switch (constarint.Equality) { case EquailtyType.LessEquals: // if constarint equation <= then plus Slack variable at the left side constarint.AddTerm(1, VariableType.Slack, m_slackPrefix + m_slackcount.ToString()); m_slackcount++; break; case EquailtyType.GreaterEquals: // if constarint equation >= then minus excess variable and plus artificial variable at the left side constarint.AddTerm(-1, VariableType.Excess, m_excessPrefix + m_excesscount.ToString()); constarint.AddTerm(1, VariableType.Artificial, m_artificialPrefix + m_artificialcount.ToString()); m_excesscount++; m_artificialcount++; break; default: // if constarint equation is eqal and subject dos nat contain basic term, then plus artificial variable at the left side if (!constarint.Terms.Any(term => term.Basic == true)) { constarint.AddTerm(1, VariableType.Artificial, m_artificialPrefix + m_artificialcount.ToString()); m_artificialcount++; } break; } } //3) find the varibles in model and distinct them Dictionary <string, TermCore> m_VectorList = new Dictionary <string, TermCore>(); //3.1) Check and collect vector label for objective funtion foreach (Term term in model.ObjectiveFunction.Terms) { if (!m_VectorList.ContainsKey(term.Vector)) { m_VectorList.Add(term.Vector, term.Core); } } //3.2) //Check and collect vector label for constranit foreach (Subject constarint in model.Subjects) { foreach (Term term in constarint.Terms) { if (!m_VectorList.ContainsKey(term.Vector)) { m_VectorList.Add(term.Vector, term.Core); } } } //3) expand the objective function and all constarints with not exsit variable in Clause //sort the vector list foreach (KeyValuePair <string, TermCore> item in m_VectorList) { if (!model.ObjectiveFunction.IsVectorContained(item.Key)) { model.ObjectiveFunction.Terms.Add(new Term() { Factor = 0, Core = item.Value }); } foreach (Subject constarint in model.Subjects) { if (!constarint.IsVectorContained(item.Key)) { constarint.Terms.Add(new Term() { Factor = 0, Core = item.Value }); } } } //Sort clause terms TermComparer tc = new TermComparer(); model.ObjectiveFunction.Terms.Sort(tc); foreach (Subject constarint in model.Subjects) { constarint.Terms.Sort(tc); } //4) change signt the factor value of term in objective fonction terms and add positive balance variable ("Z") foreach (Term term in model.ObjectiveFunction.Terms) { term.Factor *= -1; } model.ObjectiveFunction.RightHandValue = 0; //find and flag basic variable // if one of term that is non original contained only one cosntarint that ise basic varibale, let us find it int tmp_zeroCounter = 0; int tmp_OneCounter = 0; int tmp_rowcount = model.Subjects.Count; for (int i = 0; i < model.ObjectiveFunction.Terms.Count; i++) { tmp_zeroCounter = 0; tmp_OneCounter = 0; foreach (Subject constarint in model.Subjects) { if (constarint.Terms[i].Factor == 0) { tmp_zeroCounter++; } else if (constarint.Terms[i].Factor == 1) { tmp_OneCounter++; } } if (tmp_OneCounter == 1 && (tmp_OneCounter + tmp_zeroCounter == tmp_rowcount)) { model.ObjectiveFunction.Terms[i].Basic = true; } else { model.ObjectiveFunction.Terms[i].Basic = false; } } ////reflect basic flag from objective function to the cosntarint //for (int i = 0; i < model.ObjectiveFunction.Terms.Count; i++) //{ // foreach (Subject constarint in model.Subjects) // { // constarint.Terms[i].Basic= model.ObjectiveFunction.Terms[i].Basic; // } //} //5) check the term count is equeal for objective function and all of constarints #endregion #region UnitMatrix //List<Term> tmp_basicVariableslist = model.ObjectiveFunction.Terms.Where(item => item.isBasic).ToList(); //Dictionary<Term, int> tmp_UnitMatrixDictionary = new Dictionary<Term, int>(); //int tmp_index = -1; //foreach (Term item in tmp_basicVariableslist) //{ // tmp_index = -1; // foreach (Subject constarint in model.Subjects) // { // tmp_index = constarint.Terms.FindIndex(consitem => consitem.Vector == item.Vector && consitem.Factor == 1); // if (tmp_index > -1) // { // tmp_UnitMatrixDictionary.Add(item, tmp_index); // break; // } // } //} #endregion }