[haiku-commits] r39681 - in haiku/trunk: headers/libs/linprog src/libs/linprog

  • From: clemens.zeidler@xxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Tue, 30 Nov 2010 03:08:11 +0100 (CET)

Author: czeidler
Date: 2010-11-30 03:08:10 +0100 (Tue, 30 Nov 2010)
New Revision: 39681
Changeset: http://dev.haiku-os.org/changeset/39681

Modified:
   haiku/trunk/headers/libs/linprog/Constraint.h
   haiku/trunk/headers/libs/linprog/LinearSpec.h
   haiku/trunk/src/libs/linprog/Constraint.cpp
   haiku/trunk/src/libs/linprog/LinearSpec.cpp
   haiku/trunk/src/libs/linprog/Variable.cpp
Log:
Move lp_solve dependency completely into LinearSpec. Clean up and some more 
memory allocation checks.



Modified: haiku/trunk/headers/libs/linprog/Constraint.h
===================================================================
--- haiku/trunk/headers/libs/linprog/Constraint.h       2010-11-29 21:44:38 UTC 
(rev 39680)
+++ haiku/trunk/headers/libs/linprog/Constraint.h       2010-11-30 02:08:10 UTC 
(rev 39681)
@@ -33,7 +33,7 @@
 
                        SummandList*            LeftSide();
                        void                            
SetLeftSide(SummandList* summands);
-                       void                            UpdateLeftSide();
+                       
                        void                            SetLeftSide(double 
coeff1, Variable* var1);
                        void                            SetLeftSide(double 
coeff1, Variable* var1,
                                                                        double 
coeff2, Variable* var2);
@@ -73,14 +73,18 @@
 protected:
                                                                
Constraint(LinearSpec* ls,
                                                                        
SummandList* summands, OperatorType op,
-                                                                       double 
rightSide, double penaltyNeg,
-                                                                       double 
penaltyPos);
+                                                                       double 
rightSide,
+                                                                       double 
penaltyNeg = INFINITY,
+                                                                       double 
penaltyPos = INFINITY);
 
 private:
                        LinearSpec*                     fLS;
                        SummandList*            fLeftSide;
                        OperatorType            fOp;
                        double                          fRightSide;
+
+                       double                          fPenaltyNeg;
+                       double                          fPenaltyPos;
                        Summand*                        fDNegObjSummand;
                        Summand*                        fDPosObjSummand;
                        BString                         fLabel;

Modified: haiku/trunk/headers/libs/linprog/LinearSpec.h
===================================================================
--- haiku/trunk/headers/libs/linprog/LinearSpec.h       2010-11-29 21:44:38 UTC 
(rev 39680)
+++ haiku/trunk/headers/libs/linprog/LinearSpec.h       2010-11-30 02:08:10 UTC 
(rev 39681)
@@ -43,6 +43,10 @@
                        bool                            SetRange(Variable* 
variable, double min,
                                                                        double 
max);
 
+                       bool                            
AddConstraint(Constraint* constraint);
+                       bool                            
RemoveConstraint(Constraint* constraint,
+                                                                       bool 
deleteConstraint = true);
+
                        Constraint*                     
AddConstraint(SummandList* summands,
                                                                        
OperatorType op, double rightSide);
                        Constraint*                     AddConstraint(double 
coeff1, Variable* var1,
@@ -108,10 +112,22 @@
 
        const   ConstraintList&         Constraints() const;
 
+protected:
+       friend class Constraint;
+                       bool                            
UpdateLeftSide(Constraint* constraint);
+                       bool                            
UpdateRightSide(Constraint* constraint);
+                       bool                            
UpdateOperator(Constraint* constraint);
 private:
-                       ResultType                      Presolve();
-                       void                            RemovePresolved();
+                       /*! Check if all entries != NULL otherwise delete the 
list and its
+                       entries. */
+                       bool                            
_CheckSummandList(SummandList* list);
+                       Constraint*                     
_AddConstraint(SummandList* leftSide,
+                                                                       
OperatorType op, double rightSide,
+                                                                       double 
penaltyNeg, double penaltyPos);
 
+                       ResultType                      _Presolve();
+                       void                            _RemovePresolved();
+
                        lprec*                          fLpPresolved;
                        OptimizationType        fOptimization;
                        lprec*                          fLP;
@@ -122,9 +138,6 @@
                        double                          fObjectiveValue;
                        double                          fSolvingTime;
 
-public:
-       friend class            Constraint;
-
 };
 
 }      // namespace LinearProgramming

Modified: haiku/trunk/src/libs/linprog/Constraint.cpp
===================================================================
--- haiku/trunk/src/libs/linprog/Constraint.cpp 2010-11-29 21:44:38 UTC (rev 
39680)
+++ haiku/trunk/src/libs/linprog/Constraint.cpp 2010-11-30 02:08:10 UTC (rev 
39681)
@@ -66,46 +66,11 @@
                return;
 
        fLeftSide = summands;
-       UpdateLeftSide();
+       fLS->UpdateLeftSide(this);
 }
 
 
 void
-Constraint::UpdateLeftSide()
-{
-       if (!fIsValid)
-               return;
-
-       double coeffs[fLeftSide->CountItems() + 2];
-       int varIndexes[fLeftSide->CountItems() + 2];
-       int32 i;
-       for (i = 0; i < fLeftSide->CountItems(); i++) {
-               Summand* s = fLeftSide->ItemAt(i);
-               coeffs[i] = s->Coeff();
-               varIndexes[i] = s->Var()->Index();
-       }
-
-       if (fDNegObjSummand != NULL && fOp != OperatorType(LE)) {
-               varIndexes[i] = fDNegObjSummand->Var()->Index();
-               coeffs[i] = 1.0;
-               i++;
-       }
-
-       if (fDPosObjSummand != NULL && fOp != OperatorType(GE)) {
-               varIndexes[i] = fDPosObjSummand->Var()->Index();
-               coeffs[i] = -1.0;
-               i++;
-       }
-
-       if (!set_rowex(fLS->fLP, this->Index(), i, &coeffs[0], &varIndexes[0]))
-               STRACE(("Error in set_rowex."));
-
-       fLS->UpdateObjectiveFunction();
-       fLS->RemovePresolved();
-}
-
-
-void
 Constraint::SetLeftSide(double coeff1, Variable* var1)
 {
        if (!fIsValid)
@@ -115,7 +80,7 @@
                delete fLeftSide->ItemAt(i);
        fLeftSide->MakeEmpty();
        fLeftSide->AddItem(new(std::nothrow) Summand(coeff1, var1));
-       UpdateLeftSide();
+       fLS->UpdateLeftSide(this);
 }
 
 
@@ -131,7 +96,7 @@
        fLeftSide->MakeEmpty();
        fLeftSide->AddItem(new(std::nothrow) Summand(coeff1, var1));
        fLeftSide->AddItem(new(std::nothrow) Summand(coeff2, var2));
-       UpdateLeftSide();
+       fLS->UpdateLeftSide(this);
 }
 
 
@@ -149,7 +114,7 @@
        fLeftSide->AddItem(new(std::nothrow) Summand(coeff1, var1));
        fLeftSide->AddItem(new(std::nothrow) Summand(coeff2, var2));
        fLeftSide->AddItem(new(std::nothrow) Summand(coeff3, var3));
-       UpdateLeftSide();
+       fLS->UpdateLeftSide(this);
 }
 
 
@@ -169,7 +134,7 @@
        fLeftSide->AddItem(new(std::nothrow) Summand(coeff2, var2));
        fLeftSide->AddItem(new(std::nothrow) Summand(coeff3, var3));
        fLeftSide->AddItem(new(std::nothrow) Summand(coeff4, var4));
-       UpdateLeftSide();
+       fLS->UpdateLeftSide(this);
 }
 
 
@@ -197,13 +162,7 @@
                return;
 
        fOp = value;
-       if (!set_constr_type(fLS->fLP, this->Index(),
-                       ((fOp == OperatorType(EQ)) ? EQ
-                       : (fOp == OperatorType(GE)) ? GE
-                       : LE)))
-               STRACE(("Error in set_constr_type."));
-
-       fLS->RemovePresolved();
+       fLS->UpdateOperator(this);
 }
 
 
@@ -234,10 +193,8 @@
                return;
 
        fRightSide = value;
-       if (!set_rh(fLS->fLP, Index(), fRightSide))
-               STRACE(("Error in set_rh."));
 
-       fLS->RemovePresolved();
+       fLS->UpdateRightSide(this);
 }
 
 
@@ -249,9 +206,7 @@
 double
 Constraint::PenaltyNeg() const
 {
-       if (fDNegObjSummand == NULL)
-               return INFINITY;
-       return fDNegObjSummand->Coeff();
+       return fPenaltyNeg;
 }
 
 
@@ -264,13 +219,15 @@
 void
 Constraint::SetPenaltyNeg(double value)
 {
+       fPenaltyNeg = value;
+
        if (!fIsValid)
                return;
 
        if (fDNegObjSummand == NULL) {
                fDNegObjSummand = new(std::nothrow) Summand(value, 
fLS->AddVariable());
                fLS->ObjectiveFunction()->AddItem(fDNegObjSummand);
-               UpdateLeftSide();
+               fLS->UpdateLeftSide(this);
                fLS->UpdateObjectiveFunction();
                return;
        }
@@ -291,28 +248,27 @@
 double
 Constraint::PenaltyPos() const
 {
-       if (fDPosObjSummand == NULL)
-               return INFINITY;
-       return fDPosObjSummand->Coeff();
+       return fPenaltyPos;
 }
 
 
 /**
- * The penalty coefficient for negative deviations from the soft constraint's 
exact solution,
- * i.e. if the left side is too small.
- *
+ * The penalty coefficient for negative deviations from the soft constraint's
+ * exact solution, i.e. if the left side is too small.
  * @param value        coefficient of positive penalty <code>double</code>
  */
 void
 Constraint::SetPenaltyPos(double value)
 {
+       fPenaltyPos = value;
+
        if (!fIsValid)
                return;
 
        if (fDPosObjSummand == NULL) {
                fDPosObjSummand = new(std::nothrow) Summand(value, 
fLS->AddVariable());
                fLS->ObjectiveFunction()->AddItem(fDPosObjSummand);
-               UpdateLeftSide();
+               fLS->UpdateLeftSide(this);
                fLS->UpdateObjectiveFunction();
                return;
        }
@@ -424,27 +380,7 @@
                return;
 
        fIsValid = false;
-
-       for (int32 i = 0; i < fLeftSide->CountItems(); i++)
-               delete (Summand*)fLeftSide->ItemAt(i);
-       delete fLeftSide;
-       fLeftSide = NULL;
-
-       if (fDNegObjSummand) {
-               fLS->ObjectiveFunction()->RemoveItem(fDNegObjSummand);
-               delete fDNegObjSummand->Var();
-               delete fDNegObjSummand;
-               fDNegObjSummand = NULL;
-       }
-       if (fDPosObjSummand) {
-               fLS->ObjectiveFunction()->RemoveItem(fDPosObjSummand);
-               delete fDPosObjSummand->Var();
-               delete fDPosObjSummand;
-               fDPosObjSummand = NULL;
-       }
-
-       del_constraint(fLS->fLP, this->Index());
-       const_cast<ConstraintList&>(fLS->Constraints()).RemoveItem(this);
+       fLS->RemoveConstraint(this, false);
 }
 
 
@@ -492,46 +428,13 @@
        fLeftSide(summands),
        fOp(op),
        fRightSide(rightSide),
+       fPenaltyNeg(penaltyNeg),
+       fPenaltyPos(penaltyPos),
+       fDNegObjSummand(NULL),
+       fDPosObjSummand(NULL),
        fIsValid(true)
 {
-       double coeffs[summands->CountItems() + 2];
-       int varIndexes[summands->CountItems() + 2];
-       int32 nCoefficient = 0;
-       for (; nCoefficient < summands->CountItems(); nCoefficient++) {
-               Summand* s = summands->ItemAt(nCoefficient);
-               coeffs[nCoefficient] = s->Coeff();
-               varIndexes[nCoefficient] = s->Var()->Index();
-       }
 
-       if (penaltyNeg != INFINITY && penaltyNeg != 0. && fOp != 
OperatorType(LE)) {
-               fDNegObjSummand = new(std::nothrow) Summand(penaltyNeg,
-                       ls->AddVariable());
-               fLS->fObjFunction->AddItem(fDNegObjSummand);
-               varIndexes[nCoefficient] = fDNegObjSummand->Var()->Index();
-               coeffs[nCoefficient] = 1.0;
-               nCoefficient++;
-       }
-       else
-               fDNegObjSummand = NULL;
-
-       if (penaltyPos != INFINITY && penaltyPos != 0. && fOp != 
OperatorType(GE)) {
-               fDPosObjSummand = new(std::nothrow) Summand(penaltyPos,
-                       ls->AddVariable());
-               fLS->fObjFunction->AddItem(fDPosObjSummand);
-               varIndexes[nCoefficient] = fDPosObjSummand->Var()->Index();
-               coeffs[nCoefficient] = -1.0;
-               nCoefficient++;
-       }
-       else
-               fDPosObjSummand = NULL;
-
-       if (!add_constraintex(fLS->fLP, nCoefficient, &coeffs[0], 
&varIndexes[0],
-                       (fOp == OperatorType(EQ) ? EQ : (fOp == 
OperatorType(GE)) ? GE
-                               : LE), rightSide))
-               STRACE(("Error in add_constraintex."));
-
-       fLS->UpdateObjectiveFunction();
-       const_cast<ConstraintList&>(fLS->Constraints()).AddItem(this);
 }
 
 
@@ -542,5 +445,10 @@
 Constraint::~Constraint()
 {
        Invalidate();
+
+       for (int32 i = 0; i < fLeftSide->CountItems(); i++)
+               delete (Summand*)fLeftSide->ItemAt(i);
+       delete fLeftSide;
+       fLeftSide = NULL;
 }
 

Modified: haiku/trunk/src/libs/linprog/LinearSpec.cpp
===================================================================
--- haiku/trunk/src/libs/linprog/LinearSpec.cpp 2010-11-29 21:44:38 UTC (rev 
39680)
+++ haiku/trunk/src/libs/linprog/LinearSpec.cpp 2010-11-30 02:08:10 UTC (rev 
39681)
@@ -43,7 +43,7 @@
  */
 LinearSpec::~LinearSpec()
 {
-       RemovePresolved();
+       _RemovePresolved();
        for (int32 i = 0; i < fConstraints.CountItems(); i++)
                delete (Constraint*)fConstraints.ItemAt(i);
        for (int32 i = 0; i < fObjFunction->CountItems(); i++)
@@ -80,6 +80,9 @@
 bool
 LinearSpec::AddVariable(Variable* variable)
 {
+       if (variable->IsValid())
+               return false;
+
        double d = 0;
        int i = 0;
 
@@ -90,7 +93,7 @@
                return false;
        }
 
-       if (!SetRange(variable, -20000, 20000)) {
+       if (!SetRange(variable, variable->Min(), variable->Max())) {
                RemoveVariable(variable, false);
                return false;
        }
@@ -110,8 +113,30 @@
        if (!del_column(fLP, index))
                return false;
        fVariables.RemoveItemAt(index - 1);
-       variable->Invalidate();
+       variable->fIsValid = false;
 
+       // invalidate all constraints that use this variable
+       ConstraintList markedForInvalidation;
+       const ConstraintList& constraints = Constraints();
+       for (int i = 0; i < constraints.CountItems(); i++) {
+               Constraint* constraint = constraints.ItemAt(i);
+
+               if (!constraint->IsValid())
+                       continue;
+
+               SummandList* summands = constraint->LeftSide();
+               for (int j = 0; j < summands->CountItems(); j++) {
+                       Summand* summand = summands->ItemAt(j);
+                       if (summand->Var() == variable) {
+                               markedForInvalidation.AddItem(constraint);
+                               break;
+                       }
+               }
+       }
+       for (int i = 0; i < markedForInvalidation.CountItems(); i++)
+               markedForInvalidation.ItemAt(i)->Invalidate();
+
+
        if (deleteVariable)
                delete variable;
        return true;
@@ -137,6 +162,147 @@
 }
 
 
+bool
+LinearSpec::AddConstraint(Constraint* constraint)
+{
+       SummandList* summands = constraint->LeftSide();
+       OperatorType op = constraint->Op();
+       double rightSide = constraint->RightSide();
+       double penaltyNeg = constraint->PenaltyNeg();
+       double penaltyPos = constraint->PenaltyPos();
+
+       double coeffs[summands->CountItems() + 2];
+       int varIndexes[summands->CountItems() + 2];
+       int32 nCoefficient = 0;
+       for (; nCoefficient < summands->CountItems(); nCoefficient++) {
+               Summand* s = summands->ItemAt(nCoefficient);
+               coeffs[nCoefficient] = s->Coeff();
+               varIndexes[nCoefficient] = s->Var()->Index();
+       }
+
+       if (penaltyNeg != INFINITY && penaltyNeg != 0. && op != 
OperatorType(LE)) {
+               constraint->fDNegObjSummand
+                       = new(std::nothrow) Summand(constraint->PenaltyNeg(),
+                               AddVariable());
+               fObjFunction->AddItem(constraint->fDNegObjSummand);
+               varIndexes[nCoefficient] = 
constraint->fDNegObjSummand->Var()->Index();
+               coeffs[nCoefficient] = 1.0;
+               nCoefficient++;
+       }
+
+       if (penaltyPos != INFINITY && penaltyPos != 0. && op != 
OperatorType(GE)) {
+               constraint->fDPosObjSummand
+                       = new(std::nothrow) Summand(constraint->PenaltyPos(),
+                               AddVariable());
+               fObjFunction->AddItem(constraint->fDPosObjSummand);
+               varIndexes[nCoefficient] = 
constraint->fDPosObjSummand->Var()->Index();
+               coeffs[nCoefficient] = -1.0;
+               nCoefficient++;
+       }
+
+       if (!add_constraintex(fLP, nCoefficient, &coeffs[0], &varIndexes[0],
+                       (op == OperatorType(EQ) ? EQ : (op == OperatorType(GE)) 
? GE
+                               : LE), rightSide))
+               return false;
+
+       UpdateObjectiveFunction();
+       fConstraints.AddItem(constraint);
+
+       return true;
+}
+
+
+bool
+LinearSpec::RemoveConstraint(Constraint* constraint, bool deleteConstraint)
+{
+       if (constraint->fDNegObjSummand) {
+               fObjFunction->RemoveItem(constraint->fDNegObjSummand);
+               delete constraint->fDNegObjSummand->Var();
+               delete constraint->fDNegObjSummand;
+               constraint->fDNegObjSummand = NULL;
+       }
+       if (constraint->fDPosObjSummand) {
+               fObjFunction->RemoveItem(constraint->fDPosObjSummand);
+               delete constraint->fDPosObjSummand->Var();
+               delete constraint->fDPosObjSummand;
+               constraint->fDPosObjSummand = NULL;
+       }
+
+       del_constraint(fLP, constraint->Index());
+       fConstraints.RemoveItem(constraint);
+       constraint->fIsValid = false;
+
+       if (deleteConstraint)
+               delete constraint;
+       return true;
+}
+
+
+bool
+LinearSpec::UpdateLeftSide(Constraint* constraint)
+{
+       if (!constraint->IsValid())
+               return false;
+
+       SummandList* leftSide = constraint->LeftSide();
+       OperatorType op = constraint->Op();
+
+       double coeffs[leftSide->CountItems() + 2];
+       int varIndexes[leftSide->CountItems() + 2];
+       int32 i;
+       for (i = 0; i < leftSide->CountItems(); i++) {
+               Summand* s = leftSide->ItemAt(i);
+               coeffs[i] = s->Coeff();
+               varIndexes[i] = s->Var()->Index();
+       }
+
+       if (constraint->fDNegObjSummand != NULL && op != OperatorType(LE)) {
+               varIndexes[i] = constraint->fDNegObjSummand->Var()->Index();
+               coeffs[i] = 1.0;
+               i++;
+       }
+
+       if (constraint->fDPosObjSummand != NULL && op != OperatorType(GE)) {
+               varIndexes[i] = constraint->fDPosObjSummand->Var()->Index();
+               coeffs[i] = -1.0;
+               i++;
+       }
+
+       if (!set_rowex(fLP, constraint->Index(), i, &coeffs[0],
+               &varIndexes[0]))
+               return false;
+
+       UpdateObjectiveFunction();
+       _RemovePresolved();
+       return true;
+}
+
+
+bool
+LinearSpec::UpdateRightSide(Constraint* constraint)
+{
+       if (!set_rh(fLP, constraint->Index(), constraint->RightSide()))
+               return false;
+
+       _RemovePresolved();
+       return true;
+}
+
+
+bool
+LinearSpec::UpdateOperator(Constraint* constraint)
+{
+       OperatorType op = constraint->Op();
+       if (!set_constr_type(fLP, constraint->Index(),
+               (op == OperatorType(EQ)) ? EQ : (op == OperatorType(GE)) ? GE
+                       : LE))
+               return false;
+
+       _RemovePresolved();
+       return true;
+}
+
+
 /**
  * Adds a new hard linear constraint to the specification.
  *
@@ -150,10 +316,7 @@
 LinearSpec::AddConstraint(SummandList* summands, OperatorType op,
        double rightSide)
 {
-       Constraint* c = new(std::nothrow) Constraint(this, summands, op, 
rightSide,
-               INFINITY, INFINITY);
-       RemovePresolved();
-       return c;
+       return AddConstraint(summands, op, rightSide, INFINITY, INFINITY);
 }
 
 
@@ -170,12 +333,7 @@
 LinearSpec::AddConstraint(double coeff1, Variable* var1,
        OperatorType op, double rightSide)
 {
-       SummandList* summands = new(std::nothrow) SummandList(1);
-       summands->AddItem(new(std::nothrow) Summand(coeff1, var1));
-       Constraint* c = new(std::nothrow) Constraint(this, summands, op, 
rightSide,
-               INFINITY, INFINITY);
-       RemovePresolved();
-       return c;
+       return AddConstraint(coeff1, var1, op, rightSide, INFINITY, INFINITY);
 }
 
 
@@ -194,13 +352,8 @@
 LinearSpec::AddConstraint(double coeff1, Variable* var1,
        double coeff2, Variable* var2, OperatorType op, double rightSide)
 {
-       SummandList* summands = new(std::nothrow) SummandList(2);
-       summands->AddItem(new(std::nothrow) Summand(coeff1, var1));
-       summands->AddItem(new(std::nothrow) Summand(coeff2, var2));
-       Constraint* c = new(std::nothrow) Constraint(this, summands, op, 
rightSide,
-               INFINITY, INFINITY);
-       RemovePresolved();
-       return c;
+       return AddConstraint(coeff1, var1, coeff2, var2, op, rightSide, 
INFINITY,
+               INFINITY);
 }
 
 
@@ -222,14 +375,8 @@
                double coeff2, Variable* var2, double coeff3, Variable* var3,
                OperatorType op, double rightSide)
 {
-       SummandList* summands = new(std::nothrow) SummandList(3);
-       summands->AddItem(new(std::nothrow) Summand(coeff1, var1));
-       summands->AddItem(new(std::nothrow) Summand(coeff2, var2));
-       summands->AddItem(new(std::nothrow) Summand(coeff3, var3));
-       Constraint* c = new(std::nothrow) Constraint(this, summands, op, 
rightSide,
-               INFINITY, INFINITY);
-       RemovePresolved();
-       return c;
+       return AddConstraint(coeff1, var1, coeff2, var2, coeff3, var3, op,
+               rightSide, INFINITY, INFINITY);
 }
 
 
@@ -253,15 +400,8 @@
                double coeff2, Variable* var2, double coeff3, Variable* var3,
                double coeff4, Variable* var4, OperatorType op, double 
rightSide)
 {
-       SummandList* summands = new(std::nothrow) SummandList(3);
-       summands->AddItem(new(std::nothrow) Summand(coeff1, var1));
-       summands->AddItem(new(std::nothrow) Summand(coeff2, var2));
-       summands->AddItem(new(std::nothrow) Summand(coeff3, var3));
-       summands->AddItem(new(std::nothrow) Summand(coeff4, var4));
-       Constraint* c = new(std::nothrow) Constraint(this, summands, op, 
rightSide,
-               INFINITY, INFINITY);
-       RemovePresolved();
-       return c;
+       return AddConstraint(coeff1, var1, coeff2, var2, coeff3, var3, coeff4, 
var4,
+               op, rightSide, INFINITY, INFINITY);
 }
 
 
@@ -280,10 +420,7 @@
 LinearSpec::AddConstraint(SummandList* summands, OperatorType op,
                double rightSide, double penaltyNeg, double penaltyPos)
 {
-       Constraint* c = new(std::nothrow) Constraint(this, summands, op, 
rightSide,
-                       penaltyNeg, penaltyPos);
-       RemovePresolved();
-       return c;
+       return _AddConstraint(summands, op, rightSide, penaltyNeg, penaltyPos);
 }
 
 
@@ -302,11 +439,12 @@
                OperatorType op, double rightSide, double penaltyNeg, double 
penaltyPos)
 {
        SummandList* summands = new(std::nothrow) SummandList(1);
+       if (!summands)
+               return NULL;
        summands->AddItem(new(std::nothrow) Summand(coeff1, var1));
-       Constraint* c = new(std::nothrow) Constraint(this, summands, op, 
rightSide,
-               penaltyNeg, penaltyPos);
-       RemovePresolved();
-       return c;
+       if (!_CheckSummandList(summands))
+               return NULL;
+       return _AddConstraint(summands, op, rightSide, penaltyNeg, penaltyPos);
 }
 
 
@@ -328,12 +466,13 @@
        double penaltyNeg, double penaltyPos)
 {
        SummandList* summands = new(std::nothrow) SummandList(2);
+       if (!summands)
+               return NULL;
        summands->AddItem(new(std::nothrow) Summand(coeff1, var1));
        summands->AddItem(new(std::nothrow) Summand(coeff2, var2));
-       Constraint* c = new(std::nothrow) Constraint(this, summands, op, 
rightSide,
-               penaltyNeg, penaltyPos);
-       RemovePresolved();
-       return c;
+       if (!_CheckSummandList(summands))
+               return NULL;
+       return _AddConstraint(summands, op, rightSide, penaltyNeg, penaltyPos);
 }
 
 
@@ -357,13 +496,14 @@
        OperatorType op, double rightSide, double penaltyNeg, double penaltyPos)
 {
        SummandList* summands = new(std::nothrow) SummandList(2);
+       if (!summands)
+               return NULL;
        summands->AddItem(new(std::nothrow) Summand(coeff1, var1));
        summands->AddItem(new(std::nothrow) Summand(coeff2, var2));
        summands->AddItem(new(std::nothrow) Summand(coeff3, var3));
-       Constraint* c = new(std::nothrow) Constraint(this, summands, op, 
rightSide,
-               penaltyNeg, penaltyPos);
-       RemovePresolved();
-       return c;
+       if (!_CheckSummandList(summands))
+               return NULL;
+       return _AddConstraint(summands, op, rightSide, penaltyNeg, penaltyPos);
 }
 
 
@@ -390,14 +530,15 @@
        double penaltyNeg, double penaltyPos)
 {
        SummandList* summands = new(std::nothrow) SummandList(2);
+       if (!summands)
+               return NULL;
        summands->AddItem(new(std::nothrow) Summand(coeff1, var1));
        summands->AddItem(new(std::nothrow) Summand(coeff2, var2));
        summands->AddItem(new(std::nothrow) Summand(coeff3, var3));
        summands->AddItem(new(std::nothrow) Summand(coeff4, var4));
-       Constraint* c = new(std::nothrow) Constraint(this, summands, op, 
rightSide,
-               penaltyNeg, penaltyPos);
-       RemovePresolved();
-       return c;
+       if (!_CheckSummandList(summands))
+               return NULL;
+       return _AddConstraint(summands, op, rightSide, penaltyNeg, penaltyPos);
 }
 
 
@@ -475,17 +616,54 @@
        if (!set_obj_fnex(fLP, size, &coeffs[0], &varIndexes[0]))
                printf("Error in set_obj_fnex.\n");
 
-       RemovePresolved();
+       _RemovePresolved();
 }
 
 
+bool
+LinearSpec::_CheckSummandList(SummandList* list)
+{
+       bool ok = true;
+       for (int i = 0; i < list->CountItems(); i++) {
+               if (list->ItemAt(i) == NULL) {
+                       ok = false;
+                       break;
+               }
+       }
+       if (ok)
+               return true;
+
+       for (int i = 0; i < list->CountItems(); i++)
+               delete list->ItemAt(i);
+       delete list;
+       return false;
+}
+
+
+Constraint*
+LinearSpec::_AddConstraint(SummandList* leftSide, OperatorType op,
+       double rightSide, double penaltyNeg, double penaltyPos)
+{
+       Constraint* constraint = new(std::nothrow) Constraint(this, leftSide,
+               op, rightSide, penaltyNeg, penaltyPos);
+       if (constraint == NULL)
+               return NULL;
+       if (!AddConstraint(constraint)) {
+               delete constraint;
+               return NULL;
+       }
+       _RemovePresolved();
+       return constraint;
+}
+
+
 /**
  * Remove a cached presolved model, if existent.
  * This is automatically done each time after the model has been changed,
  * to avoid an old cached presolved model getting out of sync.
  */
 void
-LinearSpec::RemovePresolved()
+LinearSpec::_RemovePresolved()
 {
        if (fLpPresolved == NULL)
                return;
@@ -503,7 +681,7 @@
  * @return the result of the solving attempt
  */
 ResultType
-LinearSpec::Presolve()
+LinearSpec::_Presolve()
 {
        bigtime_t start, end;
        start = system_time();
@@ -543,7 +721,7 @@
 LinearSpec::Solve()
 {
        if (fLpPresolved != NULL)
-               return Presolve();
+               return _Presolve();
 
        bigtime_t start, end;
        start = system_time();

Modified: haiku/trunk/src/libs/linprog/Variable.cpp
===================================================================
--- haiku/trunk/src/libs/linprog/Variable.cpp   2010-11-29 21:44:38 UTC (rev 
39680)
+++ haiku/trunk/src/libs/linprog/Variable.cpp   2010-11-30 02:08:10 UTC (rev 
39681)
@@ -281,29 +281,7 @@
                return;
 
        fIsValid = false;
-       
        fLS->RemoveVariable(this, false);
-
-       // invalidate all constraints that use this variable
-       ConstraintList markedForInvalidation;
-       const ConstraintList& constraints = fLS->Constraints();
-       for (int i = 0; i < constraints.CountItems(); i++) {
-               Constraint* constraint = constraints.ItemAt(i);
-
-               if (!constraint->IsValid())
-                       continue;
-
-               SummandList* summands = constraint->LeftSide();
-               for (int j = 0; j < summands->CountItems(); j++) {
-                       Summand* summand = summands->ItemAt(j);
-                       if (summand->Var() == this) {
-                               markedForInvalidation.AddItem(constraint);
-                               break;
-                       }
-               }
-       }
-       for (int i = 0; i < markedForInvalidation.CountItems(); i++)
-               markedForInvalidation.ItemAt(i)->Invalidate();
 }
 
 
@@ -314,8 +292,8 @@
        :
        fLS(ls),
        fValue(NAN),
-       fMin(0),
-       fMax(DBL_MAX),
+       fMin(-20000),
+       fMax(20000),
        fLabel(NULL),
        fIsValid(false)
 {


Other related posts:

  • » [haiku-commits] r39681 - in haiku/trunk: headers/libs/linprog src/libs/linprog - clemens . zeidler