* 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:
@@ -11,6 +11,7 @@
|
|||||||
#include "Variable.h"
|
#include "Variable.h"
|
||||||
#include "Summand.h"
|
#include "Summand.h"
|
||||||
|
|
||||||
|
#include <File.h>
|
||||||
#include <List.h>
|
#include <List.h>
|
||||||
#include <String.h>
|
#include <String.h>
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
@@ -29,7 +30,7 @@ class Constraint {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
int32 Index();
|
int32 Index();
|
||||||
|
|
||||||
BList* LeftSide();
|
BList* LeftSide();
|
||||||
void SetLeftSide(BList* summands);
|
void SetLeftSide(BList* summands);
|
||||||
void UpdateLeftSide();
|
void UpdateLeftSide();
|
||||||
@@ -46,17 +47,30 @@ public:
|
|||||||
|
|
||||||
OperatorType Op();
|
OperatorType Op();
|
||||||
void SetOp(OperatorType value);
|
void SetOp(OperatorType value);
|
||||||
double RightSide();
|
double RightSide() const;
|
||||||
void SetRightSide(double value);
|
void SetRightSide(double value);
|
||||||
double PenaltyNeg();
|
double PenaltyNeg() const;
|
||||||
void SetPenaltyNeg(double value);
|
void SetPenaltyNeg(double value);
|
||||||
double PenaltyPos();
|
double PenaltyPos() const;
|
||||||
void SetPenaltyPos(double value);
|
void SetPenaltyPos(double value);
|
||||||
|
|
||||||
|
const char* Label();
|
||||||
|
void SetLabel(const char* label);
|
||||||
|
|
||||||
|
void WriteXML(BFile* file);
|
||||||
|
|
||||||
Variable* DNeg() const;
|
Variable* DNeg() const;
|
||||||
Variable* DPos() const;
|
Variable* DPos() const;
|
||||||
|
|
||||||
BString ToString();
|
void SetOwner(void* owner);
|
||||||
|
void* Owner() const;
|
||||||
|
|
||||||
|
bool IsValid();
|
||||||
|
void Invalidate();
|
||||||
|
|
||||||
|
BString* ToBString();
|
||||||
|
const char* ToString();
|
||||||
|
|
||||||
~Constraint();
|
~Constraint();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -71,6 +85,10 @@ private:
|
|||||||
double fRightSide;
|
double fRightSide;
|
||||||
Summand* fDNegObjSummand;
|
Summand* fDNegObjSummand;
|
||||||
Summand* fDPosObjSummand;
|
Summand* fDPosObjSummand;
|
||||||
|
void* fOwner;
|
||||||
|
char* fLabel;
|
||||||
|
|
||||||
|
bool fIsValid;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
friend class LinearSpec;
|
friend class LinearSpec;
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "lp_lib.h"
|
#include "lp_lib.h"
|
||||||
|
|
||||||
#include <List.h>
|
#include <List.h>
|
||||||
|
#include <String.h>
|
||||||
#include <OS.h>
|
#include <OS.h>
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
@@ -37,7 +38,7 @@ class LinearSpec {
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
LinearSpec();
|
LinearSpec();
|
||||||
~LinearSpec();
|
virtual ~LinearSpec();
|
||||||
|
|
||||||
Variable* AddVariable();
|
Variable* AddVariable();
|
||||||
|
|
||||||
@@ -100,6 +101,9 @@ public:
|
|||||||
double ObjectiveValue() const;
|
double ObjectiveValue() const;
|
||||||
double SolvingTime() const;
|
double SolvingTime() const;
|
||||||
|
|
||||||
|
BString* ToBString();
|
||||||
|
const char* ToString();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
int32 fCountColumns;
|
int32 fCountColumns;
|
||||||
|
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
double fCoeff;
|
double fCoeff;
|
||||||
Variable* fVar;
|
Variable* fVar;
|
||||||
|
bool fUsedInPenaltyFunction; //not set yet
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -7,13 +7,16 @@
|
|||||||
#ifndef VARIABLE_H
|
#ifndef VARIABLE_H
|
||||||
#define VARIABLE_H
|
#define VARIABLE_H
|
||||||
|
|
||||||
|
#include <File.h>
|
||||||
#include <SupportDefs.h>
|
#include <SupportDefs.h>
|
||||||
|
#include <List.h>
|
||||||
|
|
||||||
|
|
||||||
namespace LinearProgramming {
|
namespace LinearProgramming {
|
||||||
|
|
||||||
class Constraint;
|
class Constraint;
|
||||||
class LinearSpec;
|
class LinearSpec;
|
||||||
|
class Summand;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Contains minimum and maximum values.
|
* Contains minimum and maximum values.
|
||||||
@@ -23,7 +26,6 @@ class Variable {
|
|||||||
public:
|
public:
|
||||||
int32 Index();
|
int32 Index();
|
||||||
LinearSpec* LS() const;
|
LinearSpec* LS() const;
|
||||||
void SetLS(LinearSpec* value);
|
|
||||||
double Value() const;
|
double Value() const;
|
||||||
void SetValue(double value);
|
void SetValue(double value);
|
||||||
double Min() const;
|
double Min() const;
|
||||||
@@ -31,24 +33,46 @@ public:
|
|||||||
double Max() const;
|
double Max() const;
|
||||||
void SetMax(double max);
|
void SetMax(double max);
|
||||||
void SetRange(double min, 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* IsEqual(Variable* var);
|
||||||
Constraint* IsSmallerOrEqual(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:
|
protected:
|
||||||
Variable(LinearSpec* ls);
|
Variable(LinearSpec* ls);
|
||||||
~Variable();
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
LinearSpec* fLS;
|
LinearSpec* fLS;
|
||||||
|
BList* fUsingSummands; // All Summands that link to this Variable
|
||||||
double fValue;
|
double fValue;
|
||||||
double fMin;
|
double fMin;
|
||||||
double fMax;
|
double fMax;
|
||||||
|
char* fLabel;
|
||||||
|
|
||||||
|
bool fIsValid;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
friend class LinearSpec;
|
friend class LinearSpec;
|
||||||
friend class Constraint;
|
friend class Constraint;
|
||||||
|
friend class Summand;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+216
-35
@@ -11,6 +11,16 @@
|
|||||||
#include "lp_lib.h"
|
#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.
|
* Gets the index of the constraint.
|
||||||
*
|
*
|
||||||
@@ -20,8 +30,10 @@ int32
|
|||||||
Constraint::Index()
|
Constraint::Index()
|
||||||
{
|
{
|
||||||
int32 i = fLS->Constraints()->IndexOf(this);
|
int32 i = fLS->Constraints()->IndexOf(this);
|
||||||
if (i == -1)
|
if (i == -1) {
|
||||||
printf("Constraint not part of fLS->Constraints().");
|
STRACE(("Constraint not part of fLS->Constraints()."));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return i + 1;
|
return i + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,6 +59,9 @@ Constraint::LeftSide()
|
|||||||
void
|
void
|
||||||
Constraint::SetLeftSide(BList* summands)
|
Constraint::SetLeftSide(BList* summands)
|
||||||
{
|
{
|
||||||
|
if (!fIsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
fLeftSide = summands;
|
fLeftSide = summands;
|
||||||
UpdateLeftSide();
|
UpdateLeftSide();
|
||||||
}
|
}
|
||||||
@@ -55,6 +70,9 @@ Constraint::SetLeftSide(BList* summands)
|
|||||||
void
|
void
|
||||||
Constraint::UpdateLeftSide()
|
Constraint::UpdateLeftSide()
|
||||||
{
|
{
|
||||||
|
if (!fIsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
double coeffs[fLeftSide->CountItems() + 2];
|
double coeffs[fLeftSide->CountItems() + 2];
|
||||||
int varIndexes[fLeftSide->CountItems() + 2];
|
int varIndexes[fLeftSide->CountItems() + 2];
|
||||||
int32 i;
|
int32 i;
|
||||||
@@ -77,7 +95,7 @@ Constraint::UpdateLeftSide()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!set_rowex(fLS->fLP, this->Index(), i, &coeffs[0], &varIndexes[0]))
|
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->UpdateObjFunction();
|
||||||
fLS->RemovePresolved();
|
fLS->RemovePresolved();
|
||||||
@@ -87,6 +105,9 @@ Constraint::UpdateLeftSide()
|
|||||||
void
|
void
|
||||||
Constraint::SetLeftSide(double coeff1, Variable* var1)
|
Constraint::SetLeftSide(double coeff1, Variable* var1)
|
||||||
{
|
{
|
||||||
|
if (!fIsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
for (int i=0; i<fLeftSide->CountItems(); i++)
|
for (int i=0; i<fLeftSide->CountItems(); i++)
|
||||||
delete (Summand*)fLeftSide->ItemAt(i);
|
delete (Summand*)fLeftSide->ItemAt(i);
|
||||||
fLeftSide->MakeEmpty();
|
fLeftSide->MakeEmpty();
|
||||||
@@ -99,6 +120,9 @@ void
|
|||||||
Constraint::SetLeftSide(double coeff1, Variable* var1,
|
Constraint::SetLeftSide(double coeff1, Variable* var1,
|
||||||
double coeff2, Variable* var2)
|
double coeff2, Variable* var2)
|
||||||
{
|
{
|
||||||
|
if (!fIsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
for (int i=0; i<fLeftSide->CountItems(); i++)
|
for (int i=0; i<fLeftSide->CountItems(); i++)
|
||||||
delete (Summand*)fLeftSide->ItemAt(i);
|
delete (Summand*)fLeftSide->ItemAt(i);
|
||||||
fLeftSide->MakeEmpty();
|
fLeftSide->MakeEmpty();
|
||||||
@@ -113,6 +137,9 @@ Constraint::SetLeftSide(double coeff1, Variable* var1,
|
|||||||
double coeff2, Variable* var2,
|
double coeff2, Variable* var2,
|
||||||
double coeff3, Variable* var3)
|
double coeff3, Variable* var3)
|
||||||
{
|
{
|
||||||
|
if (!fIsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
for (int i=0; i<fLeftSide->CountItems(); i++)
|
for (int i=0; i<fLeftSide->CountItems(); i++)
|
||||||
delete (Summand*)fLeftSide->ItemAt(i);
|
delete (Summand*)fLeftSide->ItemAt(i);
|
||||||
fLeftSide->MakeEmpty();
|
fLeftSide->MakeEmpty();
|
||||||
@@ -129,6 +156,9 @@ Constraint::SetLeftSide(double coeff1, Variable* var1,
|
|||||||
double coeff3, Variable* var3,
|
double coeff3, Variable* var3,
|
||||||
double coeff4, Variable* var4)
|
double coeff4, Variable* var4)
|
||||||
{
|
{
|
||||||
|
if (!fIsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
for (int i=0; i<fLeftSide->CountItems(); i++)
|
for (int i=0; i<fLeftSide->CountItems(); i++)
|
||||||
delete (Summand*)fLeftSide->ItemAt(i);
|
delete (Summand*)fLeftSide->ItemAt(i);
|
||||||
fLeftSide->MakeEmpty();
|
fLeftSide->MakeEmpty();
|
||||||
@@ -160,12 +190,15 @@ Constraint::Op()
|
|||||||
void
|
void
|
||||||
Constraint::SetOp(OperatorType value)
|
Constraint::SetOp(OperatorType value)
|
||||||
{
|
{
|
||||||
|
if (!fIsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
fOp = value;
|
fOp = value;
|
||||||
if (!set_constr_type(fLS->fLP, this->Index(),
|
if (!set_constr_type(fLS->fLP, this->Index(),
|
||||||
((fOp == OperatorType(EQ)) ? EQ
|
((fOp == OperatorType(EQ)) ? EQ
|
||||||
: (fOp == OperatorType(GE)) ? GE
|
: (fOp == OperatorType(GE)) ? GE
|
||||||
: LE)))
|
: LE)))
|
||||||
printf("Error in set_constr_type.");
|
STRACE(("Error in set_constr_type."));
|
||||||
|
|
||||||
fLS->RemovePresolved();
|
fLS->RemovePresolved();
|
||||||
}
|
}
|
||||||
@@ -177,7 +210,7 @@ Constraint::SetOp(OperatorType value)
|
|||||||
* @return the constant value that is on the right side of the operator
|
* @return the constant value that is on the right side of the operator
|
||||||
*/
|
*/
|
||||||
double
|
double
|
||||||
Constraint::RightSide()
|
Constraint::RightSide() const
|
||||||
{
|
{
|
||||||
return fRightSide;
|
return fRightSide;
|
||||||
}
|
}
|
||||||
@@ -191,9 +224,12 @@ Constraint::RightSide()
|
|||||||
void
|
void
|
||||||
Constraint::SetRightSide(double value)
|
Constraint::SetRightSide(double value)
|
||||||
{
|
{
|
||||||
|
if (!fIsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
fRightSide = value;
|
fRightSide = value;
|
||||||
if (!set_rh(fLS->fLP, Index(), fRightSide))
|
if (!set_rh(fLS->fLP, Index(), fRightSide))
|
||||||
printf("Error in set_rh.");
|
STRACE(("Error in set_rh."));
|
||||||
|
|
||||||
fLS->RemovePresolved();
|
fLS->RemovePresolved();
|
||||||
}
|
}
|
||||||
@@ -205,7 +241,7 @@ Constraint::SetRightSide(double value)
|
|||||||
* @return the penalty coefficient
|
* @return the penalty coefficient
|
||||||
*/
|
*/
|
||||||
double
|
double
|
||||||
Constraint::PenaltyNeg()
|
Constraint::PenaltyNeg() const
|
||||||
{
|
{
|
||||||
if (fDNegObjSummand == NULL)
|
if (fDNegObjSummand == NULL)
|
||||||
return INFINITY;
|
return INFINITY;
|
||||||
@@ -222,6 +258,9 @@ Constraint::PenaltyNeg()
|
|||||||
void
|
void
|
||||||
Constraint::SetPenaltyNeg(double value)
|
Constraint::SetPenaltyNeg(double value)
|
||||||
{
|
{
|
||||||
|
if (!fIsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
if (fDNegObjSummand == NULL) {
|
if (fDNegObjSummand == NULL) {
|
||||||
fDNegObjSummand = new Summand(value, new Variable(fLS));
|
fDNegObjSummand = new Summand(value, new Variable(fLS));
|
||||||
fLS->ObjFunction()->AddItem(fDNegObjSummand);
|
fLS->ObjFunction()->AddItem(fDNegObjSummand);
|
||||||
@@ -244,7 +283,7 @@ Constraint::SetPenaltyNeg(double value)
|
|||||||
* @return the penalty coefficient
|
* @return the penalty coefficient
|
||||||
*/
|
*/
|
||||||
double
|
double
|
||||||
Constraint::PenaltyPos()
|
Constraint::PenaltyPos() const
|
||||||
{
|
{
|
||||||
if (fDPosObjSummand == NULL)
|
if (fDPosObjSummand == NULL)
|
||||||
return INFINITY;
|
return INFINITY;
|
||||||
@@ -261,6 +300,9 @@ Constraint::PenaltyPos()
|
|||||||
void
|
void
|
||||||
Constraint::SetPenaltyPos(double value)
|
Constraint::SetPenaltyPos(double value)
|
||||||
{
|
{
|
||||||
|
if (!fIsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
if (fDPosObjSummand == NULL) {
|
if (fDPosObjSummand == NULL) {
|
||||||
fDPosObjSummand = new Summand(value, new Variable(fLS));
|
fDPosObjSummand = new Summand(value, new Variable(fLS));
|
||||||
fLS->ObjFunction()->AddItem(fDPosObjSummand);
|
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.
|
* 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.
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
Constraint::Constraint(LinearSpec* ls, BList* summands, OperatorType op,
|
Constraint::Constraint(LinearSpec* ls, BList* summands, OperatorType op,
|
||||||
double rightSide, double penaltyNeg, double penaltyPos)
|
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];
|
double coeffs[summands->CountItems() + 2];
|
||||||
int varIndexes[summands->CountItems() + 2];
|
int varIndexes[summands->CountItems() + 2];
|
||||||
int32 i;
|
int32 i;
|
||||||
@@ -327,8 +522,8 @@ Constraint::Constraint(LinearSpec* ls, BList* summands, OperatorType op,
|
|||||||
|
|
||||||
if (penaltyNeg != INFINITY
|
if (penaltyNeg != INFINITY
|
||||||
&& fOp != OperatorType(LE)) {
|
&& fOp != OperatorType(LE)) {
|
||||||
fDNegObjSummand = new Summand(penaltyNeg, new Variable(ls));
|
fDNegObjSummand = new Summand(penaltyNeg, new Variable(fLS));
|
||||||
ls->fObjFunction->AddItem(fDNegObjSummand);
|
fLS->fObjFunction->AddItem(fDNegObjSummand);
|
||||||
varIndexes[i] = fDNegObjSummand->Var()->Index();
|
varIndexes[i] = fDNegObjSummand->Var()->Index();
|
||||||
coeffs[i] = 1.0;
|
coeffs[i] = 1.0;
|
||||||
i++;
|
i++;
|
||||||
@@ -338,8 +533,8 @@ Constraint::Constraint(LinearSpec* ls, BList* summands, OperatorType op,
|
|||||||
|
|
||||||
if (penaltyPos != INFINITY
|
if (penaltyPos != INFINITY
|
||||||
&& fOp != OperatorType(GE)) {
|
&& fOp != OperatorType(GE)) {
|
||||||
fDPosObjSummand = new Summand(penaltyPos, new Variable(ls));
|
fDPosObjSummand = new Summand(penaltyPos, new Variable(fLS));
|
||||||
ls->fObjFunction->AddItem(fDPosObjSummand);
|
fLS->fObjFunction->AddItem(fDPosObjSummand);
|
||||||
varIndexes[i] = fDPosObjSummand->Var()->Index();
|
varIndexes[i] = fDPosObjSummand->Var()->Index();
|
||||||
coeffs[i] = -1.0;
|
coeffs[i] = -1.0;
|
||||||
i++;
|
i++;
|
||||||
@@ -347,14 +542,14 @@ Constraint::Constraint(LinearSpec* ls, BList* summands, OperatorType op,
|
|||||||
else
|
else
|
||||||
fDPosObjSummand = NULL;
|
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(EQ)) ? EQ
|
||||||
: (fOp == OperatorType(GE)) ? GE
|
: (fOp == OperatorType(GE)) ? GE
|
||||||
: LE), rightSide))
|
: LE), rightSide))
|
||||||
printf("Error in add_constraintex.");
|
STRACE(("Error in add_constraintex."));
|
||||||
|
|
||||||
fLS->UpdateObjFunction();
|
fLS->UpdateObjFunction();
|
||||||
ls->Constraints()->AddItem(this);
|
fLS->Constraints()->AddItem(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -364,20 +559,6 @@ Constraint::Constraint(LinearSpec* ls, BList* summands, OperatorType op,
|
|||||||
*/
|
*/
|
||||||
Constraint::~Constraint()
|
Constraint::~Constraint()
|
||||||
{
|
{
|
||||||
for (int i=0; i<fLeftSide->CountItems(); i++)
|
Invalidate();
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,21 +12,20 @@
|
|||||||
* Creates a new specification for a linear programming problem.
|
* Creates a new specification for a linear programming problem.
|
||||||
*/
|
*/
|
||||||
LinearSpec::LinearSpec()
|
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);
|
fLP = make_lp(0, 0);
|
||||||
if (fLP == NULL)
|
if (fLP == NULL)
|
||||||
printf("Couldn't construct a new model.");
|
printf("Couldn't construct a new model.");
|
||||||
set_verbose(fLP, 1);
|
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()
|
LinearSpec::~LinearSpec()
|
||||||
{
|
{
|
||||||
RemovePresolved();
|
RemovePresolved();
|
||||||
int i;
|
for (int32 i=0; i<fConstraints->CountItems(); i++)
|
||||||
for (i=0; i<fConstraints->CountItems(); i++)
|
|
||||||
delete (Constraint*)fConstraints->ItemAt(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);
|
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 (Variable*)fVariables->ItemAt(i);
|
||||||
delete_lp(fLP);
|
delete_lp(fLP);
|
||||||
}
|
}
|
||||||
@@ -496,7 +494,7 @@ LinearSpec::Save(char* fname)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the number of columns.
|
* Gets the number of columns.
|
||||||
*
|
*
|
||||||
* @return the number of columns
|
* @return the number of columns
|
||||||
*/
|
*/
|
||||||
int32
|
int32
|
||||||
@@ -595,3 +593,55 @@ LinearSpec::SolvingTime() const
|
|||||||
return fSolvingTime;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ Summand::SetVar(Variable* var)
|
|||||||
*/
|
*/
|
||||||
Summand::~Summand()
|
Summand::~Summand()
|
||||||
{
|
{
|
||||||
|
fVar->fUsingSummands->RemoveItem(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -72,5 +73,8 @@ Summand::Summand(double coeff, Variable* var)
|
|||||||
{
|
{
|
||||||
fCoeff = coeff;
|
fCoeff = coeff;
|
||||||
fVar = var;
|
fVar = var;
|
||||||
|
fUsedInPenaltyFunction = false;
|
||||||
|
fVar->fUsingSummands->AddItem(this);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+166
-27
@@ -14,6 +14,16 @@
|
|||||||
#include <float.h> // for DBL_MAX
|
#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.
|
* Gets index of the variable.
|
||||||
*
|
*
|
||||||
@@ -23,8 +33,10 @@ int32
|
|||||||
Variable::Index()
|
Variable::Index()
|
||||||
{
|
{
|
||||||
int32 i = fLS->Variables()->IndexOf(this);
|
int32 i = fLS->Variables()->IndexOf(this);
|
||||||
if (i == -1)
|
if (i == -1) {
|
||||||
printf("Variable not part of fLS->Variables().");
|
printf("Variable not part of fLS->Variables().");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
return i + 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.
|
* Gets the value.
|
||||||
*
|
*
|
||||||
@@ -97,6 +97,9 @@ Variable::Min() const
|
|||||||
void
|
void
|
||||||
Variable::SetMin(double min)
|
Variable::SetMin(double min)
|
||||||
{
|
{
|
||||||
|
if (!fIsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
fMin = min;
|
fMin = min;
|
||||||
set_bounds(fLS->fLP, this->Index(), fMin, fMax);
|
set_bounds(fLS->fLP, this->Index(), fMin, fMax);
|
||||||
}
|
}
|
||||||
@@ -122,6 +125,9 @@ Variable::Max() const
|
|||||||
void
|
void
|
||||||
Variable::SetMax(double max)
|
Variable::SetMax(double max)
|
||||||
{
|
{
|
||||||
|
if (!fIsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
fMax = max;
|
fMax = max;
|
||||||
set_bounds(fLS->fLP, this->Index(), fMin, fMax);
|
set_bounds(fLS->fLP, this->Index(), fMin, fMax);
|
||||||
}
|
}
|
||||||
@@ -136,21 +142,64 @@ Variable::SetMax(double max)
|
|||||||
void
|
void
|
||||||
Variable::SetRange(double min, double max)
|
Variable::SetRange(double min, double max)
|
||||||
{
|
{
|
||||||
|
if (!fIsValid)
|
||||||
|
return;
|
||||||
|
|
||||||
fMin = min;
|
fMin = min;
|
||||||
fMax = max;
|
fMax = max;
|
||||||
set_bounds(fLS->fLP, this->Index(), fMin, fMax);
|
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.
|
* Returns index of the variable as String.
|
||||||
* E.g. "Var2"
|
* E.g. "Var2"
|
||||||
*
|
*
|
||||||
* @return the <code>String</code> index of the variable
|
* @return the <code>String</code> index of the variable
|
||||||
*/
|
*/
|
||||||
//~ string Variable::ToString() {
|
BString*
|
||||||
//~ return "Var" + Index();
|
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*
|
Constraint*
|
||||||
Variable::IsEqual(Variable* var)
|
Variable::IsEqual(Variable* var)
|
||||||
{
|
{
|
||||||
|
if (!fIsValid)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
return fLS->AddConstraint(1.0, this, -1.0, var, OperatorType(EQ), 0.0);
|
return fLS->AddConstraint(1.0, this, -1.0, var, OperatorType(EQ), 0.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -175,6 +227,9 @@ Variable::IsEqual(Variable* var)
|
|||||||
Constraint*
|
Constraint*
|
||||||
Variable::IsSmallerOrEqual(Variable* var)
|
Variable::IsSmallerOrEqual(Variable* var)
|
||||||
{
|
{
|
||||||
|
if (!fIsValid)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
return fLS->AddConstraint(1.0, this, -1.0, var, OperatorType(LE), 0.0);
|
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
|
* @return the new constraint
|
||||||
*/
|
*/
|
||||||
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);
|
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.
|
* Constructor.
|
||||||
*/
|
*/
|
||||||
Variable::Variable(LinearSpec* ls)
|
Variable::Variable(LinearSpec* ls)
|
||||||
|
: fLS(ls),
|
||||||
|
fUsingSummands(new BList()),
|
||||||
|
fValue(NAN),
|
||||||
|
fMin(0),
|
||||||
|
fMax(DBL_MAX),
|
||||||
|
fLabel(NULL),
|
||||||
|
fIsValid(true)
|
||||||
{
|
{
|
||||||
fMin = 0;
|
fLS->Variables()->AddItem(this);
|
||||||
fMax = DBL_MAX;
|
|
||||||
fValue = NULL;
|
|
||||||
fLS = ls;
|
|
||||||
|
|
||||||
ls->Variables()->AddItem(this);
|
if (fLS->Variables()->CountItems() > fLS->CountColumns()) {
|
||||||
|
|
||||||
if (ls->Variables()->CountItems() > ls->CountColumns()) {
|
|
||||||
double d = 0;
|
double d = 0;
|
||||||
int i = 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.");
|
printf("Error in add_columnex.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -219,7 +357,8 @@ Variable::Variable(LinearSpec* ls)
|
|||||||
*/
|
*/
|
||||||
Variable::~Variable()
|
Variable::~Variable()
|
||||||
{
|
{
|
||||||
del_column(fLS->fLP, this->Index());
|
Invalidate();
|
||||||
fLS->Variables()->RemoveItem(this);
|
free(fLabel);
|
||||||
|
delete fUsingSummands;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user