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) {