コード例 #1
0
 public ClLinearEquation(ClAbstractVariable clv, 
                         double val, 
                         ClStrength strength, 
                         double weight) : base(new ClLinearExpression(val), strength, weight)
 {
   _expression.AddVariable(clv, -1.0);
 }
コード例 #2
0
        /// <summary>
        /// Add a term c*v to this expression.  If the expression already
        /// contains a term involving v, add c to the existing coefficient.
        /// If the new coefficient is approximately 0, delete v.
        /// </summary>
        public /*sealed*/ ClLinearExpression AddVariable(ClAbstractVariable v, double c)
        {
            // body largely duplicated below
            if (Trace)
            {
                FnEnterPrint(string.Format("AddVariable: {0}, {1}", v, c));
            }

            ClDouble coeff = (ClDouble)_terms[v];

            if (coeff != null)
            {
                double new_coefficient = coeff.Value + c;

                if (Cl.Approx(new_coefficient, 0.0))
                {
                    _terms.Remove(v);
                }
                else
                {
                    coeff.Value = new_coefficient;
                }
            }
            else
            {
                if (!Cl.Approx(c, 0.0))
                {
                    _terms.Add(v, new ClDouble(c));
                }
            }

            return(this);
        }
コード例 #3
0
 public ClLinearEquation(ClLinearExpression cle,
                         ClAbstractVariable clv,
                         ClStrength strength,
                         double weight) : base((ClLinearExpression) cle.Clone(), strength, weight)
 {
   _expression.AddVariable(clv, -1.0);
 }
コード例 #4
0
 /// <summary>
 /// Variable v has been removed from an expression. If the
 /// expression is in a tableau the corresponding basic variable is
 /// subject (or if subject is nil then it's in the objective function).
 /// Update the column cross-indices.
 /// </summary>
 public void NoteRemovedVariable(ClAbstractVariable v, ClAbstractVariable subject)
 {
     if (subject != null)
     {
         _columns[v].Remove(subject);
     }
 }
コード例 #5
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);
        }
コード例 #6
0
 public ClLinearInequality(ClLinearExpression cle,
                           byte op_enum,
                           ClAbstractVariable clv,
                           ClStrength strength) : this(cle, op_enum, clv, strength, 1.0)
     /* throws ExClInternalError */
 {
 }
コード例 #7
0
 /// <summary>
 /// v has been added to the linear expression for subject
 /// update column cross indices.
 /// </summary>
 public void NoteAddedVariable(ClAbstractVariable v, ClAbstractVariable subject)
 {
     if (subject != null)
     {
         InsertColVar(v, subject);
     }
 }
コード例 #8
0
 public ClLinearEquation(ClLinearExpression cle,
                         ClAbstractVariable clv,
                         ClStrength strength,
                         double weight) : base((ClLinearExpression)cle.Clone(), strength, weight)
 {
     _expression.AddVariable(clv, -1.0);
 }
コード例 #9
0
        /// <summary>
        /// Add a term c*v to this expression.  If the expression already
        /// contains a term involving v, add c to the existing coefficient.
        /// If the new coefficient is approximately 0, delete v.
        /// </summary>
        public ClLinearExpression AddVariable(ClAbstractVariable v, double c = 1.0)
        {
            ClDouble coeff;

            if (_terms.TryGetValue(v, out coeff))
            {
                double newCoefficient = coeff.Value + c;

                if (Approx(newCoefficient, 0.0))
                {
                    _terms.Remove(v);
                }
                else
                {
                    coeff.Value = newCoefficient;
                }
            }
            else
            {
                if (!Approx(c, 0.0))
                {
                    _terms.Add(v, new ClDouble(c));
                }
            }

            return(this);
        }
コード例 #10
0
        /// <summary>
        /// Add a term c*v to this expression.  If the expression already
        /// contains a term involving v, add c to the existing coefficient.
        /// If the new coefficient is approximately 0, delete v.  Notify the
        /// solver if v appears or disappears from this expression.
        /// </summary>
        public ClLinearExpression AddVariable(ClAbstractVariable v, double c, ClAbstractVariable subject, ClTableau solver)
        {
            ClDouble coeff = _terms[v];

            if (coeff != null)
            {
                double newCoefficient = coeff.Value + c;

                if (Approx(newCoefficient, 0.0))
                {
                    solver.NoteRemovedVariable(v, subject);
                    _terms.Remove(v);
                }
                else
                {
                    coeff.Value = newCoefficient;
                }
            }
            else
            {
                if (!Approx(c, 0.0))
                {
                    _terms.Add(v, new ClDouble(c));
                    solver.NoteAddedVariable(v, subject);
                }
            }

            return(this);
        }
コード例 #11
0
 public ClLinearEquation(ClAbstractVariable clv,
                         double val,
                         ClStrength strength,
                         double weight) : base(new ClLinearExpression(val), strength, weight)
 {
     _expression.AddVariable(clv, -1.0);
 }
コード例 #12
0
        /// <summary>
        /// Replace var with a symbolic expression expr that is equal to it.
        /// If a variable has been added to this expression that wasn't there
        /// before, or if a variable has been dropped from this expression
        /// because it now has a coefficient of 0, inform the solver.
        /// PRECONDITIONS:
        ///   var occurs with a non-zero coefficient in this expression.
        /// </summary>
        public void SubstituteOut(ClAbstractVariable var, ClLinearExpression expr, ClAbstractVariable subject, ClTableau solver)
        {
            double multiplier = (_terms[var]).Value;

            _terms.Remove(var);
            IncrementConstant(multiplier * expr.Constant);

            foreach (ClAbstractVariable clv in expr.Terms.Keys)
            {
                double   coeff = (expr.Terms[clv]).Value;
                ClDouble dOldCoeff;

                if (_terms.TryGetValue(clv, out dOldCoeff))
                {
                    double oldCoeff = dOldCoeff.Value;
                    double newCoeff = oldCoeff + multiplier * coeff;

                    if (Approx(newCoeff, 0.0))
                    {
                        solver.NoteRemovedVariable(clv, subject);
                        _terms.Remove(clv);
                    }
                    else
                    {
                        dOldCoeff.Value = newCoeff;
                    }
                }
                else
                {
                    // did not have that variable already
                    _terms.Add(clv, new ClDouble(multiplier * coeff));
                    solver.NoteAddedVariable(clv, subject);
                }
            }
        }
コード例 #13
0
        /// <summary>
        /// Replace all occurrences of oldVar with expr, and update column cross indices
        /// oldVar should now be a basic variable.
        /// </summary>
        protected /*sealed*/ void SubstituteOut(ClAbstractVariable oldVar, ClLinearExpression expr)
        {
            if (Trace)
            {
                FnEnterPrint(string.Format("SubstituteOut: {0}", oldVar, expr));
            }
            if (Trace)
            {
                TracePrint(this.ToString());
            }

            Set varset = (Set)_columns[oldVar];

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

            if (oldVar.IsExternal)
            {
                _externalRows.Add(oldVar);
                _externalParametricVars.Remove(oldVar);
            }

            _columns.Remove(oldVar);
        }
コード例 #14
0
        /// <summary>
        /// Remove v from the tableau -- remove the column cross indices for v
        /// and remove v from every expression in rows in which v occurs
        /// </summary>
        protected /*sealed*/ void RemoveColumn(ClAbstractVariable var)
        {
            if (Trace)
            {
                FnEnterPrint(string.Format("RemoveColumn: {0}", var));
            }
            // remove the rows with the variables in varset

            Set rows = (Set)_columns[var];

            _columns.Remove(var);

            if (rows != null)
            {
                foreach (ClAbstractVariable clv in rows)
                {
                    ClLinearExpression expr = (ClLinearExpression)_rows[clv];
                    expr.Terms.Remove(var);
                }
            }
            else
            {
                if (Trace)
                {
                    DebugPrint(string.Format("Could not find var {0} in _columns", var));
                }
            }

            if (var.IsExternal)
            {
                _externalRows.Remove(var);
                _externalParametricVars.Remove(var);
            }
        }
コード例 #15
0
        // Add v=expr to the tableau, update column cross indices
        // v becomes a basic variable
        // expr is now owned by ClTableau class,
        // and ClTableau is responsible for deleting it
        // (also, expr better be allocated on the heap!).
        protected /*sealed*/ void AddRow(ClAbstractVariable var, ClLinearExpression expr)
        {
            if (Trace)
            {
                FnEnterPrint("AddRow: " + var + ", " + expr);
            }

            // for each variable in expr, add var to the set of rows which
            // have that variable in their expression
            _rows.Add(var, expr);

            // FIXME: check correctness!
            foreach (ClAbstractVariable clv in expr.Terms.Keys)
            {
                InsertColVar(clv, var);

                if (clv.IsExternal)
                {
                    _externalParametricVars.Add(clv);
                }
            }

            if (var.IsExternal)
            {
                _externalRows.Add(var);
            }

            if (Trace)
            {
                TracePrint(this.ToString());
            }
        }
コード例 #16
0
        public override string ToString()
        {
            String s = "";

            IDictionaryEnumerator e = _terms.GetEnumerator();

            if (!Approx(_constant.Value, 0.0) || _terms.Count == 0)
            {
                s += _constant.ToString();
            }
            else
            {
                if (_terms.Count == 0)
                {
                    return(s);
                }
                e.MoveNext(); // go to first element
                ClAbstractVariable clv   = (ClAbstractVariable)e.Key;
                ClDouble           coeff = _terms[clv];
                s += string.Format("{0}*{1}", coeff, clv);
            }
            while (e.MoveNext())
            {
                ClAbstractVariable clv   = (ClAbstractVariable)e.Key;
                ClDouble           coeff = _terms[clv];
                s += string.Format(" + {0}*{1}", coeff, clv);
            }

            return(s);
        }
コード例 #17
0
ファイル: ClTableau.cs プロジェクト: hur1can3/Cassowary.net
 /// <summary>
 /// v has been added to the linear expression for subject
 /// update column cross indices.
 /// </summary>
 public /*sealed*/ void NoteAddedVariable(ClAbstractVariable v, ClAbstractVariable subject)
 { 
   if (Trace) 
     FnEnterPrint(string.Format("NoteAddedVariable: {0}, {1}", v, subject));
   if (subject != null) {
     InsertColVar(v, subject);
   }
 }
コード例 #18
0
        protected ClLinearExpression RowExpression(ClAbstractVariable v)
        {
            // if (Trace) FnEnterPrint(string.Format("rowExpression: {0}", v));
            ClLinearExpression exp;

            _rows.TryGetValue(v, out exp);
            return(exp);
        }
コード例 #19
0
ファイル: ClTableau.cs プロジェクト: hur1can3/Cassowary.net
    /// <summary>
    /// Variable v has been removed from an expression. If the
    /// expression is in a tableau the corresponding basic variable is
    /// subject (or if subject is nil then it's in the objective function).
    /// Update the column cross-indices.
    /// </summary>
    public /*sealed*/ void NoteRemovedVariable(ClAbstractVariable v, ClAbstractVariable subject)
    { 
      if (Trace) 
        FnEnterPrint(string.Format("NoteRemovedVariable: {0}, {1}", v, subject));

      if (subject != null) {
        ((Set) _columns[v]).Remove(subject);
      }
    }
コード例 #20
0
        /// <summary>
        /// Minimize the value of the objective.
        /// </summary>
        /// <remarks>
        /// The tableau should already be feasible.
        /// </remarks>
        private void Optimize(ClObjectiveVariable zVar)
        /* throws ExClInternalError */
        {
            ClLinearExpression zRow = RowExpression(zVar);

            if (zRow == null)
            {
                throw new CassowaryInternalException("Assertion failed: zRow != null");
            }

            ClAbstractVariable entryVar = null;
            ClAbstractVariable exitVar  = null;

            while (true)
            {
                double objectiveCoeff = 0;
                foreach (var kvp in zRow.Terms)
                {
                    if (kvp.Key.IsPivotable && kvp.Value.Value < objectiveCoeff)
                    {
                        objectiveCoeff = kvp.Value.Value;
                        entryVar       = kvp.Key;
                    }
                }

                if (objectiveCoeff >= -EPSILON || entryVar == null)
                {
                    return;
                }

                double minRatio = Double.MaxValue;
                foreach (ClAbstractVariable v in Columns[entryVar])
                {
                    if (v.IsPivotable)
                    {
                        ClLinearExpression expr  = RowExpression(v);
                        double             coeff = expr.CoefficientFor(entryVar);
                        if (coeff < 0.0)
                        {
                            double r = -expr.Constant / coeff;
                            if (r < minRatio)
                            {
                                minRatio = r;
                                exitVar  = v;
                            }
                        }
                    }
                }
// ReSharper disable CompareOfFloatsByEqualityOperator
                if (minRatio == Double.MaxValue)
// ReSharper restore CompareOfFloatsByEqualityOperator
                {
                    throw new CassowaryInternalException("Objective function is unbounded in Optimize");
                }
                Pivot(entryVar, exitVar);
            }
        }
コード例 #21
0
        /// <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);
        }
コード例 #22
0
        public ClLinearExpression(ClAbstractVariable clv, double value = 1, double constant = 0)
        {
            _constant = new ClDouble(constant);
            _terms    = new Dictionary <ClAbstractVariable, ClDouble>();

            if (clv != null)
            {
                _terms.Add(clv, new ClDouble(value));
            }
        }
コード例 #23
0
 /// <summary>
 /// v has been added to the linear expression for subject
 /// update column cross indices.
 /// </summary>
 public /*sealed*/ void NoteAddedVariable(ClAbstractVariable v, ClAbstractVariable subject)
 {
     if (Trace)
     {
         FnEnterPrint(string.Format("NoteAddedVariable: {0}, {1}", v, subject));
     }
     if (subject != null)
     {
         InsertColVar(v, subject);
     }
 }
コード例 #24
0
        /// <summary>
        /// Convenience function to insert a variable into
        /// the set of rows stored at _columns[param_var],
        /// creating a new set if needed.
        /// </summary>
        private void InsertColVar(ClAbstractVariable paramVar, ClAbstractVariable rowvar)
        {
            HashSet <ClAbstractVariable> rowset;

            if (!_columns.TryGetValue(paramVar, out rowset))
            {
                _columns.Add(paramVar, rowset = new HashSet <ClAbstractVariable>());
            }

            rowset.Add(rowvar);
        }
コード例 #25
0
        /// <summary>
        /// This linear expression currently represents the equation self=0.  Destructively modify it so
        /// that subject=self represents an equivalent equation.
        ///
        /// Precondition: subject must be one of the variables in this expression.
        /// NOTES
        ///   Suppose this expression is
        ///     c + a*subject + a1*v1 + ... + an*vn
        ///   representing
        ///     c + a*subject + a1*v1 + ... + an*vn = 0
        /// The modified expression will be
        ///    subject = -c/a - (a1/a)*v1 - ... - (an/a)*vn
        ///   representing
        ///    subject = -c/a - (a1/a)*v1 - ... - (an/a)*vn
        ///
        /// Note that the term involving subject has been dropped.
        /// Returns the reciprocal, so changeSubject can use it, too
        /// </summary>
        public double NewSubject(ClAbstractVariable subject)
        {
            ClDouble coeff = _terms[subject];

            _terms.Remove(subject);

            double reciprocal = 1.0 / coeff.Value;

            MultiplyMe(-reciprocal);

            return(reciprocal);
        }
コード例 #26
0
        /// <summary>
        /// Variable v has been removed from an expression. If the
        /// expression is in a tableau the corresponding basic variable is
        /// subject (or if subject is nil then it's in the objective function).
        /// Update the column cross-indices.
        /// </summary>
        public /*sealed*/ void NoteRemovedVariable(ClAbstractVariable v, ClAbstractVariable subject)
        {
            if (Trace)
            {
                FnEnterPrint(string.Format("NoteRemovedVariable: {0}, {1}", v, subject));
            }

            if (subject != null)
            {
                ((Set)_columns[v]).Remove(subject);
            }
        }
コード例 #27
0
        /// <summary>
        /// Convenience function to insert a variable into
        /// the set of rows stored at _columns[param_var],
        /// creating a new set if needed.
        /// </summary>
        private /*sealed*/ void InsertColVar(ClAbstractVariable param_var,
                                             ClAbstractVariable rowvar)
        {
            Set rowset = (Set)_columns[param_var];

            if (rowset == null)
            {
                _columns.Add(param_var, rowset = new Set());
            }

            rowset.Add(rowvar);
        }
コード例 #28
0
        /// <summary>
        /// Add n*expr to this expression from another expression expr.
        /// Notify the solver if a variable is added or deleted from this
        /// expression.
        /// </summary>
        public ClLinearExpression AddExpression(ClLinearExpression expr, double n, ClAbstractVariable subject, ClTableau solver)
        {
            IncrementConstant(n * expr.Constant);

            foreach (ClAbstractVariable clv in expr.Terms.Keys)
            {
                double coeff = (expr.Terms[clv]).Value;
                AddVariable(clv, coeff * n, subject, solver);
            }

            return(this);
        }
コード例 #29
0
        /// <summary>
        /// This linear expression currently represents the equation
        /// oldSubject=self.  Destructively modify it so that it represents
        /// the equation newSubject=self.
        ///
        /// Precondition: newSubject currently has a nonzero coefficient in
        /// this expression.
        ///
        /// NOTES
        ///   Suppose this expression is c + a*newSubject + a1*v1 + ... + an*vn.
        ///
        ///   Then the current equation is
        ///       oldSubject = c + a*newSubject + a1*v1 + ... + an*vn.
        ///   The new equation will be
        ///        newSubject = -c/a + oldSubject/a - (a1/a)*v1 - ... - (an/a)*vn.
        ///   Note that the term involving newSubject has been dropped.
        /// </summary>
        public /*sealed*/ void ChangeSubject(ClAbstractVariable old_subject, ClAbstractVariable new_subject)
        {
            ClDouble cld = (ClDouble)_terms[old_subject];

            if (cld != null)
            {
                cld.Value = NewSubject(new_subject);
            }
            else
            {
                _terms.Add(old_subject, new ClDouble(NewSubject(new_subject)));
            }
        }
コード例 #30
0
        /// <summary>
        /// Do a pivot. Move entryVar into the basis and move exitVar
        /// out of the basis.
        /// </summary>
        /// <remarks>
        /// We could for example make entryVar a basic variable and
        /// make exitVar a parametric variable.
        /// </remarks>
        protected void Pivot(ClAbstractVariable entryVar, ClAbstractVariable exitVar)
        /* throws ExClInternalError */
        {
            // the entryVar might be non-pivotable if we're doing a
            // RemoveConstraint -- otherwise it should be a pivotable
            // variable -- enforced at call sites, hopefully

            ClLinearExpression pexpr = RemoveRow(exitVar);

            pexpr.ChangeSubject(exitVar, entryVar);
            SubstituteOut(entryVar, pexpr);
            AddRow(entryVar, pexpr);
        }
コード例 #31
0
        /// <summary>
        /// Return the coefficient corresponding to variable var, i.e.,
        /// the 'ci' corresponding to the 'vi' that var is:
        ///      v1*c1 + v2*c2 + .. + vn*cn + c
        /// </summary>
        public double CoefficientFor(ClAbstractVariable var)
        {
            ClDouble coeff;

            if (_terms.TryGetValue(var, out coeff) && coeff != null)
            {
                return(coeff.Value);
            }
            else
            {
                return(0.0);
            }
        }
コード例 #32
0
    public ClLinearExpression(ClAbstractVariable clv, double value, double constant)
    {
      if (Cl.GC)
      {
        Console.Error.WriteLine("new ClLinearExpression");
      }

      _constant = new ClDouble(constant);
      _terms = new Hashtable(1);
      
      if (clv != null)
        _terms.Add(clv, new ClDouble(value));
    }
コード例 #33
0
        /// <summary>
        /// Return the coefficient corresponding to variable var, i.e.,
        /// the 'ci' corresponding to the 'vi' that var is:
        ///      v1*c1 + v2*c2 + .. + vn*cn + c
        /// </summary>
        public double CoefficientFor(ClAbstractVariable var)
        {
            ClDouble coeff = _terms[var];

            if (coeff != null)
            {
                return(coeff.Value);
            }
            else
            {
                return(0.0);
            }
        }
コード例 #34
0
        /// <summary>
        /// This linear expression currently represents the equation
        /// oldSubject=self.  Destructively modify it so that it represents
        /// the equation newSubject=self.
        ///
        /// Precondition: newSubject currently has a nonzero coefficient in
        /// this expression.
        ///
        /// NOTES
        ///   Suppose this expression is c + a*newSubject + a1*v1 + ... + an*vn.
        ///
        ///   Then the current equation is
        ///       oldSubject = c + a*newSubject + a1*v1 + ... + an*vn.
        ///   The new equation will be
        ///        newSubject = -c/a + oldSubject/a - (a1/a)*v1 - ... - (an/a)*vn.
        ///   Note that the term involving newSubject has been dropped.
        /// </summary>
        public void ChangeSubject(ClAbstractVariable oldSubject, ClAbstractVariable newSubject)
        {
            ClDouble cld;

            if (_terms.TryGetValue(oldSubject, out cld))
            {
                cld.Value = NewSubject(newSubject);
            }
            else
            {
                _terms.Add(oldSubject, new ClDouble(NewSubject(newSubject)));
            }
        }
コード例 #35
0
        /// <summary>
        /// Replace var with a symbolic expression expr that is equal to it.
        /// If a variable has been added to this expression that wasn't there
        /// before, or if a variable has been dropped from this expression
        /// because it now has a coefficient of 0, inform the solver.
        /// PRECONDITIONS:
        ///   var occurs with a non-zero coefficient in this expression.
        /// </summary>
        public /*sealed*/ void SubstituteOut(ClAbstractVariable var, ClLinearExpression expr,
                                             ClAbstractVariable subject, ClTableau solver)
        {
            if (Trace)
            {
                FnEnterPrint(string.Format("CLE:SubstituteOut: {0}, {1}, {2}, ...", var, expr, subject));
            }
            if (Trace)
            {
                TracePrint("this = " + this);
            }

            double multiplier = ((ClDouble)_terms[var]).Value;

            _terms.Remove(var);
            IncrementConstant(multiplier * expr.Constant);

            foreach (ClAbstractVariable clv in expr.Terms.Keys)
            {
                double   coeff       = ((ClDouble)expr.Terms[clv]).Value;
                ClDouble d_old_coeff = (ClDouble)_terms[clv];

                if (d_old_coeff != null)
                {
                    double old_coeff = d_old_coeff.Value;
                    double newCoeff  = old_coeff + multiplier * coeff;

                    if (Cl.Approx(newCoeff, 0.0))
                    {
                        solver.NoteRemovedVariable(clv, subject);
                        _terms.Remove(clv);
                    }
                    else
                    {
                        d_old_coeff.Value = newCoeff;
                    }
                }
                else
                {
                    // did not have that variable already
                    _terms.Add(clv, new ClDouble(multiplier * coeff));
                    solver.NoteAddedVariable(clv, subject);
                }
            }

            if (Trace)
            {
                TracePrint("Now this is " + this);
            }
        }
コード例 #36
0
 /// <summary>
 /// Convenience function for creating a linear inequality constraint.
 /// </summary>
 public ClSimplexSolver AddUpperBound(ClAbstractVariable v, double upper)
   /* throws ExClRequiredFailure, ExClInternalError */
 {
   ClLinearInequality cn = new ClLinearInequality(v, Cl.LEQ, new ClLinearExpression(upper));
   return AddConstraint(cn);
 }
コード例 #37
0
 /// <summary>
 /// Convenience function for creating a pair of linear inequality constraints.
 /// </summary>
 public ClSimplexSolver AddBounds(ClAbstractVariable v, double lower, double upper)
   /* throws ExClRequiredFailure, ExClInternalError */
 {
   AddLowerBound(v, lower);
   AddUpperBound(v, upper);
   return this;
 }
コード例 #38
0
ファイル: ClTableau.cs プロジェクト: hur1can3/Cassowary.net
 /// <summary>
 /// Convenience function to insert a variable into
 /// the set of rows stored at _columns[param_var],
 /// creating a new set if needed. 
 /// </summary>
 private /*sealed*/ void InsertColVar(ClAbstractVariable param_var, 
                 ClAbstractVariable rowvar)
 { 
   Set rowset = (Set) _columns[param_var];
   
   if (rowset == null)
     _columns.Add(param_var, rowset = new Set());
   
   rowset.Add(rowvar);
 }
コード例 #39
0
 public ClLinearEquation(ClLinearExpression cle, ClAbstractVariable clv) : this(cle, clv, ClStrength.Required, 1.0)
 {}
コード例 #40
0
ファイル: ClTableau.cs プロジェクト: hur1can3/Cassowary.net
 /// <summary> 
 /// Replace all occurrences of oldVar with expr, and update column cross indices
 /// oldVar should now be a basic variable.
 /// </summary> 
 protected /*sealed*/ void SubstituteOut(ClAbstractVariable oldVar, ClLinearExpression expr)
 {
   if (Trace)
     FnEnterPrint(string.Format("SubstituteOut: {0}", oldVar, expr));
   if (Trace) 
     TracePrint(this.ToString());
       
   Set varset = (Set) _columns[oldVar];
   
   foreach(ClAbstractVariable v in varset)
   {
     ClLinearExpression row = (ClLinearExpression) _rows[v];
     row.SubstituteOut(oldVar, expr, v, this);
     if (v.IsRestricted && row.Constant < 0.0) 
     {
       _infeasibleRows.Add(v);
     }
   }
   
   if (oldVar.IsExternal) {
     _externalRows.Add(oldVar);
     _externalParametricVars.Remove(oldVar);
   }
 
   _columns.Remove(oldVar);
 }
コード例 #41
0
ファイル: ClTableau.cs プロジェクト: hur1can3/Cassowary.net
    /// <summary>
    /// Remove v from the tableau -- remove the column cross indices for v
    /// and remove v from every expression in rows in which v occurs
    /// </summary>
    protected /*sealed*/ void RemoveColumn(ClAbstractVariable var)
    {
      if (Trace) 
        FnEnterPrint(string.Format("RemoveColumn: {0}", var));
      // remove the rows with the variables in varset

      Set rows = (Set) _columns[var];
      _columns.Remove(var);

      if (rows != null) {
        foreach(ClAbstractVariable clv in rows)
        {
          ClLinearExpression expr = (ClLinearExpression) _rows[clv];
          expr.Terms.Remove(var);
        }
      } else {
        if (Trace) 
          DebugPrint(string.Format("Could not find var {0} in _columns", var));
      }
          
      if (var.IsExternal) {
        _externalRows.Remove(var);
        _externalParametricVars.Remove(var);
      }
    }
コード例 #42
0
 /// <summary>
 /// This linear expression currently represents the equation
 /// oldSubject=self.  Destructively modify it so that it represents
 /// the equation newSubject=self.
 ///
 /// Precondition: newSubject currently has a nonzero coefficient in
 /// this expression.
 ///
 /// NOTES
 ///   Suppose this expression is c + a*newSubject + a1*v1 + ... + an*vn.
 ///
 ///   Then the current equation is 
 ///       oldSubject = c + a*newSubject + a1*v1 + ... + an*vn.
 ///   The new equation will be
 ///        newSubject = -c/a + oldSubject/a - (a1/a)*v1 - ... - (an/a)*vn.
 ///   Note that the term involving newSubject has been dropped.
 /// </summary>
 public /*sealed*/ void ChangeSubject(ClAbstractVariable old_subject, ClAbstractVariable new_subject)
 {
   ClDouble cld = (ClDouble) _terms[old_subject];
   
   if (cld != null)
     cld.Value  = NewSubject(new_subject);
   else
     _terms.Add(old_subject, new ClDouble(NewSubject(new_subject)));
 }
コード例 #43
0
    /// <summary>
    /// Add a term c*v to this expression.  If the expression already
    /// contains a term involving v, add c to the existing coefficient.
    /// If the new coefficient is approximately 0, delete v.  Notify the
    /// solver if v appears or disappears from this expression.
    /// </summary>
    public /*sealed*/ ClLinearExpression AddVariable(ClAbstractVariable v, double c,
      ClAbstractVariable subject, ClTableau solver)
    { 
      // body largely duplicated above
      if (Trace) 
        FnEnterPrint(string.Format("AddVariable: {0}, {1}, {2}, ...", v, c, subject));

      ClDouble coeff = (ClDouble) _terms[v];
      
      if (coeff != null) 
      {
        double new_coefficient = coeff.Value + c;
        
        if (Cl.Approx(new_coefficient, 0.0)) 
        {
          solver.NoteRemovedVariable(v, subject);
          _terms.Remove(v);
        } 
        else 
        { 
          coeff.Value = new_coefficient;
        }
      } 
      else 
      {
        if (!Cl.Approx(c, 0.0)) 
        {
          _terms.Add(v, new ClDouble(c));
          solver.NoteAddedVariable(v, subject);
        }
      }

      return this;
    }
コード例 #44
0
 /// <summary>
 /// This linear expression currently represents the equation self=0.  Destructively modify it so 
 /// that subject=self represents an equivalent equation.  
 ///
 /// Precondition: subject must be one of the variables in this expression.
 /// NOTES
 ///   Suppose this expression is
 ///     c + a*subject + a1*v1 + ... + an*vn
 ///   representing 
 ///     c + a*subject + a1*v1 + ... + an*vn = 0
 /// The modified expression will be
 ///    subject = -c/a - (a1/a)*v1 - ... - (an/a)*vn
 ///   representing
 ///    subject = -c/a - (a1/a)*v1 - ... - (an/a)*vn
 ///
 /// Note that the term involving subject has been dropped.
 /// Returns the reciprocal, so changeSubject can use it, too
 /// </summary>
 public /*sealed*/ double NewSubject(ClAbstractVariable subject)
 {
   if (Trace) 
     FnEnterPrint(string.Format("newSubject: {0}", subject));
   
   ClDouble coeff = (ClDouble) _terms[subject];
   _terms.Remove(subject);
   
   double reciprocal = 1.0 / coeff.Value;
   MultiplyMe(-reciprocal);
   
   return reciprocal;
 }
コード例 #45
0
 public ClLinearEquation(ClAbstractVariable clv,
                         double val,
                         ClStrength strength) : this(clv, val, strength, 1.0)
 {}
コード例 #46
0
 public ClLinearEquation(ClAbstractVariable clv,
                         double val) : this(clv, val, ClStrength.Required, 1.0)
 {}
コード例 #47
0
 public ClLinearExpression(ClAbstractVariable clv, double value) : this(clv, value, 0.0)
 {}
コード例 #48
0
 /// <summary>
 /// Return the coefficient corresponding to variable var, i.e.,
 /// the 'ci' corresponding to the 'vi' that var is:
 ///      v1*c1 + v2*c2 + .. + vn*cn + c
 /// </summary>
 public /*sealed*/ double CoefficientFor(ClAbstractVariable var)
 { 
   ClDouble coeff = (ClDouble) _terms[var];
   
   if (coeff != null)
     return coeff.Value;
   else
     return 0.0;
 }
コード例 #49
0
 public ClLinearInequality(ClLinearExpression cle,
                           byte op_enum,
                           ClAbstractVariable clv,
                           ClStrength strength,
                           double weight) : base((ClLinearExpression) cle.Clone(), strength, weight)
                           /* throws ExClInternalError */
 {
   switch (op_enum)
   {
     case Cl.LEQ:
       _expression.MultiplyMe(-1.0);
       _expression.AddVariable(clv);
       break;
     case Cl.GEQ:
       _expression.AddVariable(clv, -1.0);
       break;
     default:
       // invalid operator
       throw new ExClInternalError("Invalid operator in ClLinearInequality constructor");
   }
 }
コード例 #50
0
    /// <summary>
    /// Replace var with a symbolic expression expr that is equal to it.
    /// If a variable has been added to this expression that wasn't there
    /// before, or if a variable has been dropped from this expression
    /// because it now has a coefficient of 0, inform the solver.
    /// PRECONDITIONS:
    ///   var occurs with a non-zero coefficient in this expression.
    /// </summary>
    public /*sealed*/ void SubstituteOut(ClAbstractVariable var, ClLinearExpression expr, 
      ClAbstractVariable subject, ClTableau solver)
    {
      if (Trace) 
        FnEnterPrint(string.Format("CLE:SubstituteOut: {0}, {1}, {2}, ...", var, expr, subject));
      if (Trace) 
        TracePrint("this = " + this);

      double multiplier = ((ClDouble) _terms[var]).Value;
       _terms.Remove(var);
      IncrementConstant(multiplier * expr.Constant);
        
      foreach (ClAbstractVariable clv in expr.Terms.Keys)
      {
        double coeff = ((ClDouble) expr.Terms[clv]).Value;
        ClDouble d_old_coeff = (ClDouble) _terms[clv];
        
        if (d_old_coeff != null) 
        {
          double old_coeff = d_old_coeff.Value;
          double newCoeff = old_coeff + multiplier * coeff;
          
          if (Cl.Approx(newCoeff, 0.0)) 
          {
            solver.NoteRemovedVariable(clv, subject);
            _terms.Remove(clv);
          } 
          else 
          {
            d_old_coeff.Value = newCoeff;
          }
        } 
        else 
        {
          // did not have that variable already
          _terms.Add(clv, new ClDouble(multiplier * coeff));
          solver.NoteAddedVariable(clv, subject);
        }
      }

      if (Trace) 
        TracePrint("Now this is " + this);
    }
コード例 #51
0
ファイル: ClTableau.cs プロジェクト: hur1can3/Cassowary.net
 protected /*sealed*/ ClLinearExpression RowExpression(ClAbstractVariable v)
 {
   // if (Trace) FnEnterPrint(string.Format("rowExpression: {0}", v));
   return (ClLinearExpression) _rows[v];
 }
コード例 #52
0
 public ClLinearExpression(ClAbstractVariable clv) : this(clv, 1, 0)
 {}
コード例 #53
0
ファイル: ClTableau.cs プロジェクト: hur1can3/Cassowary.net
 /// <summary>
 /// Return true if and only if the variable subject is in the columns keys 
 /// </summary>
 protected /*sealed*/ bool ColumnsHasKey(ClAbstractVariable subject)
 { 
   return _columns.ContainsKey(subject);
 }
コード例 #54
0
    /// <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)
    {
      if (Trace)
        FnEnterPrint("DeltaEditConstant :" + delta + ", " 
            + plusErrorVar + ", " + 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;
      }

      Set columnVars = (Set) _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);
        }
      }
    }
コード例 #55
0
ファイル: ClTableau.cs プロジェクト: hur1can3/Cassowary.net
    /// <summary>
    /// Remove the basic variable v from the tableau row v=expr
    /// Then update column cross indices.
    /// </summary>
    protected /*sealed*/ ClLinearExpression RemoveRow(ClAbstractVariable var)
      /*throws ExCLInternalError*/
    {
      if (Trace) 
        FnEnterPrint(string.Format("RemoveRow: {0}", var));

      ClLinearExpression expr = (ClLinearExpression) _rows[var];
      Assert(expr != 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 (ClAbstractVariable clv in expr.Terms.Keys)
      {
        Set varset = (Set) _columns[clv];
        
        if (varset != null) 
        {
          if (Trace) 
            DebugPrint(string.Format("removing from varset {0}", var));
          
          varset.Remove(var);
        }
      }
                
      _infeasibleRows.Remove(var);

      if (var.IsExternal) {
        _externalRows.Remove(var);
      }

      _rows.Remove(var);
      if (Trace) 
        FnExitPrint(string.Format("returning {0}", expr));
      
      return expr;
    }
コード例 #56
0
    /// <summary>
    /// Do a pivot. Move entryVar into the basis and move exitVar 
    /// out of the basis.
    /// </summary>
    /// <remarks>
    /// We could for example make entryVar a basic variable and
    /// make exitVar a parametric variable.
    /// </remarks>
    protected void Pivot(ClAbstractVariable entryVar,
                         ClAbstractVariable exitVar)
      /* throws ExClInternalError */
    {
      if (Trace)
        FnEnterPrint("Pivot: " + entryVar + ", " + exitVar);

      // the entryVar might be non-pivotable if we're doing a 
      // RemoveConstraint -- otherwise it should be a pivotable
      // variable -- enforced at call sites, hopefully

      ClLinearExpression pexpr = RemoveRow(exitVar);

      pexpr.ChangeSubject(exitVar, entryVar);
      SubstituteOut(entryVar, pexpr);
      AddRow(entryVar, pexpr);
    }
コード例 #57
0
ファイル: ClTableau.cs プロジェクト: hur1can3/Cassowary.net
    // Add v=expr to the tableau, update column cross indices
    // v becomes a basic variable
    // expr is now owned by ClTableau class, 
    // and ClTableau is responsible for deleting it
    // (also, expr better be allocated on the heap!).
    protected /*sealed*/ void AddRow(ClAbstractVariable var, ClLinearExpression expr)
    {
      if (Trace) 
        FnEnterPrint("AddRow: " + var + ", " + expr);

      // for each variable in expr, add var to the set of rows which
      // have that variable in their expression
      _rows.Add(var, expr);
        
      // FIXME: check correctness!
      foreach (ClAbstractVariable clv in expr.Terms.Keys)
      {
        InsertColVar(clv, var);
        
        if (clv.IsExternal)
        {
          _externalParametricVars.Add(clv);
        }
      }

      if (var.IsExternal) {
        _externalRows.Add(var);
      }

      if (Trace) 
        TracePrint(this.ToString());
    }
コード例 #58
0
    /// <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);
    }
コード例 #59
0
 public ClLinearInequality(ClLinearExpression cle,
                           byte op_enum,
                           ClAbstractVariable clv) : this(cle, op_enum, clv, ClStrength.Required, 1.0)
                           /* throws ExClInternalError */
 {}
コード例 #60
0
 public ClLinearEquation(ClLinearExpression cle,
                         ClAbstractVariable clv,
                         ClStrength strength) : this(cle, clv, strength, 1.0)
 {}