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:
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
+27
-119
@@ -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 <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 @@ 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<ConstraintList&>(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<ConstraintList&>(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;
|
||||
}
|
||||
|
||||
|
||||
+239
-61
@@ -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();
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user