Beispiel #1
0
        /// <summary>
        /// Remove the basic variable v from the tableau row v=expr
        /// Then update column cross indices.
        /// </summary>
        protected ClLinearExpression RemoveRow(ClAbstractVariable var)
        /*throws ExCLInternalError*/
        {
            var expr = _rows[var];

            if (expr == null)
            {
                throw new CassowaryInternalException("linear expression is null");
            }

            // For each variable in this expression, update
            // the column mapping and remove the variable from the list
            // of rows it is known to be in.
            foreach (var varset in expr.Terms.Keys.Select(clv => _columns[clv]).Where(varset => varset != null))
            {
                varset.Remove(var);
            }

            InfeasibleRows.Remove(var);

            if (var.IsExternal)
            {
                ExternalRows.Remove((ClVariable)var);
            }

            _rows.Remove(var);
            return(expr);
        }
        /// <summary>
        /// Re-solve the current collection of constraints, given the new
        /// values for the edit variables that have already been
        /// suggested (see <see cref="IEditContext.SuggestValue"/> method).
        /// </summary>
        IEditContext IEditContext.Resolve()
        {
            DualOptimize();
            SetExternalVariables();
            InfeasibleRows.Clear();
            ResetStayConstants();

            return(this);
        }
        /// <summary>
        /// Marks the start of an edit session.
        /// </summary>
        /// <remarks>
        /// BeginEdit should be called before sending Resolve()
        /// messages, after adding the appropriate edit variables.
        /// </remarks>
        public IEditContext BeginEdit(params ClVariable[] editVar)
        {
            foreach (ClVariable variable in editVar)
            {
                AddEditVar(variable, ClStrength.Strong);
            }

            Assert(_editVarMap.Count > 0, "_editVarMap.Count > 0");
            // may later want to do more in here
            InfeasibleRows.Clear();
            ResetStayConstants();
            _stkCedcns.Push(_editVarMap.Count);

            return(this);
        }
        /// <summary>
        /// Re-optimize using the dual simplex algorithm.
        /// </summary>
        /// <remarks>
        /// We have set new values for the constants in the edit constraints.
        /// </remarks>
        protected void DualOptimize()
        /* throws ExClInternalError */
        {
            ClLinearExpression zRow = RowExpression(_objective);

            while (InfeasibleRows.Count > 0)
            {
                ClAbstractVariable exitVar = InfeasibleRows.First();

                InfeasibleRows.Remove(exitVar);
                ClAbstractVariable entryVar = null;
                ClLinearExpression expr     = RowExpression(exitVar);
                if (expr != null)
                {
                    if (expr.Constant < 0.0)
                    {
                        double ratio = Double.MaxValue;
                        var    terms = expr.Terms;
                        foreach (ClAbstractVariable v in terms.Keys)
                        {
                            double c = (terms[v]).Value;
                            if (c > 0.0 && v.IsPivotable)
                            {
                                double zc = zRow.CoefficientFor(v);
                                double r  = zc / c;
                                if (r < ratio)
                                {
                                    entryVar = v;
                                    ratio    = r;
                                }
                            }
                        }
// ReSharper disable CompareOfFloatsByEqualityOperator
                        if (ratio == Double.MaxValue)
// ReSharper restore CompareOfFloatsByEqualityOperator
                        {
                            throw new CassowaryInternalException("ratio == nil (Double.MaxValue) in DualOptimize");
                        }
                        Pivot(entryVar, exitVar);
                    }
                }
            }
        }
        /// <summary>
        /// Fix the constants in the equations representing the edit constraints.
        /// </summary>
        /// <remarks>
        /// Each of the non-required edits will be represented by an equation
        /// of the form:
        ///   v = c + eplus - eminus
        /// where v is the variable with the edit, c is the previous edit value,
        /// and eplus and eminus are slack variables that hold the error in
        /// satisfying the edit constraint. We are about to change something,
        /// and we want to fix the constants in the equations representing
        /// the edit constraints. If one of eplus and eminus is basic, the other
        /// must occur only in the expression for that basic error variable.
        /// (They can't both be basic.) Fix the constant in this expression.
        /// Otherwise they are both non-basic. Find all of the expressions
        /// in which they occur, and fix the constants in those. See the
        /// UIST paper for details.
        /// (This comment was for ResetEditConstants(), but that is now
        /// gone since it was part of the screwey vector-based interface
        /// to resolveing. --02/16/99 gjb)
        /// </remarks>
        protected void DeltaEditConstant(double delta,
                                         ClAbstractVariable plusErrorVar,
                                         ClAbstractVariable minusErrorVar)
        {
            ClLinearExpression exprPlus = RowExpression(plusErrorVar);

            if (exprPlus != null)
            {
                exprPlus.IncrementConstant(delta);

                if (exprPlus.Constant < 0.0)
                {
                    InfeasibleRows.Add(plusErrorVar);
                }
                return;
            }

            ClLinearExpression exprMinus = RowExpression(minusErrorVar);

            if (exprMinus != null)
            {
                exprMinus.IncrementConstant(-delta);
                if (exprMinus.Constant < 0.0)
                {
                    InfeasibleRows.Add(minusErrorVar);
                }
                return;
            }

            var columnVars = Columns[minusErrorVar];

            foreach (ClAbstractVariable basicVar in columnVars)
            {
                ClLinearExpression expr = RowExpression(basicVar);
                //Assert(expr != null, "expr != null");
                double c = expr.CoefficientFor(minusErrorVar);
                expr.IncrementConstant(c * delta);
                if (basicVar.IsRestricted && expr.Constant < 0.0)
                {
                    InfeasibleRows.Add(basicVar);
                }
            }
        }
Beispiel #6
0
        /// <summary>
        /// Replace all occurrences of oldVar with expr, and update column cross indices
        /// oldVar should now be a basic variable.
        /// </summary>
        protected void SubstituteOut(ClAbstractVariable oldVar, ClLinearExpression expr)
        {
            var varset = _columns[oldVar];

            foreach (var v in varset)
            {
                var row = _rows[v];
                row.SubstituteOut(oldVar, expr, v, this);
                if (v.IsRestricted && row.Constant < 0.0)
                {
                    InfeasibleRows.Add(v);
                }
            }

            if (oldVar.IsExternal)
            {
                ExternalRows.Add((ClVariable)oldVar);
                ExternalParametricVars.Remove((ClVariable)oldVar);
            }

            _columns.Remove(oldVar);
        }