private ResultType SolveTableau(ref Tableau t) { Variable head; Variable row; var prevTargetVal = 0d; var isCircular = false; while (t.FindPivot(out head, out row)) { t = NextTableau(t, head, row); //check cycles if (Math.Abs(t.TargetEquation.Coefficient - prevTargetVal) <= double.Epsilon) { isCircular = true; break; } prevTargetVal = t.TargetEquation.Coefficient; } ResultFactors = (from e in t.Equations where e.LeftTerm.Type != VariableType.Slack select new VariableFactor(e.LeftTerm, e.Coefficient)).ToArray(); if (isCircular) { return(ResultType.InfinitResults); } return(ResultType.OneResult); }
public ResultType Solve() { var tableau = new Tableau(_equations); tableau = PreprocessTableau(tableau); return(SolveTableau(ref tableau)); }
private Tableau PreprocessTableau(Tableau t) { //check if there is no need to preprocess the table if (t.Equations.All(e => e.LeftTerm.Type == VariableType.Target || e.Coefficient >= 0)) { return(t); } var eqs = new Equation[t.Equations.Length]; var tVar = Variable.Problem(0); for (var i = 0; i < eqs.Length - 1; i++) { eqs[i] = t.Equations[i].AddFactor(new VariableFactor(tVar, 1)); } var f = new VariableFactor[t.Equations[0].Factors.Length]; for (var i = 0; i < f.Length; i++) { f[i] = new VariableFactor(t.Equations[0].Factors[i].Variable, 0); } var target = new Equation(Variable.Target(), f, 0); target = target.AddFactor(new VariableFactor(tVar, -1)); eqs[eqs.Length - 1] = target; t = new Tableau(eqs); for (var i = 0; i < eqs.Length; i++) { if (t[i].LeftTerm.Type != VariableType.Target && t[i].Coefficient < 0) { t = NextTableau(t, tVar, t[i].LeftTerm); } } SolveTableau(ref t); var mainEquations = new Equation[t.Equations.Length]; for (var i = 0; i < mainEquations.Length - 1; i++) { mainEquations[i] = t.Equations[i].RemoveFactor(tVar); } var mainTarget = target.RemoveFactor(tVar); mainEquations[mainEquations.Length - 1] = mainTarget; return(new Tableau(mainEquations)); }
public static Tableau NextTableau(Tableau t, Variable pHead, Variable pRow) { var pIndex = t.IndexOf(pRow); var pEq = t[pRow].Switch(pHead); var equations = new Equation[t.Equations.Length]; for (int i = 0; i < equations.Length; i++) { if (i == pIndex) { equations[i] = pEq; } else { equations[i] = t[i].Resolve(pEq); } } return(new Tableau(equations)); }