/// <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);
        }
Пример #2
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);
        }
Пример #3
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);
        }
Пример #4
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));
            }
        }
Пример #5
0
        /// <summary>
        /// For use by the clone method.
        /// </summary>
        protected ClLinearExpression(ClDouble constant, Dictionary <ClAbstractVariable, ClDouble> terms)
        {
            _constant = constant.Clone();
            _terms    = new Dictionary <ClAbstractVariable, ClDouble>();

            // need to unalias the ClDouble-s that we clone (do a deep clone)
            foreach (var clv in terms.Keys)
            {
                _terms.Add(clv, (terms[clv]).Clone());
            }
        }
        public ClLinearExpression MultiplyMe(double x)
        {
            _constant.Value = _constant.Value * x;

            foreach (ClAbstractVariable clv in _terms.Keys)
            {
                ClDouble cld = (ClDouble)_terms[clv];
                cld.Value = cld.Value * x;
            }

            return(this);
        }
Пример #7
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);
        }
Пример #8
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));
    }
        /// <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)));
            }
        }
Пример #10
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);
            }
        }
        /// <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);
            }
        }
        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));
            }
        }
        /// <summary>
        /// For use by the clone method.
        /// </summary>
        protected ClLinearExpression(ClDouble constant, Hashtable terms)
        {
            if (Cl.GC)
            {
                Console.Error.WriteLine("clone ClLinearExpression");
            }

            _constant = (ClDouble)constant.Clone();
            _terms    = new Hashtable();

            // need to unalias the ClDouble-s that we clone (do a deep clone)
            foreach (ClAbstractVariable clv in terms.Keys)
            {
                _terms.Add(clv, ((ClDouble)terms[clv]).Clone());
            }
        }
        public /*sealed*/ ClLinearExpression SetVariable(ClAbstractVariable v, double c)
        {
            // Assert(c != 0.0);
            ClDouble coeff = (ClDouble)_terms[v];

            if (coeff != null)
            {
                coeff.Value = c;
            }
            else
            {
                _terms.Add(v, new ClDouble(c));
            }

            return(this);
        }
Пример #15
0
    /// <summary>
    /// For use by the clone method.
    /// </summary>
    protected ClLinearExpression(ClDouble constant, Hashtable terms)
    {
      if (Cl.GC)
      {
        Console.Error.WriteLine("clone ClLinearExpression");
      }
      
      _constant = (ClDouble) constant.Clone();
      _terms = new Hashtable();

      // need to unalias the ClDouble-s that we clone (do a deep clone)
      foreach (ClAbstractVariable clv in terms.Keys)
      {
        _terms.Add(clv, ((ClDouble) terms[clv]).Clone());
      }
    }
        /// <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);
        }
Пример #17
0
        /// <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>
        /// 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);
        }
Пример #19
0
	void Number(out ClDouble d) {
		Expect(13);
		double tmpVal = double.Parse(t.val, new CultureInfo("en-US").NumberFormat);
		d = new ClDouble(tmpVal);
		
	}
Пример #20
0
        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);
        }
Пример #21
0
    /// <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;
    }
Пример #22
0
    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;
    }