/// <summary> /// Remove the edit constraint previously added. /// <param name="v">Variable to which the edit constraint was added before.</param> /// </summary> private void RemoveEditVar(ClVariable v) { ClEditInfo cei = _editVarMap[v]; ClConstraint cn = cei.Constraint; RemoveConstraint(cn); }
/// <summary> /// Protected convenience function to insert an error variable /// into the _errorVars set, creating the mapping with Add as necessary. /// </summary> protected void InsertErrorVar(ClConstraint cn, ClAbstractVariable var) { HashSet <ClAbstractVariable> cnset; if (!_errorVars.TryGetValue(cn, out cnset)) { _errorVars.Add(cn, cnset = new HashSet <ClAbstractVariable>()); } cnset.Add(var); }
public ClEditInfo(ClConstraint cn, ClSlackVariable eplus, ClSlackVariable eminus, double prevEditConstant, int i) { _cn = cn; _clvEditPlus = eplus; _clvEditMinus = eminus; _prevEditConstant = prevEditConstant; _i = i; }
/// <summary> /// Same as AddConstraint, throws no exceptions. /// <returns> /// False if the constraint resulted in an unsolvable system, otherwise true. /// </returns> /// </summary> public bool TryAddConstraint(ClConstraint cn) { try { AddConstraint(cn); return(true); } catch (CassowaryRequiredFailureException) { return(false); } }
public void Parse() { UTF8Encoding ue = new UTF8Encoding(); byte[] ruleBytes = ue.GetBytes(Rule); MemoryStream ms = new MemoryStream(ruleBytes); Scanner s = new Scanner(ms); Parser p = new Parser(s); p.Context = Context; p.Parse(); _result = p.Value; if (p.errors.count > 0) throw new ExClParseError(Rule); }
/// <summary> /// Add a constraint to the solver. /// <param name="cn"> /// The constraint to be added. /// </param> /// </summary> public ClSimplexSolver AddConstraint(ClConstraint cn) { List <ClAbstractVariable> eplusEminus = new List <ClAbstractVariable>(2); ClDouble prevEConstant = new ClDouble(); ClLinearExpression expr = NewExpression(cn, /* output to: */ eplusEminus, prevEConstant); bool cAddedOkDirectly = TryAddingDirectly(expr); if (!cAddedOkDirectly) { // could not add directly AddWithArtificialVariable(expr); } _cNeedsSolving = true; if (cn.IsEditConstraint) { int i = _editVarMap.Count; ClEditConstraint cnEdit = (ClEditConstraint)cn; ClSlackVariable clvEplus = (ClSlackVariable)eplusEminus[0]; ClSlackVariable clvEminus = (ClSlackVariable)eplusEminus[1]; _editVarMap.Add(cnEdit.Variable, new ClEditInfo(cnEdit, clvEplus, clvEminus, prevEConstant.Value, i)); } if (_cOptimizeAutomatically) { Optimize(_objective); SetExternalVariables(); } return(this); }
/// <summary> /// Remove a constraint from the tableau. /// Also remove any error variable associated with it. /// </summary> public ClSimplexSolver RemoveConstraint(ClConstraint cn) /* throws ExClRequiredFailure, ExClInternalError */ { if (Trace) { FnEnterPrint("RemoveConstraint: " + cn); TracePrint(this.ToString()); } _cNeedsSolving = true; ResetStayConstants(); ClLinearExpression zRow = RowExpression(_objective); Set eVars = (Set) _errorVars[cn]; if (Trace) TracePrint("eVars == " + eVars); if (eVars != null) { foreach (ClAbstractVariable clv in eVars) { ClLinearExpression expr = RowExpression(clv); if (expr == null) { zRow.AddVariable(clv, -cn.Weight * cn.Strength.SymbolicWeight.AsDouble(), _objective, this); } else // the error variable was in the basis { zRow.AddExpression(expr, -cn.Weight * cn.Strength.SymbolicWeight.AsDouble(), _objective, this); } } } int markerVarsCount = _markerVars.Count; ClAbstractVariable marker = (ClAbstractVariable) _markerVars[cn]; _markerVars.Remove(cn); if (markerVarsCount == _markerVars.Count) // key was not found { throw new ExClConstraintNotFound(); } if (Trace) TracePrint("Looking to remove var " + marker); if (RowExpression(marker) == null) { // not in the basis, so need to do some more work Set col = (Set) _columns[marker]; if (Trace) TracePrint("Must pivot -- columns are " + col); ClAbstractVariable exitVar = null; double minRatio = 0.0; foreach (ClAbstractVariable v in col) { if (v.IsRestricted) { ClLinearExpression expr = RowExpression(v); double coeff = expr.CoefficientFor(marker); if (Trace) TracePrint("Marker " + marker + "'s coefficient in " + expr + " is " + coeff); if (coeff < 0.0) { double r = -expr.Constant / coeff; if (exitVar == null || r < minRatio) { minRatio = r; exitVar = v; } } } } if (exitVar == null) { if (Trace) TracePrint("exitVar is still null"); foreach (ClAbstractVariable v in col) { if (v.IsRestricted) { ClLinearExpression expr = RowExpression(v); double coeff = expr.CoefficientFor(marker); double r = expr.Constant / coeff; if (exitVar == null || r < minRatio) { minRatio = r; exitVar = v; } } } } if (exitVar == null) { // exitVar is still null if (col.Count == 0) { RemoveColumn(marker); } else { // put first element in exitVar IEnumerator colEnum = col.GetEnumerator(); colEnum.MoveNext(); exitVar = (ClAbstractVariable) colEnum.Current; } } if (exitVar != null) { Pivot(marker, exitVar); } } if (RowExpression(marker) != null) { RemoveRow(marker); } if (eVars != null) { foreach (ClAbstractVariable v in eVars) { // FIXME: decide wether to use equals or != if (v != marker) { RemoveColumn(v); // v = null; // is read-only, cannot be set to null } } } if (cn.IsStayConstraint) { if (eVars != null) { for (int i = 0; i < _stayPlusErrorVars.Count; i++) { eVars.Remove(_stayPlusErrorVars[i]); eVars.Remove(_stayMinusErrorVars[i]); } } } else if (cn.IsEditConstraint) { Assert(eVars != null, "eVars != null"); ClEditConstraint cnEdit = (ClEditConstraint) cn; ClVariable clv = cnEdit.Variable; ClEditInfo cei = (ClEditInfo) _editVarMap[clv]; ClSlackVariable clvEditMinus = cei.ClvEditMinus; RemoveColumn(clvEditMinus); _editVarMap.Remove(clv); } // FIXME: do the remove at top if (eVars != null) { _errorVars.Remove(eVars); } marker = null; if (_cOptimizeAutomatically) { Optimize(_objective); SetExternalVariables(); } return this; }
/// <summary> /// Same as AddConstraint, throws no exceptions. /// <returns> /// False if the constraint resulted in an unsolvable system, otherwise true. /// </returns> /// </summary> public bool AddConstraintNoException(ClConstraint cn) { if (Trace) FnEnterPrint("AddConstraintNoException: " + cn); try { AddConstraint(cn); return true; } catch (ExClRequiredFailure) { return false; } }
/// <summary> /// Protected convenience function to insert an error variable /// into the _errorVars set, creating the mapping with Add as necessary. /// </summary> protected void InsertErrorVar(ClConstraint cn, ClAbstractVariable var) { if (Trace) FnEnterPrint("InsertErrorVar: " + cn + ", " + var); Set cnset = (Set) _errorVars[cn]; if (cnset == null) _errorVars.Add(cn, cnset = new Set()); cnset.Add(var); }
protected ClLinearExpression NewExpression(ClConstraint cn, ArrayList eplus_eminus, ClDouble prevEConstant) { if (Trace) { FnEnterPrint("NewExpression: " + cn); TracePrint("cn.IsInequality == " + cn.IsInequality); TracePrint("cn.IsRequired == " + cn.IsRequired); } ClLinearExpression cnExpr = cn.Expression; ClLinearExpression expr = new ClLinearExpression(cnExpr.Constant); ClSlackVariable slackVar = new ClSlackVariable(); ClDummyVariable dummyVar = new ClDummyVariable(); ClSlackVariable eminus = new ClSlackVariable(); ClSlackVariable eplus = new ClSlackVariable(); Hashtable cnTerms = cnExpr.Terms; foreach(ClAbstractVariable v in cnTerms.Keys) { double c = ((ClDouble) cnTerms[v]).Value; ClLinearExpression e = RowExpression(v); if (e == null) expr.AddVariable(v, c); else expr.AddExpression(e, c); } if (cn.IsInequality) { ++_slackCounter; slackVar = new ClSlackVariable (_slackCounter, "s"); expr.SetVariable(slackVar, -1); _markerVars.Add(cn, slackVar); if (!cn.IsRequired) { ++_slackCounter; eminus = new ClSlackVariable(_slackCounter, "em"); expr.SetVariable(eminus, 1.0); ClLinearExpression zRow = RowExpression(_objective); ClSymbolicWeight sw = cn.Strength.SymbolicWeight.Times(cn.Weight); zRow.SetVariable(eminus, sw.AsDouble()); InsertErrorVar(cn, eminus); NoteAddedVariable(eminus, _objective); } } else { // cn is an equality if (cn.IsRequired) { ++_dummyCounter; dummyVar = new ClDummyVariable(_dummyCounter, "d"); expr.SetVariable(dummyVar, 1.0); _markerVars.Add(cn, dummyVar); if (Trace) TracePrint("Adding dummyVar == d" + _dummyCounter); } else { ++_slackCounter; eplus = new ClSlackVariable(_slackCounter, "ep"); eminus = new ClSlackVariable(_slackCounter, "em"); expr.SetVariable(eplus, -1.0); expr.SetVariable(eminus, 1.0); _markerVars.Add(cn, eplus); ClLinearExpression zRow = RowExpression(_objective); ClSymbolicWeight sw = cn.Strength.SymbolicWeight.Times(cn.Weight); double swCoeff = sw.AsDouble(); if (swCoeff == 0) { if (Trace) { TracePrint("sw == " + sw); TracePrint("cn == " + cn); TracePrint("adding " + eplus + " and " + eminus + " with swCoeff == " + swCoeff); } } zRow.SetVariable(eplus, swCoeff); NoteAddedVariable(eplus, _objective); zRow.SetVariable(eminus, swCoeff); NoteAddedVariable(eminus, _objective); InsertErrorVar(cn, eminus); InsertErrorVar(cn, eplus); if (cn.IsStayConstraint) { _stayPlusErrorVars.Add(eplus); _stayMinusErrorVars.Add(eminus); } else if (cn.IsEditConstraint) { eplus_eminus.Add(eplus); eplus_eminus.Add(eminus); prevEConstant.Value = cnExpr.Constant; } } } if (expr.Constant < 0) expr.MultiplyMe(-1); if (Trace) FnExitPrint("returning " + expr); return expr; }
/// <summary> /// Add a constraint to the solver. /// <param name="cn"> /// The constraint to be added. /// </param> /// </summary> public ClSimplexSolver AddConstraint(ClConstraint cn) /* throws ExClRequiredFailure, ExClInternalError */ { if (Trace) FnEnterPrint("AddConstraint: " + cn); ArrayList eplus_eminus = new ArrayList(2); ClDouble prevEConstant = new ClDouble(); ClLinearExpression expr = NewExpression(cn, /* output to: */ eplus_eminus, prevEConstant); bool cAddedOkDirectly = false; try { cAddedOkDirectly = TryAddingDirectly(expr); if (!cAddedOkDirectly) { // could not add directly AddWithArtificialVariable(expr); } } catch (ExClRequiredFailure rf) { throw rf; } _cNeedsSolving = true; if (cn.IsEditConstraint) { int i = _editVarMap.Count; ClEditConstraint cnEdit = (ClEditConstraint) cn; ClSlackVariable clvEplus = (ClSlackVariable) eplus_eminus[0]; ClSlackVariable clvEminus = (ClSlackVariable) eplus_eminus[1]; _editVarMap.Add(cnEdit.Variable, new ClEditInfo(cnEdit, clvEplus, clvEminus, prevEConstant.Value, i)); } if (_cOptimizeAutomatically) { Optimize(_objective); SetExternalVariables(); } return this; }
private ClLinearExpression NewExpression(ClConstraint cn, ICollection <ClAbstractVariable> eplusEminus, ClDouble prevEConstant) { ClLinearExpression cnExpr = cn.Expression; ClLinearExpression expr = new ClLinearExpression(cnExpr.Constant); ClSlackVariable eminus; var cnTerms = cnExpr.Terms; foreach (ClAbstractVariable v in cnTerms.Keys) { double c = (cnTerms[v]).Value; ClLinearExpression e = RowExpression(v); if (e == null) { expr.AddVariable(v, c); } else { expr.AddExpression(e, c); } } if (cn.IsInequality) { ++_slackCounter; ClSlackVariable slackVar = new ClSlackVariable(_slackCounter, "s"); expr.SetVariable(slackVar, -1); _markerVars.Add(cn, slackVar); if (!cn.Strength.IsRequired) { ++_slackCounter; eminus = new ClSlackVariable(_slackCounter, "em"); expr.SetVariable(eminus, 1.0); ClLinearExpression zRow = RowExpression(_objective); ClSymbolicWeight sw = cn.Strength.SymbolicWeight.Times(cn.Weight); zRow.SetVariable(eminus, sw.AsDouble()); InsertErrorVar(cn, eminus); NoteAddedVariable(eminus, _objective); } } else { // cn is an equality if (cn.Strength.IsRequired) { ++_dummyCounter; ClDummyVariable dummyVar = new ClDummyVariable(_dummyCounter, "d"); expr.SetVariable(dummyVar, 1.0); _markerVars.Add(cn, dummyVar); } else { ++_slackCounter; ClSlackVariable eplus = new ClSlackVariable(_slackCounter, "ep"); eminus = new ClSlackVariable(_slackCounter, "em"); expr.SetVariable(eplus, -1.0); expr.SetVariable(eminus, 1.0); _markerVars.Add(cn, eplus); ClLinearExpression zRow = RowExpression(_objective); ClSymbolicWeight sw = cn.Strength.SymbolicWeight.Times(cn.Weight); double swCoeff = sw.AsDouble(); zRow.SetVariable(eplus, swCoeff); NoteAddedVariable(eplus, _objective); zRow.SetVariable(eminus, swCoeff); NoteAddedVariable(eminus, _objective); InsertErrorVar(cn, eminus); InsertErrorVar(cn, eplus); if (cn.IsStayConstraint) { _stayPlusErrorVars.Add(eplus); _stayMinusErrorVars.Add(eminus); } else if (cn.IsEditConstraint) { eplusEminus.Add(eplus); eplusEminus.Add(eminus); prevEConstant.Value = cnExpr.Constant; } } } if (expr.Constant < 0) { expr.MultiplyMe(-1); } return(expr); }
/// <summary> /// Remove a constraint from the tableau. /// Also remove any error variable associated with it. /// </summary> public ClSimplexSolver RemoveConstraint(ClConstraint cn) /* throws ExClRequiredFailure, ExClInternalError */ { _cNeedsSolving = true; ResetStayConstants(); ClLinearExpression zRow = RowExpression(_objective); HashSet <ClAbstractVariable> eVars; if (_errorVars.TryGetValue(cn, out eVars)) { foreach (ClAbstractVariable clv in eVars) { ClLinearExpression expr = RowExpression(clv); if (expr == null) { zRow.AddVariable(clv, -cn.Weight * cn.Strength.SymbolicWeight.AsDouble(), _objective, this); } else // the error variable was in the basis { zRow.AddExpression(expr, -cn.Weight * cn.Strength.SymbolicWeight.AsDouble(), _objective, this); } } } ClAbstractVariable marker; if (!_markerVars.TryGetValue(cn, out marker)) { throw new CassowaryConstraintNotFoundException(); } _markerVars.Remove(cn); if (RowExpression(marker) == null) { // not in the basis, so need to do some more work var col = Columns[marker]; ClAbstractVariable exitVar = null; double minRatio = 0.0; foreach (ClAbstractVariable v in col) { if (v.IsRestricted) { ClLinearExpression expr = RowExpression(v); double coeff = expr.CoefficientFor(marker); if (coeff < 0.0) { double r = -expr.Constant / coeff; if (exitVar == null || r < minRatio) { minRatio = r; exitVar = v; } } } } if (exitVar == null) { foreach (ClAbstractVariable v in col) { if (v.IsRestricted) { ClLinearExpression expr = RowExpression(v); double coeff = expr.CoefficientFor(marker); double r = expr.Constant / coeff; if (exitVar == null || r < minRatio) { minRatio = r; exitVar = v; } } } } if (exitVar == null) { // exitVar is still null if (col.Count == 0) { RemoveColumn(marker); } else { // put first element in exitVar var colEnum = col.GetEnumerator(); colEnum.MoveNext(); exitVar = colEnum.Current; } } if (exitVar != null) { Pivot(marker, exitVar); } } if (RowExpression(marker) != null) { RemoveRow(marker); } if (eVars != null) { foreach (ClAbstractVariable v in eVars.Where(a => a != marker)) { RemoveColumn(v); } } if (cn.IsStayConstraint) { if (eVars != null) { for (int i = 0; i < _stayPlusErrorVars.Count; i++) { eVars.Remove(_stayPlusErrorVars[i]); eVars.Remove(_stayMinusErrorVars[i]); } } } else if (cn.IsEditConstraint) { Assert(eVars != null, "eVars != null"); ClEditConstraint cnEdit = (ClEditConstraint)cn; ClVariable clv = cnEdit.Variable; ClEditInfo cei = _editVarMap[clv]; ClSlackVariable clvEditMinus = cei.ClvEditMinus; RemoveColumn(clvEditMinus); _editVarMap.Remove(clv); } // FIXME: do the remove at top if (eVars != null) { //_errorVars.Remove(eVars); _errorVars.Remove(cn); } if (_cOptimizeAutomatically) { Optimize(_objective); SetExternalVariables(); } return(this); }
void Constraint() { ClLinearExpression e1, e2; bool eq = false, geq = false, leq = false; Expression(out e1); if (la.kind == 3) { Get(); eq = true; } else if (la.kind == 2) { Get(); geq = true; } else if (la.kind == 5) { Get(); geq = true; } else if (la.kind == 1) { Get(); leq = true; } else if (la.kind == 4) { Get(); leq = true; } else SynErr(15); Expression(out e2); if (eq) Value = new ClLinearEquation(e1, e2); else if (geq) Value = new ClLinearInequality(e1, Cl.GEQ, e2); else if (leq) Value = new ClLinearInequality(e1, Cl.LEQ, e2); }