/// <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> /// Suggest a new value for an edit variable. /// </summary> /// <remarks> /// The variable needs to be added as an edit variable and /// BeginEdit() needs to be called before this is called. /// The tableau will not be solved completely until after Resolve() /// has been called. /// </remarks> IEditContext IEditContext.SuggestValue(ClVariable v, double x) { ClEditInfo cei = _editVarMap[v]; if (cei == null) { throw new CassowaryException("SuggestValue for variable " + v + ", but var is not an edit variable\n"); } ClSlackVariable clvEditPlus = cei.ClvEditPlus; ClSlackVariable clvEditMinus = cei.ClvEditMinus; double delta = x - cei.PrevEditConstant; cei.PrevEditConstant = x; DeltaEditConstant(delta, clvEditPlus, clvEditMinus); 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 */ { _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); }