Move lp_solve dependency completely into LinearSpec. Clean up and some more memory allocation checks.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39681 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Clemens Zeidler
2010-11-30 02:08:10 +00:00
parent d2ff9616c8
commit 067f47a3ee
5 changed files with 293 additions and 212 deletions
+7 -3
View File
@@ -33,7 +33,7 @@ public:
SummandList* LeftSide(); SummandList* LeftSide();
void SetLeftSide(SummandList* summands); void SetLeftSide(SummandList* summands);
void UpdateLeftSide();
void SetLeftSide(double coeff1, Variable* var1); void SetLeftSide(double coeff1, Variable* var1);
void SetLeftSide(double coeff1, Variable* var1, void SetLeftSide(double coeff1, Variable* var1,
double coeff2, Variable* var2); double coeff2, Variable* var2);
@@ -73,14 +73,18 @@ public:
protected: protected:
Constraint(LinearSpec* ls, Constraint(LinearSpec* ls,
SummandList* summands, OperatorType op, SummandList* summands, OperatorType op,
double rightSide, double penaltyNeg, double rightSide,
double penaltyPos); double penaltyNeg = INFINITY,
double penaltyPos = INFINITY);
private: private:
LinearSpec* fLS; LinearSpec* fLS;
SummandList* fLeftSide; SummandList* fLeftSide;
OperatorType fOp; OperatorType fOp;
double fRightSide; double fRightSide;
double fPenaltyNeg;
double fPenaltyPos;
Summand* fDNegObjSummand; Summand* fDNegObjSummand;
Summand* fDPosObjSummand; Summand* fDPosObjSummand;
BString fLabel; BString fLabel;
+18 -5
View File
@@ -43,6 +43,10 @@ public:
bool SetRange(Variable* variable, double min, bool SetRange(Variable* variable, double min,
double max); double max);
bool AddConstraint(Constraint* constraint);
bool RemoveConstraint(Constraint* constraint,
bool deleteConstraint = true);
Constraint* AddConstraint(SummandList* summands, Constraint* AddConstraint(SummandList* summands,
OperatorType op, double rightSide); OperatorType op, double rightSide);
Constraint* AddConstraint(double coeff1, Variable* var1, Constraint* AddConstraint(double coeff1, Variable* var1,
@@ -108,9 +112,21 @@ public:
const ConstraintList& Constraints() const; const ConstraintList& Constraints() const;
protected:
friend class Constraint;
bool UpdateLeftSide(Constraint* constraint);
bool UpdateRightSide(Constraint* constraint);
bool UpdateOperator(Constraint* constraint);
private: private:
ResultType Presolve(); /*! Check if all entries != NULL otherwise delete the list and its
void RemovePresolved(); entries. */
bool _CheckSummandList(SummandList* list);
Constraint* _AddConstraint(SummandList* leftSide,
OperatorType op, double rightSide,
double penaltyNeg, double penaltyPos);
ResultType _Presolve();
void _RemovePresolved();
lprec* fLpPresolved; lprec* fLpPresolved;
OptimizationType fOptimization; OptimizationType fOptimization;
@@ -122,9 +138,6 @@ private:
double fObjectiveValue; double fObjectiveValue;
double fSolvingTime; double fSolvingTime;
public:
friend class Constraint;
}; };
} // namespace LinearProgramming } // namespace LinearProgramming
+27 -119
View File
@@ -66,42 +66,7 @@ Constraint::SetLeftSide(SummandList* summands)
return; return;
fLeftSide = summands; 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();
} }
@@ -115,7 +80,7 @@ Constraint::SetLeftSide(double coeff1, Variable* var1)
delete fLeftSide->ItemAt(i); delete fLeftSide->ItemAt(i);
fLeftSide->MakeEmpty(); fLeftSide->MakeEmpty();
fLeftSide->AddItem(new(std::nothrow) Summand(coeff1, var1)); 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->MakeEmpty();
fLeftSide->AddItem(new(std::nothrow) Summand(coeff1, var1)); fLeftSide->AddItem(new(std::nothrow) Summand(coeff1, var1));
fLeftSide->AddItem(new(std::nothrow) Summand(coeff2, var2)); 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(coeff1, var1));
fLeftSide->AddItem(new(std::nothrow) Summand(coeff2, var2)); fLeftSide->AddItem(new(std::nothrow) Summand(coeff2, var2));
fLeftSide->AddItem(new(std::nothrow) Summand(coeff3, var3)); 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(coeff2, var2));
fLeftSide->AddItem(new(std::nothrow) Summand(coeff3, var3)); fLeftSide->AddItem(new(std::nothrow) Summand(coeff3, var3));
fLeftSide->AddItem(new(std::nothrow) Summand(coeff4, var4)); fLeftSide->AddItem(new(std::nothrow) Summand(coeff4, var4));
UpdateLeftSide(); fLS->UpdateLeftSide(this);
} }
@@ -197,13 +162,7 @@ Constraint::SetOp(OperatorType value)
return; return;
fOp = value; fOp = value;
if (!set_constr_type(fLS->fLP, this->Index(), fLS->UpdateOperator(this);
((fOp == OperatorType(EQ)) ? EQ
: (fOp == OperatorType(GE)) ? GE
: LE)))
STRACE(("Error in set_constr_type."));
fLS->RemovePresolved();
} }
@@ -234,10 +193,8 @@ Constraint::SetRightSide(double value)
return; return;
fRightSide = value; 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 double
Constraint::PenaltyNeg() const Constraint::PenaltyNeg() const
{ {
if (fDNegObjSummand == NULL) return fPenaltyNeg;
return INFINITY;
return fDNegObjSummand->Coeff();
} }
@@ -264,13 +219,15 @@ Constraint::PenaltyNeg() const
void void
Constraint::SetPenaltyNeg(double value) Constraint::SetPenaltyNeg(double value)
{ {
fPenaltyNeg = value;
if (!fIsValid) if (!fIsValid)
return; return;
if (fDNegObjSummand == NULL) { if (fDNegObjSummand == NULL) {
fDNegObjSummand = new(std::nothrow) Summand(value, fLS->AddVariable()); fDNegObjSummand = new(std::nothrow) Summand(value, fLS->AddVariable());
fLS->ObjectiveFunction()->AddItem(fDNegObjSummand); fLS->ObjectiveFunction()->AddItem(fDNegObjSummand);
UpdateLeftSide(); fLS->UpdateLeftSide(this);
fLS->UpdateObjectiveFunction(); fLS->UpdateObjectiveFunction();
return; return;
} }
@@ -291,28 +248,27 @@ Constraint::SetPenaltyNeg(double value)
double double
Constraint::PenaltyPos() const Constraint::PenaltyPos() const
{ {
if (fDPosObjSummand == NULL) return fPenaltyPos;
return INFINITY;
return fDPosObjSummand->Coeff();
} }
/** /**
* The penalty coefficient for negative deviations from the soft constraint's exact solution, * The penalty coefficient for negative deviations from the soft constraint's
* i.e. if the left side is too small. * exact solution, i.e. if the left side is too small.
*
* @param value coefficient of positive penalty <code>double</code> * @param value coefficient of positive penalty <code>double</code>
*/ */
void void
Constraint::SetPenaltyPos(double value) Constraint::SetPenaltyPos(double value)
{ {
fPenaltyPos = value;
if (!fIsValid) if (!fIsValid)
return; return;
if (fDPosObjSummand == NULL) { if (fDPosObjSummand == NULL) {
fDPosObjSummand = new(std::nothrow) Summand(value, fLS->AddVariable()); fDPosObjSummand = new(std::nothrow) Summand(value, fLS->AddVariable());
fLS->ObjectiveFunction()->AddItem(fDPosObjSummand); fLS->ObjectiveFunction()->AddItem(fDPosObjSummand);
UpdateLeftSide(); fLS->UpdateLeftSide(this);
fLS->UpdateObjectiveFunction(); fLS->UpdateObjectiveFunction();
return; return;
} }
@@ -424,27 +380,7 @@ Constraint::Invalidate()
return; return;
fIsValid = false; fIsValid = false;
fLS->RemoveConstraint(this, 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);
} }
@@ -492,46 +428,13 @@ Constraint::Constraint(LinearSpec* ls, SummandList* summands, OperatorType op,
fLeftSide(summands), fLeftSide(summands),
fOp(op), fOp(op),
fRightSide(rightSide), fRightSide(rightSide),
fPenaltyNeg(penaltyNeg),
fPenaltyPos(penaltyPos),
fDNegObjSummand(NULL),
fDPosObjSummand(NULL),
fIsValid(true) 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(LinearSpec* ls, SummandList* summands, OperatorType op,
Constraint::~Constraint() Constraint::~Constraint()
{ {
Invalidate(); Invalidate();
for (int32 i = 0; i < fLeftSide->CountItems(); i++)
delete (Summand*)fLeftSide->ItemAt(i);
delete fLeftSide;
fLeftSide = NULL;
} }
+239 -61
View File
@@ -43,7 +43,7 @@ LinearSpec::LinearSpec()
*/ */
LinearSpec::~LinearSpec() LinearSpec::~LinearSpec()
{ {
RemovePresolved(); _RemovePresolved();
for (int32 i = 0; i < fConstraints.CountItems(); i++) for (int32 i = 0; i < fConstraints.CountItems(); i++)
delete (Constraint*)fConstraints.ItemAt(i); delete (Constraint*)fConstraints.ItemAt(i);
for (int32 i = 0; i < fObjFunction->CountItems(); i++) for (int32 i = 0; i < fObjFunction->CountItems(); i++)
@@ -80,6 +80,9 @@ LinearSpec::AddVariable()
bool bool
LinearSpec::AddVariable(Variable* variable) LinearSpec::AddVariable(Variable* variable)
{ {
if (variable->IsValid())
return false;
double d = 0; double d = 0;
int i = 0; int i = 0;
@@ -90,7 +93,7 @@ LinearSpec::AddVariable(Variable* variable)
return false; return false;
} }
if (!SetRange(variable, -20000, 20000)) { if (!SetRange(variable, variable->Min(), variable->Max())) {
RemoveVariable(variable, false); RemoveVariable(variable, false);
return false; return false;
} }
@@ -110,7 +113,29 @@ LinearSpec::RemoveVariable(Variable* variable, bool deleteVariable)
if (!del_column(fLP, index)) if (!del_column(fLP, index))
return false; return false;
fVariables.RemoveItemAt(index - 1); 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) if (deleteVariable)
delete variable; 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. * Adds a new hard linear constraint to the specification.
* *
@@ -150,10 +316,7 @@ Constraint*
LinearSpec::AddConstraint(SummandList* summands, OperatorType op, LinearSpec::AddConstraint(SummandList* summands, OperatorType op,
double rightSide) double rightSide)
{ {
Constraint* c = new(std::nothrow) Constraint(this, summands, op, rightSide, return AddConstraint(summands, op, rightSide, INFINITY, INFINITY);
INFINITY, INFINITY);
RemovePresolved();
return c;
} }
@@ -170,12 +333,7 @@ Constraint*
LinearSpec::AddConstraint(double coeff1, Variable* var1, LinearSpec::AddConstraint(double coeff1, Variable* var1,
OperatorType op, double rightSide) OperatorType op, double rightSide)
{ {
SummandList* summands = new(std::nothrow) SummandList(1); return AddConstraint(coeff1, var1, op, rightSide, INFINITY, INFINITY);
summands->AddItem(new(std::nothrow) Summand(coeff1, var1));
Constraint* c = new(std::nothrow) Constraint(this, summands, op, rightSide,
INFINITY, INFINITY);
RemovePresolved();
return c;
} }
@@ -194,13 +352,8 @@ Constraint*
LinearSpec::AddConstraint(double coeff1, Variable* var1, LinearSpec::AddConstraint(double coeff1, Variable* var1,
double coeff2, Variable* var2, OperatorType op, double rightSide) double coeff2, Variable* var2, OperatorType op, double rightSide)
{ {
SummandList* summands = new(std::nothrow) SummandList(2); return AddConstraint(coeff1, var1, coeff2, var2, op, rightSide, INFINITY,
summands->AddItem(new(std::nothrow) Summand(coeff1, var1)); INFINITY);
summands->AddItem(new(std::nothrow) Summand(coeff2, var2));
Constraint* c = new(std::nothrow) Constraint(this, summands, op, rightSide,
INFINITY, INFINITY);
RemovePresolved();
return c;
} }
@@ -222,14 +375,8 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
double coeff2, Variable* var2, double coeff3, Variable* var3, double coeff2, Variable* var2, double coeff3, Variable* var3,
OperatorType op, double rightSide) OperatorType op, double rightSide)
{ {
SummandList* summands = new(std::nothrow) SummandList(3); return AddConstraint(coeff1, var1, coeff2, var2, coeff3, var3, op,
summands->AddItem(new(std::nothrow) Summand(coeff1, var1)); rightSide, INFINITY, INFINITY);
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;
} }
@@ -253,15 +400,8 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
double coeff2, Variable* var2, double coeff3, Variable* var3, double coeff2, Variable* var2, double coeff3, Variable* var3,
double coeff4, Variable* var4, OperatorType op, double rightSide) double coeff4, Variable* var4, OperatorType op, double rightSide)
{ {
SummandList* summands = new(std::nothrow) SummandList(3); return AddConstraint(coeff1, var1, coeff2, var2, coeff3, var3, coeff4, var4,
summands->AddItem(new(std::nothrow) Summand(coeff1, var1)); op, rightSide, INFINITY, INFINITY);
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;
} }
@@ -280,10 +420,7 @@ Constraint*
LinearSpec::AddConstraint(SummandList* summands, OperatorType op, LinearSpec::AddConstraint(SummandList* summands, OperatorType op,
double rightSide, double penaltyNeg, double penaltyPos) double rightSide, double penaltyNeg, double penaltyPos)
{ {
Constraint* c = new(std::nothrow) Constraint(this, summands, op, rightSide, return _AddConstraint(summands, op, rightSide, penaltyNeg, penaltyPos);
penaltyNeg, penaltyPos);
RemovePresolved();
return c;
} }
@@ -302,11 +439,12 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
OperatorType op, double rightSide, double penaltyNeg, double penaltyPos) OperatorType op, double rightSide, double penaltyNeg, double penaltyPos)
{ {
SummandList* summands = new(std::nothrow) SummandList(1); SummandList* summands = new(std::nothrow) SummandList(1);
if (!summands)
return NULL;
summands->AddItem(new(std::nothrow) Summand(coeff1, var1)); summands->AddItem(new(std::nothrow) Summand(coeff1, var1));
Constraint* c = new(std::nothrow) Constraint(this, summands, op, rightSide, if (!_CheckSummandList(summands))
penaltyNeg, penaltyPos); return NULL;
RemovePresolved(); return _AddConstraint(summands, op, rightSide, penaltyNeg, penaltyPos);
return c;
} }
@@ -328,12 +466,13 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
double penaltyNeg, double penaltyPos) double penaltyNeg, double penaltyPos)
{ {
SummandList* summands = new(std::nothrow) SummandList(2); 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(coeff1, var1));
summands->AddItem(new(std::nothrow) Summand(coeff2, var2)); summands->AddItem(new(std::nothrow) Summand(coeff2, var2));
Constraint* c = new(std::nothrow) Constraint(this, summands, op, rightSide, if (!_CheckSummandList(summands))
penaltyNeg, penaltyPos); return NULL;
RemovePresolved(); return _AddConstraint(summands, op, rightSide, penaltyNeg, penaltyPos);
return c;
} }
@@ -357,13 +496,14 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
OperatorType op, double rightSide, double penaltyNeg, double penaltyPos) OperatorType op, double rightSide, double penaltyNeg, double penaltyPos)
{ {
SummandList* summands = new(std::nothrow) SummandList(2); 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(coeff1, var1));
summands->AddItem(new(std::nothrow) Summand(coeff2, var2)); summands->AddItem(new(std::nothrow) Summand(coeff2, var2));
summands->AddItem(new(std::nothrow) Summand(coeff3, var3)); summands->AddItem(new(std::nothrow) Summand(coeff3, var3));
Constraint* c = new(std::nothrow) Constraint(this, summands, op, rightSide, if (!_CheckSummandList(summands))
penaltyNeg, penaltyPos); return NULL;
RemovePresolved(); return _AddConstraint(summands, op, rightSide, penaltyNeg, penaltyPos);
return c;
} }
@@ -390,14 +530,15 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
double penaltyNeg, double penaltyPos) double penaltyNeg, double penaltyPos)
{ {
SummandList* summands = new(std::nothrow) SummandList(2); 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(coeff1, var1));
summands->AddItem(new(std::nothrow) Summand(coeff2, var2)); summands->AddItem(new(std::nothrow) Summand(coeff2, var2));
summands->AddItem(new(std::nothrow) Summand(coeff3, var3)); summands->AddItem(new(std::nothrow) Summand(coeff3, var3));
summands->AddItem(new(std::nothrow) Summand(coeff4, var4)); summands->AddItem(new(std::nothrow) Summand(coeff4, var4));
Constraint* c = new(std::nothrow) Constraint(this, summands, op, rightSide, if (!_CheckSummandList(summands))
penaltyNeg, penaltyPos); return NULL;
RemovePresolved(); return _AddConstraint(summands, op, rightSide, penaltyNeg, penaltyPos);
return c;
} }
@@ -475,7 +616,44 @@ LinearSpec::UpdateObjectiveFunction()
if (!set_obj_fnex(fLP, size, &coeffs[0], &varIndexes[0])) if (!set_obj_fnex(fLP, size, &coeffs[0], &varIndexes[0]))
printf("Error in set_obj_fnex.\n"); 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. * to avoid an old cached presolved model getting out of sync.
*/ */
void void
LinearSpec::RemovePresolved() LinearSpec::_RemovePresolved()
{ {
if (fLpPresolved == NULL) if (fLpPresolved == NULL)
return; return;
@@ -503,7 +681,7 @@ LinearSpec::RemovePresolved()
* @return the result of the solving attempt * @return the result of the solving attempt
*/ */
ResultType ResultType
LinearSpec::Presolve() LinearSpec::_Presolve()
{ {
bigtime_t start, end; bigtime_t start, end;
start = system_time(); start = system_time();
@@ -543,7 +721,7 @@ ResultType
LinearSpec::Solve() LinearSpec::Solve()
{ {
if (fLpPresolved != NULL) if (fLpPresolved != NULL)
return Presolve(); return _Presolve();
bigtime_t start, end; bigtime_t start, end;
start = system_time(); start = system_time();
+2 -24
View File
@@ -281,29 +281,7 @@ Variable::Invalidate()
return; return;
fIsValid = false; fIsValid = false;
fLS->RemoveVariable(this, 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), fLS(ls),
fValue(NAN), fValue(NAN),
fMin(0), fMin(-20000),
fMax(DBL_MAX), fMax(20000),
fLabel(NULL), fLabel(NULL),
fIsValid(false) fIsValid(false)
{ {