* Applied patch by Hong Yul Yang to update linprog.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33609 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2009-10-16 12:13:07 +00:00
parent 98b4079944
commit 676ef01ba7
8 changed files with 511 additions and 90 deletions

View File

@ -11,6 +11,7 @@
#include "Variable.h"
#include "Summand.h"
#include <File.h>
#include <List.h>
#include <String.h>
#include <SupportDefs.h>
@ -29,7 +30,7 @@ class Constraint {
public:
int32 Index();
BList* LeftSide();
void SetLeftSide(BList* summands);
void UpdateLeftSide();
@ -46,17 +47,30 @@ public:
OperatorType Op();
void SetOp(OperatorType value);
double RightSide();
double RightSide() const;
void SetRightSide(double value);
double PenaltyNeg();
double PenaltyNeg() const;
void SetPenaltyNeg(double value);
double PenaltyPos();
double PenaltyPos() const;
void SetPenaltyPos(double value);
const char* Label();
void SetLabel(const char* label);
void WriteXML(BFile* file);
Variable* DNeg() const;
Variable* DPos() const;
BString ToString();
void SetOwner(void* owner);
void* Owner() const;
bool IsValid();
void Invalidate();
BString* ToBString();
const char* ToString();
~Constraint();
protected:
@ -71,6 +85,10 @@ private:
double fRightSide;
Summand* fDNegObjSummand;
Summand* fDPosObjSummand;
void* fOwner;
char* fLabel;
bool fIsValid;
public:
friend class LinearSpec;

View File

@ -18,6 +18,7 @@
#include "lp_lib.h"
#include <List.h>
#include <String.h>
#include <OS.h>
#include <SupportDefs.h>
#include <math.h>
@ -37,7 +38,7 @@ class LinearSpec {
public:
LinearSpec();
~LinearSpec();
virtual ~LinearSpec();
Variable* AddVariable();
@ -100,6 +101,9 @@ public:
double ObjectiveValue() const;
double SolvingTime() const;
BString* ToBString();
const char* ToString();
protected:
int32 fCountColumns;

View File

@ -29,6 +29,7 @@ public:
private:
double fCoeff;
Variable* fVar;
bool fUsedInPenaltyFunction; //not set yet
};

View File

@ -7,13 +7,16 @@
#ifndef VARIABLE_H
#define VARIABLE_H
#include <File.h>
#include <SupportDefs.h>
#include <List.h>
namespace LinearProgramming {
class Constraint;
class LinearSpec;
class Summand;
/**
* Contains minimum and maximum values.
@ -23,7 +26,6 @@ class Variable {
public:
int32 Index();
LinearSpec* LS() const;
void SetLS(LinearSpec* value);
double Value() const;
void SetValue(double value);
double Min() const;
@ -31,24 +33,46 @@ public:
double Max() const;
void SetMax(double max);
void SetRange(double min, double max);
//~ string ToString();
const char* Label();
void SetLabel(const char* label);
BString* ToBString();
const char* ToString();
Constraint* IsEqual(Variable* var);
Constraint* IsSmallerOrEqual(Variable* var);
Constraint* IsGreaterorEqual(Variable* var);
Constraint* IsGreaterOrEqual(Variable* var);
Constraint* IsEqual(Variable* var,
double penaltyNeg, double penaltyPos);
Constraint* IsSmallerOrEqual(Variable* var,
double penaltyNeg, double penaltyPos);
Constraint* IsGreaterOrEqual(Variable* var,
double penaltyNeg, double penaltyPos);
bool IsValid();
void Invalidate();
virtual ~Variable();
protected:
Variable(LinearSpec* ls);
~Variable();
private:
LinearSpec* fLS;
BList* fUsingSummands; // All Summands that link to this Variable
double fValue;
double fMin;
double fMax;
char* fLabel;
bool fIsValid;
public:
friend class LinearSpec;
friend class Constraint;
friend class LinearSpec;
friend class Constraint;
friend class Summand;
};

View File

@ -11,6 +11,16 @@
#include "lp_lib.h"
// Toggle debug output
//#define DEBUG_CONSTRAINT
#ifdef DEBUG_CONSTRAINT
# define STRACE(x) debug_printf x
#else
# define STRACE(x) ;
#endif
/**
* Gets the index of the constraint.
*
@ -20,8 +30,10 @@ int32
Constraint::Index()
{
int32 i = fLS->Constraints()->IndexOf(this);
if (i == -1)
printf("Constraint not part of fLS->Constraints().");
if (i == -1) {
STRACE(("Constraint not part of fLS->Constraints()."));
return -1;
}
return i + 1;
}
@ -47,6 +59,9 @@ Constraint::LeftSide()
void
Constraint::SetLeftSide(BList* summands)
{
if (!fIsValid)
return;
fLeftSide = summands;
UpdateLeftSide();
}
@ -55,6 +70,9 @@ Constraint::SetLeftSide(BList* summands)
void
Constraint::UpdateLeftSide()
{
if (!fIsValid)
return;
double coeffs[fLeftSide->CountItems() + 2];
int varIndexes[fLeftSide->CountItems() + 2];
int32 i;
@ -77,7 +95,7 @@ Constraint::UpdateLeftSide()
}
if (!set_rowex(fLS->fLP, this->Index(), i, &coeffs[0], &varIndexes[0]))
printf("Error in set_rowex.");
STRACE(("Error in set_rowex."));
fLS->UpdateObjFunction();
fLS->RemovePresolved();
@ -87,6 +105,9 @@ Constraint::UpdateLeftSide()
void
Constraint::SetLeftSide(double coeff1, Variable* var1)
{
if (!fIsValid)
return;
for (int i=0; i<fLeftSide->CountItems(); i++)
delete (Summand*)fLeftSide->ItemAt(i);
fLeftSide->MakeEmpty();
@ -99,6 +120,9 @@ void
Constraint::SetLeftSide(double coeff1, Variable* var1,
double coeff2, Variable* var2)
{
if (!fIsValid)
return;
for (int i=0; i<fLeftSide->CountItems(); i++)
delete (Summand*)fLeftSide->ItemAt(i);
fLeftSide->MakeEmpty();
@ -113,6 +137,9 @@ Constraint::SetLeftSide(double coeff1, Variable* var1,
double coeff2, Variable* var2,
double coeff3, Variable* var3)
{
if (!fIsValid)
return;
for (int i=0; i<fLeftSide->CountItems(); i++)
delete (Summand*)fLeftSide->ItemAt(i);
fLeftSide->MakeEmpty();
@ -129,6 +156,9 @@ Constraint::SetLeftSide(double coeff1, Variable* var1,
double coeff3, Variable* var3,
double coeff4, Variable* var4)
{
if (!fIsValid)
return;
for (int i=0; i<fLeftSide->CountItems(); i++)
delete (Summand*)fLeftSide->ItemAt(i);
fLeftSide->MakeEmpty();
@ -160,12 +190,15 @@ Constraint::Op()
void
Constraint::SetOp(OperatorType value)
{
if (!fIsValid)
return;
fOp = value;
if (!set_constr_type(fLS->fLP, this->Index(),
((fOp == OperatorType(EQ)) ? EQ
: (fOp == OperatorType(GE)) ? GE
: LE)))
printf("Error in set_constr_type.");
STRACE(("Error in set_constr_type."));
fLS->RemovePresolved();
}
@ -177,7 +210,7 @@ Constraint::SetOp(OperatorType value)
* @return the constant value that is on the right side of the operator
*/
double
Constraint::RightSide()
Constraint::RightSide() const
{
return fRightSide;
}
@ -191,9 +224,12 @@ Constraint::RightSide()
void
Constraint::SetRightSide(double value)
{
if (!fIsValid)
return;
fRightSide = value;
if (!set_rh(fLS->fLP, Index(), fRightSide))
printf("Error in set_rh.");
STRACE(("Error in set_rh."));
fLS->RemovePresolved();
}
@ -205,7 +241,7 @@ Constraint::SetRightSide(double value)
* @return the penalty coefficient
*/
double
Constraint::PenaltyNeg()
Constraint::PenaltyNeg() const
{
if (fDNegObjSummand == NULL)
return INFINITY;
@ -222,6 +258,9 @@ Constraint::PenaltyNeg()
void
Constraint::SetPenaltyNeg(double value)
{
if (!fIsValid)
return;
if (fDNegObjSummand == NULL) {
fDNegObjSummand = new Summand(value, new Variable(fLS));
fLS->ObjFunction()->AddItem(fDNegObjSummand);
@ -244,7 +283,7 @@ Constraint::SetPenaltyNeg(double value)
* @return the penalty coefficient
*/
double
Constraint::PenaltyPos()
Constraint::PenaltyPos() const
{
if (fDPosObjSummand == NULL)
return INFINITY;
@ -261,6 +300,9 @@ Constraint::PenaltyPos()
void
Constraint::SetPenaltyPos(double value)
{
if (!fIsValid)
return;
if (fDPosObjSummand == NULL) {
fDPosObjSummand = new Summand(value, new Variable(fLS));
fLS->ObjFunction()->AddItem(fDPosObjSummand);
@ -277,6 +319,62 @@ Constraint::SetPenaltyPos(double value)
}
const char*
Constraint::Label()
{
return fLabel;
}
void
Constraint::SetLabel(const char* label)
{
fLabel = (char*) malloc(strlen(label) + 1);
strcpy(fLabel, label);
}
void
Constraint::WriteXML(BFile* file)
{
if (file->IsWritable() && fOwner == NULL) {
char buffer[200];
file->Write(buffer, sprintf(buffer, "\t<constraint>\n"));
file->Write(buffer, sprintf(buffer, "\t\t<leftside>\n"));
Summand* summand;
for (int32 i = 0; i < fLeftSide->CountItems(); i++) {
summand = (Summand*)fLeftSide->ItemAt(i);
file->Write(buffer, sprintf(buffer, "\t\t\t<summand>\n"));
file->Write(buffer, sprintf(buffer, "\t\t\t\t<coeff>%f</coeff>\n",
summand->Coeff()));
BString* varStr = summand->Var()->ToBString();
file->Write(buffer, sprintf(buffer, "\t\t\t\t<var>%s</var>\n",
varStr->String()));
delete varStr;
file->Write(buffer, sprintf(buffer, "\t\t\t</summand>\n"));
}
file->Write(buffer, sprintf(buffer, "\t\t</leftside>\n"));
char* op;
if (fOp == OperatorType(EQ))
op = "EQ";
else if (fOp == OperatorType(LE))
op = "LE";
else if (fOp == OperatorType(GE))
op = "GE";
file->Write(buffer, sprintf(buffer, "\t\t<op>%s</op>\n", op));
file->Write(buffer, sprintf(buffer, "\t\t<rightside>%f</rightside>\n", fRightSide));
//~ file->Write(buffer, sprintf(buffer, "\t\t<penaltyneg>%s</penaltyneg>\n", PenaltyNeg()));
//~ file->Write(buffer, sprintf(buffer, "\t\t<penaltypos>%s</penaltypos>\n", PenaltyPos()));
file->Write(buffer, sprintf(buffer, "\t</constraint>\n"));
}
}
/**
* Gets the slack variable for the negative variations.
*
@ -305,17 +403,114 @@ Constraint::DPos() const
}
void
Constraint::SetOwner(void* owner)
{
fOwner = owner;
}
void*
Constraint::Owner() const
{
return fOwner;
}
bool
Constraint::IsValid()
{
return fIsValid;
}
void
Constraint::Invalidate()
{
STRACE(("Constraint::Invalidate() on %d\n", this));
if (!fIsValid)
return;
fIsValid = false;
for (int32 i = 0; i < fLeftSide->CountItems(); i++)
delete (Summand*)fLeftSide->ItemAt(i);
delete fLeftSide;
fLeftSide = NULL;
if (fDNegObjSummand) {
fLS->ObjFunction()->RemoveItem(fDNegObjSummand);
delete fDNegObjSummand->Var();
delete fDNegObjSummand;
fDNegObjSummand = NULL;
}
if (fDPosObjSummand) {
fLS->ObjFunction()->RemoveItem(fDPosObjSummand);
delete fDPosObjSummand->Var();
delete fDPosObjSummand;
fDPosObjSummand = NULL;
}
del_constraint(fLS->fLP, this->Index());
fLS->Constraints()->RemoveItem(this);
}
BString*
Constraint::ToBString()
{
BString* str = new BString();
*str << "Constraint ";
if (fLabel)
*str << fLabel;
*str << "(" << (int32)this << "): ";
if (fIsValid) {
for (int i = 0; i < fLeftSide->CountItems(); i++) {
Summand* s = static_cast<Summand*>(fLeftSide->ItemAt(i));
*str << (float)s->Coeff() << "*";
BString* varString = s->Var()->ToBString();
*str << *varString << " ";
delete varString;
}
*str << ((fOp == OperatorType(EQ)) ? "== "
: (fOp == OperatorType(GE)) ? ">= "
: (fOp == OperatorType(LE)) ? "<= "
: "?? ");
*str << (float)fRightSide;
*str << " PenaltyPos=" << (float)PenaltyPos();
*str << " PenaltyNeg=" << (float)PenaltyNeg();
} else
*str << "invalid";
return str;
}
const char*
Constraint::ToString()
{
BString* str = ToBString();
char* result = (char*) malloc(str->Length() + 1);
str->CopyInto(result, 0, str->Length());
delete str;
return result;
}
/**
* Constructor.
*/
Constraint::Constraint(LinearSpec* ls, BList* summands, OperatorType op,
double rightSide, double penaltyNeg, double penaltyPos)
: fLS(ls),
fLeftSide(summands),
fOp(op),
fRightSide(rightSide),
fOwner(NULL),
fLabel(NULL),
fIsValid(true)
{
fLS = ls;
fLeftSide = summands;
fOp = op;
fRightSide = rightSide;
double coeffs[summands->CountItems() + 2];
int varIndexes[summands->CountItems() + 2];
int32 i;
@ -327,8 +522,8 @@ Constraint::Constraint(LinearSpec* ls, BList* summands, OperatorType op,
if (penaltyNeg != INFINITY
&& fOp != OperatorType(LE)) {
fDNegObjSummand = new Summand(penaltyNeg, new Variable(ls));
ls->fObjFunction->AddItem(fDNegObjSummand);
fDNegObjSummand = new Summand(penaltyNeg, new Variable(fLS));
fLS->fObjFunction->AddItem(fDNegObjSummand);
varIndexes[i] = fDNegObjSummand->Var()->Index();
coeffs[i] = 1.0;
i++;
@ -338,8 +533,8 @@ Constraint::Constraint(LinearSpec* ls, BList* summands, OperatorType op,
if (penaltyPos != INFINITY
&& fOp != OperatorType(GE)) {
fDPosObjSummand = new Summand(penaltyPos, new Variable(ls));
ls->fObjFunction->AddItem(fDPosObjSummand);
fDPosObjSummand = new Summand(penaltyPos, new Variable(fLS));
fLS->fObjFunction->AddItem(fDPosObjSummand);
varIndexes[i] = fDPosObjSummand->Var()->Index();
coeffs[i] = -1.0;
i++;
@ -347,14 +542,14 @@ Constraint::Constraint(LinearSpec* ls, BList* summands, OperatorType op,
else
fDPosObjSummand = NULL;
if (!add_constraintex(ls->fLP, i, &coeffs[0], &varIndexes[0],
if (!add_constraintex(fLS->fLP, i, &coeffs[0], &varIndexes[0],
((fOp == OperatorType(EQ)) ? EQ
: (fOp == OperatorType(GE)) ? GE
: LE), rightSide))
printf("Error in add_constraintex.");
STRACE(("Error in add_constraintex."));
fLS->UpdateObjFunction();
ls->Constraints()->AddItem(this);
fLS->Constraints()->AddItem(this);
}
@ -364,20 +559,6 @@ Constraint::Constraint(LinearSpec* ls, BList* summands, OperatorType op,
*/
Constraint::~Constraint()
{
for (int i=0; i<fLeftSide->CountItems(); i++)
delete (Summand*)fLeftSide->ItemAt(i);
delete fLeftSide;
if (fDNegObjSummand != NULL) {
delete fDNegObjSummand->Var();
delete fDNegObjSummand;
}
if (fDPosObjSummand != NULL) {
delete fDPosObjSummand->Var();
delete fDPosObjSummand;
}
del_constraint(fLS->fLP, Index());
fLS->Constraints()->RemoveItem(this);
Invalidate();
}

View File

@ -12,21 +12,20 @@
* Creates a new specification for a linear programming problem.
*/
LinearSpec::LinearSpec()
: fCountColumns(0),
fLpPresolved(NULL),
fOptimization(MINIMIZE),
fObjFunction(new BList()),
fVariables(new BList()),
fConstraints(new BList()),
fResult(ERROR),
fObjectiveValue(NAN),
fSolvingTime(NAN)
{
fLP = make_lp(0, 0);
if (fLP == NULL)
printf("Couldn't construct a new model.");
set_verbose(fLP, 1);
fObjFunction = new BList();
fVariables = new BList();
fConstraints = new BList();
fCountColumns = 0;
fLpPresolved = NULL;
fOptimization = MINIMIZE;
fResult = ERROR;
fObjectiveValue = NAN;
fSolvingTime = NAN;
}
@ -38,12 +37,11 @@ LinearSpec::LinearSpec()
LinearSpec::~LinearSpec()
{
RemovePresolved();
int i;
for (i=0; i<fConstraints->CountItems(); i++)
for (int32 i=0; i<fConstraints->CountItems(); i++)
delete (Constraint*)fConstraints->ItemAt(i);
for (i=0; i<fObjFunction->CountItems(); i++)
for (int32 i=0; i<fObjFunction->CountItems(); i++)
delete (Summand*)fObjFunction->ItemAt(i);
for (i=0; i<fVariables->CountItems(); i++)
for (int32 i=0; i<fVariables->CountItems(); i++)
delete (Variable*)fVariables->ItemAt(i);
delete_lp(fLP);
}
@ -496,7 +494,7 @@ LinearSpec::Save(char* fname)
/**
* Gets the number of columns.
*
*
* @return the number of columns
*/
int32
@ -595,3 +593,55 @@ LinearSpec::SolvingTime() const
return fSolvingTime;
}
BString*
LinearSpec::ToBString()
{
BString* str = new BString();
*str << "LinearSpec " << (int32)this << ":\n";
for (int i = 0; i < fVariables->CountItems(); i++) {
Variable* variable = static_cast<Variable*>(fVariables->ItemAt(i));
BString* vStr = variable->ToBString();
*str << *vStr << "=" << (float)variable->Value() << " ";
delete vStr;
}
*str << "\n";
for (int i = 0; i < fConstraints->CountItems(); i++) {
Constraint* c = static_cast<Constraint*>(fConstraints->ItemAt(i));
BString* cStr = c->ToBString();
*str << i << ": " << *cStr;
delete cStr;
*str << "\n";
}
*str << "Result=";
if (fResult==-1)
*str << "ERROR";
else if (fResult==0)
*str << "OPTIMAL";
else if (fResult==1)
*str << "SUBOPTIMAL";
else if (fResult==2)
*str << "INFEASIBLE";
else if (fResult==3)
*str << "UNBOUNDED";
else if (fResult==4)
*str << "DEGENERATE";
else if (fResult==5)
*str << "NUMFAILURE";
else
*str << fResult;
*str << " SolvingTime=" << (float)fSolvingTime << "ms";
return str;
}
const char*
LinearSpec::ToString()
{
BString* str = ToBString();
char* result = (char*) malloc(str->Length() + 1);
str->CopyInto(result, 0, str->Length());
delete str;
return result;
}

View File

@ -62,6 +62,7 @@ Summand::SetVar(Variable* var)
*/
Summand::~Summand()
{
fVar->fUsingSummands->RemoveItem(this);
}
@ -72,5 +73,8 @@ Summand::Summand(double coeff, Variable* var)
{
fCoeff = coeff;
fVar = var;
fUsedInPenaltyFunction = false;
fVar->fUsingSummands->AddItem(this);
}

View File

@ -14,6 +14,16 @@
#include <float.h> // for DBL_MAX
// Toggle debug output
//#define DEBUG_VARIABLE
#ifdef DEBUG_VARIABLE
# define STRACE(x) debug_printf x
#else
# define STRACE(x) ;
#endif
/**
* Gets index of the variable.
*
@ -23,8 +33,10 @@ int32
Variable::Index()
{
int32 i = fLS->Variables()->IndexOf(this);
if (i == -1)
if (i == -1) {
printf("Variable not part of fLS->Variables().");
return -1;
}
return i + 1;
}
@ -41,18 +53,6 @@ Variable::LS() const
}
/**
* Sets the current linear specification.
*
* @param value the current linear specification
*/
void
Variable::SetLS(LinearSpec* value)
{
fLS = value;
}
/**
* Gets the value.
*
@ -97,6 +97,9 @@ Variable::Min() const
void
Variable::SetMin(double min)
{
if (!fIsValid)
return;
fMin = min;
set_bounds(fLS->fLP, this->Index(), fMin, fMax);
}
@ -122,6 +125,9 @@ Variable::Max() const
void
Variable::SetMax(double max)
{
if (!fIsValid)
return;
fMax = max;
set_bounds(fLS->fLP, this->Index(), fMin, fMax);
}
@ -136,21 +142,64 @@ Variable::SetMax(double max)
void
Variable::SetRange(double min, double max)
{
if (!fIsValid)
return;
fMin = min;
fMax = max;
set_bounds(fLS->fLP, this->Index(), fMin, fMax);
}
const char*
Variable::Label()
{
return fLabel;
}
void
Variable::SetLabel(const char* label)
{
fLabel = (char*) malloc(strlen(label) + 1);
strcpy(fLabel, label);
}
/**
* Returns index of the variable as String.
* E.g. "Var2"
*
* @return the <code>String</code> index of the variable
*/
//~ string Variable::ToString() {
//~ return "Var" + Index();
//~ }
BString*
Variable::ToBString()
{
BString* str = new BString();
if (fLabel) {
*str << fLabel;
if (!fIsValid)
*str << "(invalid)";
} else {
*str << "Var";
if (!fIsValid)
*str << "(invalid," << (int32)this << ")";
else
*str << Index();
}
return str;
}
const char*
Variable::ToString()
{
BString* str = ToBString();
char* result = (char*) malloc(str->Length() + 1);
str->CopyInto(result, 0, str->Length());
delete str;
return result;
}
/**
@ -162,6 +211,9 @@ Variable::SetRange(double min, double max)
Constraint*
Variable::IsEqual(Variable* var)
{
if (!fIsValid)
return NULL;
return fLS->AddConstraint(1.0, this, -1.0, var, OperatorType(EQ), 0.0);
}
@ -175,6 +227,9 @@ Variable::IsEqual(Variable* var)
Constraint*
Variable::IsSmallerOrEqual(Variable* var)
{
if (!fIsValid)
return NULL;
return fLS->AddConstraint(1.0, this, -1.0, var, OperatorType(LE), 0.0);
}
@ -186,28 +241,111 @@ Variable::IsSmallerOrEqual(Variable* var)
* @return the new constraint
*/
Constraint*
Variable::IsGreaterorEqual(Variable* var)
Variable::IsGreaterOrEqual(Variable* var)
{
if (!fIsValid)
return NULL;
return fLS->AddConstraint(-1.0, var, 1.0, this, OperatorType(GE), 0.0);
}
Constraint*
Variable::IsEqual(Variable* var, double penaltyNeg, double penaltyPos)
{
if (!fIsValid)
return NULL;
return fLS->AddConstraint(1.0, this, -1.0, var, OperatorType(EQ), 0.0,
penaltyNeg, penaltyPos);
}
Constraint*
Variable::IsSmallerOrEqual(Variable* var, double penaltyNeg, double penaltyPos)
{
if (!fIsValid)
return NULL;
return fLS->AddConstraint(1.0, this, -1.0, var, OperatorType(LE), 0.0,
penaltyNeg, penaltyPos);
}
Constraint*
Variable::IsGreaterOrEqual(Variable* var, double penaltyNeg, double penaltyPos)
{
if (!fIsValid)
return NULL;
return fLS->AddConstraint(-1.0, var, 1.0, this, OperatorType(GE), 0.0,
penaltyNeg, penaltyPos);
}
bool
Variable::IsValid()
{
return fIsValid;
}
void
Variable::Invalidate()
{
STRACE(("Variable::Invalidate() on %s\n", ToString()));
if (!fIsValid)
return;
fIsValid = false;
del_column(fLS->fLP, Index());
fLS->Variables()->RemoveItem(this);
// invalidate all constraints that use this variable
BList* markedForInvalidation = new BList();
BList* constraints = fLS->Constraints();
for (int i = 0; i < constraints->CountItems(); i++) {
Constraint* constraint = static_cast<Constraint*>(
constraints->ItemAt(i));
if (!constraint->IsValid())
continue;
BList* summands = constraint->LeftSide();
for (int j = 0; j < summands->CountItems(); j++) {
Summand* summand = static_cast<Summand*>(summands->ItemAt(j));
if (summand->Var() == this) {
markedForInvalidation->AddItem(constraint);
break;
}
}
}
for (int i = 0; i < markedForInvalidation->CountItems(); i++)
static_cast<Constraint*>(markedForInvalidation->ItemAt(i))
->Invalidate();
delete markedForInvalidation;
}
/**
* Constructor.
*/
Variable::Variable(LinearSpec* ls)
: fLS(ls),
fUsingSummands(new BList()),
fValue(NAN),
fMin(0),
fMax(DBL_MAX),
fLabel(NULL),
fIsValid(true)
{
fMin = 0;
fMax = DBL_MAX;
fValue = NULL;
fLS = ls;
fLS->Variables()->AddItem(this);
ls->Variables()->AddItem(this);
if (ls->Variables()->CountItems() > ls->CountColumns()) {
if (fLS->Variables()->CountItems() > fLS->CountColumns()) {
double d = 0;
int i = 0;
if (!add_columnex(ls->fLP, 0, &d, &i))
if (!add_columnex(fLS->fLP, 0, &d, &i))
printf("Error in add_columnex.");
}
}
@ -219,7 +357,8 @@ Variable::Variable(LinearSpec* ls)
*/
Variable::~Variable()
{
del_column(fLS->fLP, this->Index());
fLS->Variables()->RemoveItem(this);
Invalidate();
free(fLabel);
delete fUsingSummands;
}