diff --git a/headers/libs/linprog/Constraint.h b/headers/libs/linprog/Constraint.h
index 41b0ec4363..d011eb7f6e 100644
--- a/headers/libs/linprog/Constraint.h
+++ b/headers/libs/linprog/Constraint.h
@@ -33,7 +33,7 @@ public:
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 @@ public:
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;
diff --git a/headers/libs/linprog/LinearSpec.h b/headers/libs/linprog/LinearSpec.h
index 826be7bc50..78661ed123 100644
--- a/headers/libs/linprog/LinearSpec.h
+++ b/headers/libs/linprog/LinearSpec.h
@@ -43,6 +43,10 @@ public:
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,9 +112,21 @@ public:
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;
@@ -122,9 +138,6 @@ private:
double fObjectiveValue;
double fSolvingTime;
-public:
- friend class Constraint;
-
};
} // namespace LinearProgramming
diff --git a/src/libs/linprog/Constraint.cpp b/src/libs/linprog/Constraint.cpp
index b7a57326fc..090fc09941 100644
--- a/src/libs/linprog/Constraint.cpp
+++ b/src/libs/linprog/Constraint.cpp
@@ -66,42 +66,7 @@ Constraint::SetLeftSide(SummandList* summands)
return;
fLeftSide = summands;
- UpdateLeftSide();
-}
-
-
-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();
+ fLS->UpdateLeftSide(this);
}
@@ -115,7 +80,7 @@ Constraint::SetLeftSide(double coeff1, Variable* var1)
delete fLeftSide->ItemAt(i);
fLeftSide->MakeEmpty();
fLeftSide->AddItem(new(std::nothrow) Summand(coeff1, var1));
- UpdateLeftSide();
+ fLS->UpdateLeftSide(this);
}
@@ -131,7 +96,7 @@ Constraint::SetLeftSide(double coeff1, Variable* var1,
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 @@ Constraint::SetLeftSide(double coeff1, Variable* var1,
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 @@ Constraint::SetLeftSide(double coeff1, Variable* var1,
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 @@ Constraint::SetOp(OperatorType value)
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 @@ Constraint::SetRightSide(double value)
return;
fRightSide = value;
- if (!set_rh(fLS->fLP, Index(), fRightSide))
- STRACE(("Error in set_rh."));
- fLS->RemovePresolved();
+ fLS->UpdateRightSide(this);
}
@@ -249,9 +206,7 @@ Constraint::SetRightSide(double value)
double
Constraint::PenaltyNeg() const
{
- if (fDNegObjSummand == NULL)
- return INFINITY;
- return fDNegObjSummand->Coeff();
+ return fPenaltyNeg;
}
@@ -264,13 +219,15 @@ Constraint::PenaltyNeg() const
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 @@ Constraint::SetPenaltyNeg(double value)
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 double
*/
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 @@ Constraint::Invalidate()
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(fLS->Constraints()).RemoveItem(this);
+ fLS->RemoveConstraint(this, false);
}
@@ -492,46 +428,13 @@ Constraint::Constraint(LinearSpec* ls, SummandList* summands, OperatorType op,
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(fLS->Constraints()).AddItem(this);
}
@@ -542,5 +445,10 @@ Constraint::Constraint(LinearSpec* ls, SummandList* summands, OperatorType op,
Constraint::~Constraint()
{
Invalidate();
+
+ for (int32 i = 0; i < fLeftSide->CountItems(); i++)
+ delete (Summand*)fLeftSide->ItemAt(i);
+ delete fLeftSide;
+ fLeftSide = NULL;
}
diff --git a/src/libs/linprog/LinearSpec.cpp b/src/libs/linprog/LinearSpec.cpp
index 2fef02b0f8..66981a2477 100644
--- a/src/libs/linprog/LinearSpec.cpp
+++ b/src/libs/linprog/LinearSpec.cpp
@@ -43,7 +43,7 @@ LinearSpec::LinearSpec()
*/
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 @@ LinearSpec::AddVariable()
bool
LinearSpec::AddVariable(Variable* variable)
{
+ if (variable->IsValid())
+ return false;
+
double d = 0;
int i = 0;
@@ -90,7 +93,7 @@ LinearSpec::AddVariable(Variable* variable)
return false;
}
- if (!SetRange(variable, -20000, 20000)) {
+ if (!SetRange(variable, variable->Min(), variable->Max())) {
RemoveVariable(variable, false);
return false;
}
@@ -110,7 +113,29 @@ LinearSpec::RemoveVariable(Variable* variable, bool deleteVariable)
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;
@@ -137,6 +162,147 @@ LinearSpec::SetRange(Variable* variable, double min, double max)
}
+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 @@ Constraint*
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 @@ Constraint*
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 @@ Constraint*
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 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
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 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
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 @@ Constraint*
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 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
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 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
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 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
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 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
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,7 +616,44 @@ LinearSpec::UpdateObjectiveFunction()
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;
}
@@ -485,7 +663,7 @@ LinearSpec::UpdateObjectiveFunction()
* to avoid an old cached presolved model getting out of sync.
*/
void
-LinearSpec::RemovePresolved()
+LinearSpec::_RemovePresolved()
{
if (fLpPresolved == NULL)
return;
@@ -503,7 +681,7 @@ LinearSpec::RemovePresolved()
* @return the result of the solving attempt
*/
ResultType
-LinearSpec::Presolve()
+LinearSpec::_Presolve()
{
bigtime_t start, end;
start = system_time();
@@ -543,7 +721,7 @@ ResultType
LinearSpec::Solve()
{
if (fLpPresolved != NULL)
- return Presolve();
+ return _Presolve();
bigtime_t start, end;
start = system_time();
diff --git a/src/libs/linprog/Variable.cpp b/src/libs/linprog/Variable.cpp
index 5e083342e6..dc84a81942 100644
--- a/src/libs/linprog/Variable.cpp
+++ b/src/libs/linprog/Variable.cpp
@@ -281,29 +281,7 @@ Variable::Invalidate()
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 @@ Variable::Variable(LinearSpec* ls)
:
fLS(ls),
fValue(NAN),
- fMin(0),
- fMax(DBL_MAX),
+ fMin(-20000),
+ fMax(20000),
fLabel(NULL),
fIsValid(false)
{