ALM/linprog patch by Christof Lutteroth:

* Got rid of class ObjFunctionSummand. Both the constraint summands and
  the objective function summands are now stored using class Summand.
* Some method names are more BeOS compliant now: SetX instead of ChangeX.
* linprog test code now uses new AddConstraint methods.
* CalculateMinSize and CalculateMaxSize did not free the memory they
  allocated.
* Removed inappropriate setter and getter methods.
* Memory allocated in class Constraint is freed now.
* Other small changes.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@24351 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Ingo Weinhold
2008-03-10 21:43:32 +00:00
parent 0bc0282224
commit 5bced18eab
16 changed files with 361 additions and 665 deletions
+15 -10
View File
@@ -32,6 +32,7 @@ class Area {
public: public:
bool AutoPrefContentSize() const; bool AutoPrefContentSize() const;
void SetAutoPrefContentSize(bool value); void SetAutoPrefContentSize(bool value);
XTab* Left() const; XTab* Left() const;
void SetLeft(XTab* left); void SetLeft(XTab* left);
XTab* Right() const; XTab* Right() const;
@@ -40,10 +41,12 @@ public:
void SetTop(YTab* top); void SetTop(YTab* top);
YTab* Bottom() const; YTab* Bottom() const;
void SetBottom(YTab* bottom); void SetBottom(YTab* bottom);
Row* GetRow() const; Row* GetRow() const;
void SetRow(Row* row); void SetRow(Row* row);
Column* GetColumn() const; Column* GetColumn() const;
void SetColumn(Column* column); void SetColumn(Column* column);
BView* Content() const; BView* Content() const;
void SetContent(BView* content); void SetContent(BView* content);
XTab* ContentLeft() const; XTab* ContentLeft() const;
@@ -76,6 +79,7 @@ public:
void SetBottomInset(int32 bottom); void SetBottomInset(int32 bottom);
void SetDefaultPrefContentSize(); void SetDefaultPrefContentSize();
//~ string ToString(); //~ string ToString();
Constraint* HasSameWidthAs(Area* area); Constraint* HasSameWidthAs(Area* area);
Constraint* HasSameHeightAs(Area* area); Constraint* HasSameHeightAs(Area* area);
BList* HasSameSizetAs(Area* area); BList* HasSameSizetAs(Area* area);
@@ -92,18 +96,18 @@ protected:
void DoLayout(); void DoLayout();
private: private:
void InitChildArea(); void InitChildArea();
void UpdateHorizontal(); void UpdateHorizontal();
void UpdateVertical(); void UpdateVertical();
void Init(BALMLayout* ls, XTab* left, YTab* top, void Init(BALMLayout* ls, XTab* left, YTab* top,
XTab* right, YTab* bottom, XTab* right, YTab* bottom,
BView* content, BView* content,
BSize minContentSize); BSize minContentSize);
public: public:
static BSize kMaxSize; static BSize kMaxSize;
static BSize kMinSize; static BSize kMinSize;
static BSize kUndefinedSize; static BSize kUndefinedSize;
protected: protected:
BView* fContent; BView* fContent;
@@ -152,3 +156,4 @@ public:
using BALM::Area; using BALM::Area;
#endif // AREA_H #endif // AREA_H
+19 -21
View File
@@ -33,7 +33,7 @@ class BALMLayout : public BLayout, public LinearSpec {
public: public:
BALMLayout(); BALMLayout();
void SolveLayout(); void SolveLayout();
XTab* AddXTab(); XTab* AddXTab();
YTab* AddYTab(); YTab* AddYTab();
@@ -41,6 +41,7 @@ public:
Row* AddRow(YTab* top, YTab* bottom); Row* AddRow(YTab* top, YTab* bottom);
Column* AddColumn(); Column* AddColumn();
Column* AddColumn(XTab* left, XTab* right); Column* AddColumn(XTab* left, XTab* right);
Area* AddArea(XTab* left, YTab* top, XTab* right, YTab* bottom, Area* AddArea(XTab* left, YTab* top, XTab* right, YTab* bottom,
BView* content, BSize minContentSize); BView* content, BSize minContentSize);
Area* AddArea(Row* row, Column* column, BView* content, Area* AddArea(Row* row, Column* column, BView* content,
@@ -50,40 +51,37 @@ public:
Area* AddArea(Row* row, Column* column, BView* content); Area* AddArea(Row* row, Column* column, BView* content);
Area* AreaOf(BView* control); Area* AreaOf(BView* control);
BList* Areas() const; BList* Areas() const;
void SetAreas(BList* areas);
XTab* Left() const;
void SetLeft(XTab* left);
XTab* Right() const;
void SetRight(XTab* right);
YTab* Top() const;
void SetTop(YTab* top);
YTab* Bottom() const;
void SetBottom(YTab* bottom);
void RecoverLayout(BView* parent);
LayoutStyleType LayoutStyle() const;
void SetLayoutStyle(LayoutStyleType style);
BLayoutItem* AddView(BView* child); XTab* Left() const;
BLayoutItem* AddView(int32 index, BView* child); XTab* Right() const;
YTab* Top() const;
YTab* Bottom() const;
void RecoverLayout(BView* parent);
LayoutStyleType LayoutStyle() const;
void SetLayoutStyle(LayoutStyleType style);
BLayoutItem* AddView(BView* child);
BLayoutItem* AddView(int32 index, BView* child);
bool AddItem(BLayoutItem* item); bool AddItem(BLayoutItem* item);
bool AddItem(int32 index, BLayoutItem* item); bool AddItem(int32 index, BLayoutItem* item);
bool RemoveView(BView* child); bool RemoveView(BView* child);
bool RemoveItem(BLayoutItem* item); bool RemoveItem(BLayoutItem* item);
BLayoutItem* RemoveItem(int32 index); BLayoutItem* RemoveItem(int32 index);
BSize MinSize(); BSize MinSize();
BSize MaxSize(); BSize MaxSize();
BSize PreferredSize(); BSize PreferredSize();
BAlignment Alignment(); BAlignment Alignment();
bool HasHeightForWidth(); bool HasHeightForWidth();
void GetHeightForWidth(float width, float* min, void GetHeightForWidth(float width, float* min,
float* max, float* preferred); float* max, float* preferred);
void InvalidateLayout(); void InvalidateLayout();
void LayoutView(); void LayoutView();
char* PerformancePath() const; char* PerformancePath() const;
void SetPerformancePath(char* path); void SetPerformancePath(char* path);
private: private:
BSize CalculateMinSize(); BSize CalculateMinSize();
+16 -15
View File
@@ -9,7 +9,7 @@
#include "OperatorType.h" #include "OperatorType.h"
#include "Variable.h" #include "Variable.h"
#include "ObjFunctionSummand.h" #include "Summand.h"
#include <List.h> #include <List.h>
#include <String.h> #include <String.h>
@@ -29,18 +29,21 @@ class Constraint {
public: public:
int32 Index(); int32 Index();
BList* Summands();
void ChangeLeftSide(BList* summands); BList* LeftSide();
void ChangeLeftSide(double coeff1, Variable* var1); void SetLeftSide(BList* summands);
void ChangeLeftSide(double coeff1, Variable* var1, void UpdateLeftSide();
void SetLeftSide(double coeff1, Variable* var1);
void SetLeftSide(double coeff1, Variable* var1,
double coeff2, Variable* var2); double coeff2, Variable* var2);
void ChangeLeftSide(double coeff1, Variable* var1, void SetLeftSide(double coeff1, Variable* var1,
double coeff2, Variable* var2, double coeff2, Variable* var2,
double coeff3, Variable* var3); double coeff3, Variable* var3);
void ChangeLeftSide(double coeff1, Variable* var1, void SetLeftSide(double coeff1, Variable* var1,
double coeff2, Variable* var2, double coeff2, Variable* var2,
double coeff3, Variable* var3, double coeff3, Variable* var3,
double coeff4, Variable* var4); double coeff4, Variable* var4);
OperatorType Op(); OperatorType Op();
void SetOp(OperatorType value); void SetOp(OperatorType value);
double RightSide(); double RightSide();
@@ -49,6 +52,7 @@ public:
void SetPenaltyNeg(double value); void SetPenaltyNeg(double value);
double PenaltyPos(); double PenaltyPos();
void SetPenaltyPos(double value); void SetPenaltyPos(double value);
Variable* DNeg() const; Variable* DNeg() const;
Variable* DPos() const; Variable* DPos() const;
@@ -56,21 +60,17 @@ public:
~Constraint(); ~Constraint();
protected: protected:
Constraint(LinearSpec* ls, BList* summands, Constraint(LinearSpec* ls, BList* summands,
OperatorType op, double rightSide, OperatorType op, double rightSide,
double penaltyNeg, double penaltyPos); double penaltyNeg, double penaltyPos);
private: private:
LinearSpec* fLS; LinearSpec* fLS;
BList* fSummands; BList* fLeftSide;
OperatorType fOp; OperatorType fOp;
double fRightSide; double fRightSide;
Variable* fDNeg; Summand* fDNegObjSummand;
Variable* fDPos; Summand* fDPosObjSummand;
ObjFunctionSummand* fDNegSummand;
ObjFunctionSummand* fDPosSummand;
void _UpdateLeftSide();
public: public:
friend class LinearSpec; friend class LinearSpec;
@@ -82,3 +82,4 @@ public:
using LinearProgramming::Constraint; using LinearProgramming::Constraint;
#endif // CONSTRAINT_H #endif // CONSTRAINT_H
+16 -19
View File
@@ -7,6 +7,10 @@
#ifndef LINEAR_SPEC_H #ifndef LINEAR_SPEC_H
#define LINEAR_SPEC_H #define LINEAR_SPEC_H
#include "Variable.h"
#include "Constraint.h"
#include "Summand.h"
#include "PenaltyFunction.h"
#include "OperatorType.h" #include "OperatorType.h"
#include "ResultType.h" #include "ResultType.h"
#include "OptimizationType.h" #include "OptimizationType.h"
@@ -34,9 +38,7 @@ class LinearSpec {
public: public:
LinearSpec(); LinearSpec();
~LinearSpec(); ~LinearSpec();
void UpdateObjFunction();
void SetObjFunction(BList* summands);
ObjFunctionSummand* AddObjFunctionSummand(double coeff, Variable* var);
Variable* AddVariable(); Variable* AddVariable();
Constraint* AddConstraint(BList* summands, Constraint* AddConstraint(BList* summands,
@@ -79,47 +81,42 @@ public:
double penaltyNeg, double penaltyPos); double penaltyNeg, double penaltyPos);
PenaltyFunction* AddPenaltyFunction(Variable* var, BList* xs, BList* gs); PenaltyFunction* AddPenaltyFunction(Variable* var, BList* xs, BList* gs);
void RemovePresolved();
BList* ObjFunction();
void SetObjFunction(BList* summands);
void UpdateObjFunction();
ResultType Presolve(); ResultType Presolve();
void RemovePresolved();
ResultType Solve(); ResultType Solve();
void Save(char* fname); void Save(char* fname);
int32 Columns() const; int32 CountColumns() const;
void SetColumns(int32 value);
OptimizationType Optimization() const; OptimizationType Optimization() const;
void SetOptimization(OptimizationType value); void SetOptimization(OptimizationType value);
lprec* LP() const;
void SetLP(lprec* value);
BList* ObjFunctionSummands() const;
void SetObjFunctionSummands(BList* value);
BList* Variables() const; BList* Variables() const;
void SetVariables(BList* value);
BList* Constraints() const; BList* Constraints() const;
void SetConstraints(BList* value);
ResultType Result() const; ResultType Result() const;
void SetResult(ResultType value);
double ObjectiveValue() const; double ObjectiveValue() const;
void SetObjectiveValue(double value);
double SolvingTime() const; double SolvingTime() const;
void SetSolvingTime(double value);
protected: protected:
int32 fColumns; int32 fCountColumns;
private: private:
lprec* fLpPresolved; lprec* fLpPresolved;
OptimizationType fOptimization; OptimizationType fOptimization;
lprec* fLP; lprec* fLP;
BList* fObjFunctionSummands; BList* fObjFunction;
BList* fVariables; BList* fVariables;
BList* fConstraints; BList* fConstraints;
ResultType fResult; ResultType fResult;
double fObjectiveValue; double fObjectiveValue;
double fSolvingTime; // = Double.Nan double fSolvingTime;
public: public:
friend class ObjFunctionSummand;
friend class Constraint; friend class Constraint;
friend class Variable;
}; };
-43
View File
@@ -1,43 +0,0 @@
/*
* Copyright 2007-2008, Christof Lutteroth, [email protected]
* Copyright 2007-2008, James Kim, [email protected]
* Distributed under the terms of the MIT License.
*/
#ifndef OBJ_FUNCTION_SUMMAND_H
#define OBJ_FUNCTION_SUMMAND_H
#include "Summand.h"
namespace LinearProgramming {
class LinearSpec;
class Variable;
/**
* A summand of the objective function.
*/
class ObjFunctionSummand : public Summand {
public:
void SetCoeff(double coeff);
void SetVar(Variable* var);
~ObjFunctionSummand();
protected:
ObjFunctionSummand(LinearSpec* ls, double coeff, Variable* var);
private:
LinearSpec* fLS;
public:
friend class LinearSpec;
};
} // namespace LinearProgramming
using LinearProgramming::ObjFunctionSummand;
#endif // OBJ_FUNCTION_SUMMAND_H
+4 -3
View File
@@ -26,12 +26,12 @@ protected:
public: public:
~PenaltyFunction(); ~PenaltyFunction();
const Variable* Var() const; const Variable* Var() const;
const BList* Xs() const; const BList* Xs() const;
const BList* Gs() const; const BList* Gs() const;
private: private:
LinearSpec* fLS; LinearSpec* fLS;
Variable* fVar; Variable* fVar;
BList* fXs; // double BList* fXs; // double
BList* fGs; // double BList* fGs; // double
BList* fConstraints; BList* fConstraints;
@@ -47,3 +47,4 @@ public:
using LinearProgramming::PenaltyFunction; using LinearProgramming::PenaltyFunction;
#endif // PENALTY_FUNCTION_H #endif // PENALTY_FUNCTION_H
+1
View File
@@ -37,3 +37,4 @@ private:
using LinearProgramming::Summand; using LinearProgramming::Summand;
#endif // OBJ_FUNCTION_SUMMAND_H #endif // OBJ_FUNCTION_SUMMAND_H
+33 -33
View File
@@ -77,10 +77,10 @@ Area::SetLeft(XTab* left)
fColumn = NULL; fColumn = NULL;
if (fChildArea == NULL) { if (fChildArea == NULL) {
fMinContentWidth->ChangeLeftSide(-1.0, fLeft, 1.0, fRight); fMinContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight);
if (fMaxContentWidth != NULL) if (fMaxContentWidth != NULL)
fMaxContentWidth->ChangeLeftSide(-1.0, fLeft, 1.0, fRight); fMaxContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight);
} else } else
UpdateHorizontal(); UpdateHorizontal();
fLS->InvalidateLayout(); fLS->InvalidateLayout();
@@ -112,10 +112,10 @@ Area::SetRight(XTab* right)
fColumn = NULL; fColumn = NULL;
if (fChildArea == NULL) { if (fChildArea == NULL) {
fMinContentWidth->ChangeLeftSide(-1.0, fLeft, 1.0, fRight); fMinContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight);
if (fMaxContentWidth != NULL) if (fMaxContentWidth != NULL)
fMaxContentWidth->ChangeLeftSide(-1.0, fLeft, 1.0, fRight); fMaxContentWidth->SetLeftSide(-1.0, fLeft, 1.0, fRight);
} else } else
UpdateHorizontal(); UpdateHorizontal();
fLS->InvalidateLayout(); fLS->InvalidateLayout();
@@ -143,10 +143,10 @@ Area::SetTop(YTab* top)
fRow = NULL; fRow = NULL;
if (fChildArea == NULL) { if (fChildArea == NULL) {
fMinContentHeight->ChangeLeftSide(-1.0, fTop, 1.0, fBottom); fMinContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom);
if (fMaxContentHeight != NULL) if (fMaxContentHeight != NULL)
fMaxContentHeight->ChangeLeftSide(-1.0, fTop, 1.0, fBottom); fMaxContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom);
} else } else
UpdateVertical(); UpdateVertical();
fLS->InvalidateLayout(); fLS->InvalidateLayout();
@@ -174,10 +174,10 @@ Area::SetBottom(YTab* bottom)
fRow = NULL; fRow = NULL;
if (fChildArea == NULL) { if (fChildArea == NULL) {
fMinContentHeight->ChangeLeftSide(-1.0, fTop, 1.0, fBottom); fMinContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom);
if (fMaxContentHeight != NULL) if (fMaxContentHeight != NULL)
fMaxContentHeight->ChangeLeftSide(-1.0, fTop, 1.0, fBottom); fMaxContentHeight->SetLeftSide(-1.0, fTop, 1.0, fBottom);
} else } else
UpdateVertical(); UpdateVertical();
fLS->InvalidateLayout(); fLS->InvalidateLayout();
@@ -471,7 +471,7 @@ Area::SetContentAspectRatio(double ratio)
OperatorType(EQ), 0.0); OperatorType(EQ), 0.0);
fConstraints->AddItem(fContentAspectRatioC); fConstraints->AddItem(fContentAspectRatioC);
} else { } else {
fContentAspectRatioC->ChangeLeftSide( fContentAspectRatioC->SetLeftSide(
-1.0, fLeft, 1.0, fRight, ratio, fTop, -ratio, fBottom); -1.0, fLeft, 1.0, fRight, ratio, fTop, -ratio, fBottom);
} }
} else } else
@@ -855,10 +855,10 @@ Area::InitChildArea()
fChildArea->fMaxContentSize = fMaxContentSize; fChildArea->fMaxContentSize = fMaxContentSize;
fChildArea->fMaxContentWidth = fMaxContentWidth; fChildArea->fMaxContentWidth = fMaxContentWidth;
fMaxContentWidth->ChangeLeftSide(-1.0, fChildArea->Left(), 1.0, fChildArea->Right()); fMaxContentWidth->SetLeftSide(-1.0, fChildArea->Left(), 1.0, fChildArea->Right());
fChildArea->fMaxContentHeight = fMaxContentHeight; fChildArea->fMaxContentHeight = fMaxContentHeight;
fMaxContentHeight->ChangeLeftSide(-1.0, fChildArea->Top(), 1.0, fChildArea->Bottom()); fMaxContentHeight->SetLeftSide(-1.0, fChildArea->Top(), 1.0, fChildArea->Bottom());
} }
// if there are preferred content size constraints on this area, // if there are preferred content size constraints on this area,
@@ -870,10 +870,10 @@ Area::InitChildArea()
fChildArea->fExpandRigidity = fExpandRigidity; fChildArea->fExpandRigidity = fExpandRigidity;
fChildArea->fPrefContentWidth = fPrefContentWidth; fChildArea->fPrefContentWidth = fPrefContentWidth;
fPrefContentWidth->ChangeLeftSide(-1.0, fChildArea->Left(), 1.0, fChildArea->Right()); fPrefContentWidth->SetLeftSide(-1.0, fChildArea->Left(), 1.0, fChildArea->Right());
fChildArea->fPrefContentHeight = fPrefContentHeight; fChildArea->fPrefContentHeight = fPrefContentHeight;
fPrefContentHeight->ChangeLeftSide(-1.0, fChildArea->Top(), 1.0, fChildArea->Bottom()); fPrefContentHeight->SetLeftSide(-1.0, fChildArea->Top(), 1.0, fChildArea->Bottom());
} }
} }
@@ -891,43 +891,43 @@ Area::UpdateHorizontal()
// change the constraints leftConstraint and rightConstraint so that the horizontal // change the constraints leftConstraint and rightConstraint so that the horizontal
// alignment and insets of the childArea within this area are as specified by the user // alignment and insets of the childArea within this area are as specified by the user
if (fAlignment.Horizontal() == B_ALIGN_LEFT) { if (fAlignment.Horizontal() == B_ALIGN_LEFT) {
fLeftConstraint->ChangeLeftSide(-1.0, fLeft, 1.0, fChildArea->Left()); fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left());
fLeftConstraint->SetOp(OperatorType(EQ)); fLeftConstraint->SetOp(OperatorType(EQ));
fLeftConstraint->SetRightSide(fLeftInset); fLeftConstraint->SetRightSide(fLeftInset);
fRightConstraint->ChangeLeftSide(-1.0, fChildArea->Right(), 1.0, fRight); fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight);
fRightConstraint->SetOp(OperatorType(GE)); fRightConstraint->SetOp(OperatorType(GE));
fRightConstraint->SetRightSide(fRightInset); fRightConstraint->SetRightSide(fRightInset);
} else if (fAlignment.Horizontal() == B_ALIGN_RIGHT) { } else if (fAlignment.Horizontal() == B_ALIGN_RIGHT) {
fLeftConstraint->ChangeLeftSide(-1.0, fLeft, 1.0, fChildArea->Left()); fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left());
fLeftConstraint->SetOp(OperatorType(GE)); fLeftConstraint->SetOp(OperatorType(GE));
fLeftConstraint->SetRightSide(fLeftInset); fLeftConstraint->SetRightSide(fLeftInset);
fRightConstraint->ChangeLeftSide(-1.0, fChildArea->Right(), 1.0, fRight); fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight);
fRightConstraint->SetOp(OperatorType(EQ)); fRightConstraint->SetOp(OperatorType(EQ));
fRightConstraint->SetRightSide(fRightInset); fRightConstraint->SetRightSide(fRightInset);
} else if (fAlignment.Horizontal() == B_ALIGN_HORIZONTAL_CENTER) { } else if (fAlignment.Horizontal() == B_ALIGN_HORIZONTAL_CENTER) {
fLeftConstraint->ChangeLeftSide(-1.0, fLeft, 1.0, fChildArea->Left()); fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left());
fLeftConstraint->SetOp(OperatorType(GE)); fLeftConstraint->SetOp(OperatorType(GE));
fLeftConstraint->SetRightSide(max(fLeftInset, fRightInset)); fLeftConstraint->SetRightSide(max(fLeftInset, fRightInset));
fRightConstraint->ChangeLeftSide(-1.0, fLeft, 1.0, fChildArea->Left(), 1.0, fChildArea->Right(), -1.0, fRight); fRightConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left(), 1.0, fChildArea->Right(), -1.0, fRight);
fRightConstraint->SetOp(OperatorType(EQ)); fRightConstraint->SetOp(OperatorType(EQ));
fRightConstraint->SetRightSide(0); fRightConstraint->SetRightSide(0);
} else if (fAlignment.Horizontal() == B_ALIGN_USE_FULL_WIDTH) { } else if (fAlignment.Horizontal() == B_ALIGN_USE_FULL_WIDTH) {
fLeftConstraint->ChangeLeftSide(-1.0, fLeft, 1.0, fChildArea->Left()); fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left());
fLeftConstraint->SetOp(OperatorType(EQ)); fLeftConstraint->SetOp(OperatorType(EQ));
fLeftConstraint->SetRightSide(fLeftInset); fLeftConstraint->SetRightSide(fLeftInset);
fRightConstraint->ChangeLeftSide(-1.0, fChildArea->Right(), 1.0, fRight); fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight);
fRightConstraint->SetOp(OperatorType(EQ)); fRightConstraint->SetOp(OperatorType(EQ));
fRightConstraint->SetRightSide(fRightInset); fRightConstraint->SetRightSide(fRightInset);
} else if (fAlignment.Horizontal() == B_ALIGN_HORIZONTAL_UNSET) { } else if (fAlignment.Horizontal() == B_ALIGN_HORIZONTAL_UNSET) {
fLeftConstraint->ChangeLeftSide(-1.0, fLeft, 1.0, fChildArea->Left()); fLeftConstraint->SetLeftSide(-1.0, fLeft, 1.0, fChildArea->Left());
fLeftConstraint->SetOp(OperatorType(GE)); fLeftConstraint->SetOp(OperatorType(GE));
fLeftConstraint->SetRightSide(fLeftInset); fLeftConstraint->SetRightSide(fLeftInset);
fRightConstraint->ChangeLeftSide(-1.0, fChildArea->Right(), 1.0, fRight); fRightConstraint->SetLeftSide(-1.0, fChildArea->Right(), 1.0, fRight);
fRightConstraint->SetOp(OperatorType(GE)); fRightConstraint->SetOp(OperatorType(GE));
fRightConstraint->SetRightSide(fRightInset); fRightConstraint->SetRightSide(fRightInset);
} }
@@ -945,43 +945,43 @@ void Area::UpdateVertical() {
// change the constraints topConstraint and bottomConstraint so that the vertical // change the constraints topConstraint and bottomConstraint so that the vertical
// alignment and insets of the childArea within this area are as specified by the user // alignment and insets of the childArea within this area are as specified by the user
if (fAlignment.Vertical() == B_ALIGN_TOP) { if (fAlignment.Vertical() == B_ALIGN_TOP) {
fTopConstraint->ChangeLeftSide(-1.0, fTop, 1.0, fChildArea->Top()); fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top());
fTopConstraint->SetOp(OperatorType(EQ)); fTopConstraint->SetOp(OperatorType(EQ));
fTopConstraint->SetRightSide(fTopInset); fTopConstraint->SetRightSide(fTopInset);
fBottomConstraint->ChangeLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom); fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom);
fBottomConstraint->SetOp(OperatorType(GE)); fBottomConstraint->SetOp(OperatorType(GE));
fBottomConstraint->SetRightSide(fBottomInset); fBottomConstraint->SetRightSide(fBottomInset);
} else if (fAlignment.Vertical() == B_ALIGN_BOTTOM) { } else if (fAlignment.Vertical() == B_ALIGN_BOTTOM) {
fTopConstraint->ChangeLeftSide(-1.0, fTop, 1.0, fChildArea->Top()); fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top());
fTopConstraint->SetOp(OperatorType(GE)); fTopConstraint->SetOp(OperatorType(GE));
fTopConstraint->SetRightSide(fTopInset); fTopConstraint->SetRightSide(fTopInset);
fBottomConstraint->ChangeLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom); fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom);
fBottomConstraint->SetOp(OperatorType(EQ)); fBottomConstraint->SetOp(OperatorType(EQ));
fBottomConstraint->SetRightSide(fBottomInset); fBottomConstraint->SetRightSide(fBottomInset);
} else if (fAlignment.Vertical() == B_ALIGN_VERTICAL_CENTER) { } else if (fAlignment.Vertical() == B_ALIGN_VERTICAL_CENTER) {
fTopConstraint->ChangeLeftSide(-1.0, fTop, 1.0, fChildArea->Top()); fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top());
fTopConstraint->SetOp(OperatorType(GE)); fTopConstraint->SetOp(OperatorType(GE));
fTopConstraint->SetRightSide(max(fTopInset, fBottomInset)); fTopConstraint->SetRightSide(max(fTopInset, fBottomInset));
fBottomConstraint->ChangeLeftSide(-1.0, fTop, 1.0, fChildArea->Top(), 1.0, fChildArea->Bottom(), -1.0, fBottom); fBottomConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top(), 1.0, fChildArea->Bottom(), -1.0, fBottom);
fBottomConstraint->SetOp(OperatorType(EQ)); fBottomConstraint->SetOp(OperatorType(EQ));
fBottomConstraint->SetRightSide(0); fBottomConstraint->SetRightSide(0);
} else if (fAlignment.Vertical() == B_ALIGN_USE_FULL_HEIGHT) { } else if (fAlignment.Vertical() == B_ALIGN_USE_FULL_HEIGHT) {
fTopConstraint->ChangeLeftSide(-1.0, fTop, 1.0, fChildArea->Top()); fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top());
fTopConstraint->SetOp(OperatorType(EQ)); fTopConstraint->SetOp(OperatorType(EQ));
fTopConstraint->SetRightSide(fTopInset); fTopConstraint->SetRightSide(fTopInset);
fBottomConstraint->ChangeLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom); fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom);
fBottomConstraint->SetOp(OperatorType(EQ)); fBottomConstraint->SetOp(OperatorType(EQ));
fBottomConstraint->SetRightSide(fBottomInset); fBottomConstraint->SetRightSide(fBottomInset);
} else if (fAlignment.Vertical() == B_ALIGN_VERTICAL_UNSET) { } else if (fAlignment.Vertical() == B_ALIGN_VERTICAL_UNSET) {
fTopConstraint->ChangeLeftSide(-1.0, fTop, 1.0, fChildArea->Top()); fTopConstraint->SetLeftSide(-1.0, fTop, 1.0, fChildArea->Top());
fTopConstraint->SetOp(OperatorType(GE)); fTopConstraint->SetOp(OperatorType(GE));
fTopConstraint->SetRightSide(fTopInset); fTopConstraint->SetRightSide(fTopInset);
fBottomConstraint->ChangeLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom); fBottomConstraint->SetLeftSide(-1.0, fChildArea->Bottom(), 1.0, fBottom);
fBottomConstraint->SetOp(OperatorType(GE)); fBottomConstraint->SetOp(OperatorType(GE));
fBottomConstraint->SetRightSide(fBottomInset); fBottomConstraint->SetRightSide(fBottomInset);
} }
+18 -65
View File
@@ -289,18 +289,6 @@ BALMLayout::Areas() const
} }
/**
* Sets the ares.
*
* @param areas the areas
*/
void
BALMLayout::SetAreas(BList* areas)
{
fAreas = areas;
}
/** /**
* Gets the left variable. * Gets the left variable.
*/ */
@@ -311,16 +299,6 @@ BALMLayout::Left() const
} }
/**
* Sets the left variable.
*/
void
BALMLayout::SetLeft(XTab* left)
{
fLeft = left;
}
/** /**
* Gets the right variable. * Gets the right variable.
*/ */
@@ -331,16 +309,6 @@ BALMLayout::Right() const
} }
/**
* Sets the right variable.
*/
void
BALMLayout::SetRight(XTab* right)
{
fRight = right;
}
/** /**
* Gets the top variable. * Gets the top variable.
*/ */
@@ -351,16 +319,6 @@ BALMLayout::Top() const
} }
/**
* Sets the top variable.
*/
void
BALMLayout::SetTop(YTab* top)
{
fTop = top;
}
/** /**
* Gets the bottom variable. * Gets the bottom variable.
*/ */
@@ -371,16 +329,6 @@ BALMLayout::Bottom() const
} }
/**
* Sets the bottom variable.
*/
void
BALMLayout::SetBottom(YTab* bottom)
{
fBottom = bottom;
}
/** /**
* Reverse engineers a GUI and recovers an ALM specification. * Reverse engineers a GUI and recovers an ALM specification.
* @param parent the parent container of the GUI * @param parent the parent container of the GUI
@@ -641,14 +589,17 @@ BALMLayout::SetPerformancePath(char* path)
BSize BSize
BALMLayout::CalculateMinSize() BALMLayout::CalculateMinSize()
{ {
printf("CalculateMinSize"); BList* oldObjFunction = ObjFunction();
BList* buf = ObjFunctionSummands(); BList* newObjFunction = new BList(2);
SetObjFunctionSummands(new BList(2)); newObjFunction->AddItem(new Summand(1.0, fRight));
AddObjFunctionSummand(1.0, fRight); newObjFunction->AddItem(new Summand(1.0, fBottom));
AddObjFunctionSummand(1.0, fBottom); SetObjFunction(newObjFunction);
SolveLayout(); SolveLayout();
SetObjFunctionSummands(buf); SetObjFunction(oldObjFunction);
UpdateObjFunction(); UpdateObjFunction();
delete (Summand*)newObjFunction->ItemAt(0);
delete (Summand*)newObjFunction->ItemAt(1);
delete newObjFunction;
if (Result() == UNBOUNDED) if (Result() == UNBOUNDED)
return Area::kMinSize; return Area::kMinSize;
@@ -667,14 +618,17 @@ BALMLayout::CalculateMinSize()
BSize BSize
BALMLayout::CalculateMaxSize() BALMLayout::CalculateMaxSize()
{ {
printf("CalculateMaxSize"); BList* oldObjFunction = ObjFunction();
BList* buf = ObjFunctionSummands(); BList* newObjFunction = new BList(2);
SetObjFunctionSummands(new BList(2)); newObjFunction->AddItem(new Summand(-1.0, fRight));
AddObjFunctionSummand(-1.0, fRight); newObjFunction->AddItem(new Summand(-1.0, fBottom));
AddObjFunctionSummand(-1.0, fBottom); SetObjFunction(newObjFunction);
SolveLayout(); SolveLayout();
SetObjFunctionSummands(buf); SetObjFunction(oldObjFunction);
UpdateObjFunction(); UpdateObjFunction();
delete (Summand*)newObjFunction->ItemAt(0);
delete (Summand*)newObjFunction->ItemAt(1);
delete newObjFunction;
if (Result() == UNBOUNDED) if (Result() == UNBOUNDED)
return Area::kMaxSize; return Area::kMaxSize;
@@ -693,7 +647,6 @@ BALMLayout::CalculateMaxSize()
BSize BSize
BALMLayout::CalculatePreferredSize() BALMLayout::CalculatePreferredSize()
{ {
printf("CalculatePreferredSize");
SolveLayout(); SolveLayout();
if (Result() != OPTIMAL) { if (Result() != OPTIMAL) {
Save("failed-layout.txt"); Save("failed-layout.txt");
+120 -100
View File
@@ -27,107 +27,116 @@ Constraint::Index()
/** /**
* Gets the summands of the constraint. * Gets the left side of the constraint.
* *
* @return pointer to a BList containing the summands of the constraint * @return pointer to a BList containing the summands on the left side of the constraint
*/ */
BList* BList*
Constraint::Summands() Constraint::LeftSide()
{ {
return fSummands; return fLeftSide;
}
void
Constraint::_UpdateLeftSide()
{
double coeffs[fSummands->CountItems() + 2];
int varIndexes[fSummands->CountItems() + 2];
int32 i;
for (i = 0; i < fSummands->CountItems(); i++) {
Summand* s = (Summand*)fSummands->ItemAt(i);
coeffs[i] = s->Coeff();
varIndexes[i] = s->Var()->Index();
}
if (fDNegSummand != NULL && fOp != OperatorType(LE)) {
varIndexes[i] = fDNegSummand->Var()->Index();
coeffs[i] = 1.0;
i++;
}
if (fDPosSummand != NULL && fOp != OperatorType(GE)) {
varIndexes[i] = fDPosSummand->Var()->Index();
coeffs[i] = -1.0;
i++;
}
if (!set_rowex(fLS->LP(), this->Index(), i, &coeffs[0], &varIndexes[0]))
printf("Error in set_rowex.");
fLS->RemovePresolved();
} }
/** /**
* Changes the left side of the constraint, i.e.&nbsp;its coefficients and variables. * Sets the summands on the left side of the constraint.
* There must be exactly one coefficient for each variable. * The old summands are NOT deleted.
* *
* @param summands a BList containing the Summand objects that make up the new left side * @param summands a BList containing the Summand objects that make up the new left side
*/ */
void void
Constraint::ChangeLeftSide(BList* summands) Constraint::SetLeftSide(BList* summands)
{ {
fSummands = summands; fLeftSide = summands;
_UpdateLeftSide(); UpdateLeftSide();
} }
void void
Constraint::ChangeLeftSide(double coeff1, Variable* var1) Constraint::UpdateLeftSide()
{ {
fSummands->MakeEmpty(); double coeffs[fLeftSide->CountItems() + 2];
fSummands->AddItem(new Summand(coeff1, var1)); int varIndexes[fLeftSide->CountItems() + 2];
_UpdateLeftSide(); int32 i;
for (i = 0; i < fLeftSide->CountItems(); i++) {
Summand* s = (Summand*)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]))
printf("Error in set_rowex.");
fLS->UpdateObjFunction();
fLS->RemovePresolved();
} }
void void
Constraint::ChangeLeftSide(double coeff1, Variable* var1, Constraint::SetLeftSide(double coeff1, Variable* var1)
{
for (int i=0; i<fLeftSide->CountItems(); i++)
delete (Summand*)fLeftSide->ItemAt(i);
fLeftSide->MakeEmpty();
fLeftSide->AddItem(new Summand(coeff1, var1));
UpdateLeftSide();
}
void
Constraint::SetLeftSide(double coeff1, Variable* var1,
double coeff2, Variable* var2) double coeff2, Variable* var2)
{ {
fSummands->MakeEmpty(); for (int i=0; i<fLeftSide->CountItems(); i++)
fSummands->AddItem(new Summand(coeff1, var1)); delete (Summand*)fLeftSide->ItemAt(i);
fSummands->AddItem(new Summand(coeff2, var2)); fLeftSide->MakeEmpty();
_UpdateLeftSide(); fLeftSide->AddItem(new Summand(coeff1, var1));
fLeftSide->AddItem(new Summand(coeff2, var2));
UpdateLeftSide();
} }
void void
Constraint::ChangeLeftSide(double coeff1, Variable* var1, Constraint::SetLeftSide(double coeff1, Variable* var1,
double coeff2, Variable* var2, double coeff2, Variable* var2,
double coeff3, Variable* var3) double coeff3, Variable* var3)
{ {
fSummands->MakeEmpty(); for (int i=0; i<fLeftSide->CountItems(); i++)
fSummands->AddItem(new Summand(coeff1, var1)); delete (Summand*)fLeftSide->ItemAt(i);
fSummands->AddItem(new Summand(coeff2, var2)); fLeftSide->MakeEmpty();
fSummands->AddItem(new Summand(coeff3, var3)); fLeftSide->AddItem(new Summand(coeff1, var1));
_UpdateLeftSide(); fLeftSide->AddItem(new Summand(coeff2, var2));
fLeftSide->AddItem(new Summand(coeff3, var3));
UpdateLeftSide();
} }
void void
Constraint::ChangeLeftSide(double coeff1, Variable* var1, Constraint::SetLeftSide(double coeff1, Variable* var1,
double coeff2, Variable* var2, double coeff2, Variable* var2,
double coeff3, Variable* var3, double coeff3, Variable* var3,
double coeff4, Variable* var4) double coeff4, Variable* var4)
{ {
fSummands->MakeEmpty(); for (int i=0; i<fLeftSide->CountItems(); i++)
fSummands->AddItem(new Summand(coeff1, var1)); delete (Summand*)fLeftSide->ItemAt(i);
fSummands->AddItem(new Summand(coeff2, var2)); fLeftSide->MakeEmpty();
fSummands->AddItem(new Summand(coeff3, var3)); fLeftSide->AddItem(new Summand(coeff1, var1));
fSummands->AddItem(new Summand(coeff4, var4)); fLeftSide->AddItem(new Summand(coeff2, var2));
_UpdateLeftSide(); fLeftSide->AddItem(new Summand(coeff3, var3));
fLeftSide->AddItem(new Summand(coeff4, var4));
UpdateLeftSide();
} }
@@ -152,7 +161,7 @@ void
Constraint::SetOp(OperatorType value) Constraint::SetOp(OperatorType value)
{ {
fOp = value; fOp = value;
if (!set_constr_type(fLS->LP(), 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)))
@@ -183,7 +192,7 @@ void
Constraint::SetRightSide(double value) Constraint::SetRightSide(double value)
{ {
fRightSide = value; fRightSide = value;
if (!set_rh(fLS->LP(), Index(), fRightSide)) if (!set_rh(fLS->fLP, Index(), fRightSide))
printf("Error in set_rh."); printf("Error in set_rh.");
fLS->RemovePresolved(); fLS->RemovePresolved();
@@ -198,9 +207,9 @@ Constraint::SetRightSide(double value)
double double
Constraint::PenaltyNeg() Constraint::PenaltyNeg()
{ {
if (fDNegSummand == NULL) if (fDNegObjSummand == NULL)
return INFINITY; return INFINITY;
return fDNegSummand->Coeff(); return fDNegObjSummand->Coeff();
} }
@@ -213,16 +222,18 @@ Constraint::PenaltyNeg()
void void
Constraint::SetPenaltyNeg(double value) Constraint::SetPenaltyNeg(double value)
{ {
if (fDNegSummand == NULL) { if (fDNegObjSummand == NULL) {
fDNegSummand = fLS->AddObjFunctionSummand(value, new Variable(fLS)); fDNegObjSummand = new Summand(value, new Variable(fLS));
ChangeLeftSide(fSummands); fLS->ObjFunction()->AddItem(fDNegObjSummand);
UpdateLeftSide();
fLS->UpdateObjFunction(); fLS->UpdateObjFunction();
return; return;
} }
if (value == fDNegSummand->Coeff()) if (value == fDNegObjSummand->Coeff())
return; return;
fDNegSummand->SetCoeff(value);
fDNegObjSummand->SetCoeff(value);
fLS->UpdateObjFunction(); fLS->UpdateObjFunction();
} }
@@ -235,9 +246,9 @@ Constraint::SetPenaltyNeg(double value)
double double
Constraint::PenaltyPos() Constraint::PenaltyPos()
{ {
if (fDPosSummand == NULL) if (fDPosObjSummand == NULL)
return INFINITY; return INFINITY;
return fDPosSummand->Coeff(); return fDPosObjSummand->Coeff();
} }
@@ -250,16 +261,18 @@ Constraint::PenaltyPos()
void void
Constraint::SetPenaltyPos(double value) Constraint::SetPenaltyPos(double value)
{ {
if (fDPosSummand == NULL) { if (fDPosObjSummand == NULL) {
fDPosSummand = fLS->AddObjFunctionSummand(value, new Variable(fLS)); fDPosObjSummand = new Summand(value, new Variable(fLS));
ChangeLeftSide(fSummands); fLS->ObjFunction()->AddItem(fDPosObjSummand);
UpdateLeftSide();
fLS->UpdateObjFunction(); fLS->UpdateObjFunction();
return; return;
} }
if (value == fDPosSummand->Coeff()) if (value == fDPosObjSummand->Coeff())
return; return;
fDPosSummand->SetCoeff(value);
fDPosObjSummand->SetCoeff(value);
fLS->UpdateObjFunction(); fLS->UpdateObjFunction();
} }
@@ -272,9 +285,9 @@ Constraint::SetPenaltyPos(double value)
Variable* Variable*
Constraint::DNeg() const Constraint::DNeg() const
{ {
if (fDNegSummand == NULL) if (fDNegObjSummand == NULL)
return NULL; return NULL;
return fDNegSummand->Var(); return fDNegObjSummand->Var();
} }
@@ -286,9 +299,9 @@ Constraint::DNeg() const
Variable* Variable*
Constraint::DPos() const Constraint::DPos() const
{ {
if (fDPosSummand == NULL) if (fDPosObjSummand == NULL)
return NULL; return NULL;
return fDPosSummand->Var(); return fDPosObjSummand->Var();
} }
@@ -299,7 +312,7 @@ Constraint::Constraint(LinearSpec* ls, BList* summands, OperatorType op,
double rightSide, double penaltyNeg, double penaltyPos) double rightSide, double penaltyNeg, double penaltyPos)
{ {
fLS = ls; fLS = ls;
fSummands = summands; fLeftSide = summands;
fOp = op; fOp = op;
fRightSide = rightSide; fRightSide = rightSide;
@@ -314,50 +327,57 @@ Constraint::Constraint(LinearSpec* ls, BList* summands, OperatorType op,
if (penaltyNeg != INFINITY if (penaltyNeg != INFINITY
&& fOp != OperatorType(LE)) { && fOp != OperatorType(LE)) {
fDNegSummand = ls->AddObjFunctionSummand(penaltyNeg, new Variable(ls)); fDNegObjSummand = new Summand(penaltyNeg, new Variable(ls));
varIndexes[i] = fDNegSummand->Var()->Index(); ls->fObjFunction->AddItem(fDNegObjSummand);
varIndexes[i] = fDNegObjSummand->Var()->Index();
coeffs[i] = 1.0; coeffs[i] = 1.0;
i++; i++;
} }
else else
fDNegSummand = NULL; fDNegObjSummand = NULL;
if (penaltyPos != INFINITY if (penaltyPos != INFINITY
&& fOp != OperatorType(GE)) { && fOp != OperatorType(GE)) {
fDPosSummand = ls->AddObjFunctionSummand(penaltyPos, new Variable(ls)); fDPosObjSummand = new Summand(penaltyPos, new Variable(ls));
varIndexes[i] = fDPosSummand->Var()->Index(); ls->fObjFunction->AddItem(fDPosObjSummand);
varIndexes[i] = fDPosObjSummand->Var()->Index();
coeffs[i] = -1.0; coeffs[i] = -1.0;
i++; i++;
} }
else else
fDPosSummand = NULL; fDPosObjSummand = NULL;
if (!add_constraintex(ls->LP(), i, &coeffs[0], &varIndexes[0], if (!add_constraintex(ls->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."); printf("Error in add_constraintex.");
fLS->UpdateObjFunction();
ls->Constraints()->AddItem(this); ls->Constraints()->AddItem(this);
} }
/** /**
* Destructor. * Destructor.
* Removes the constraint from its specification. * Removes the constraint from its specification and deletes all the summands.
*/ */
Constraint::~Constraint() Constraint::~Constraint()
{ {
del_constraint(fLS->LP(), Index()); for (int i=0; i<fLeftSide->CountItems(); i++)
delete fSummands; delete (Summand*)fLeftSide->ItemAt(i);
if(fDNegSummand != NULL) { delete fLeftSide;
delete fDNegSummand->Var();
delete fDNegSummand; if (fDNegObjSummand != NULL) {
delete fDNegObjSummand->Var();
delete fDNegObjSummand;
} }
if(fDPosSummand != NULL) { if (fDPosObjSummand != NULL) {
delete fDPosSummand->Var(); delete fDPosObjSummand->Var();
delete fDPosSummand; delete fDPosObjSummand;
} }
del_constraint(fLS->fLP, Index());
fLS->Constraints()->RemoveItem(this); fLS->Constraints()->RemoveItem(this);
} }
-1
View File
@@ -8,7 +8,6 @@ SharedLibrary liblinprog.so :
Constraint.cpp Constraint.cpp
LinearSpec.cpp LinearSpec.cpp
Summand.cpp Summand.cpp
ObjFunctionSummand.cpp
PenaltyFunction.cpp PenaltyFunction.cpp
Variable.cpp Variable.cpp
: :
+95 -214
View File
@@ -5,13 +5,6 @@
*/ */
#include "LinearSpec.h" #include "LinearSpec.h"
#include "Constraint.h"
#include "ObjFunctionSummand.h"
#include "PenaltyFunction.h"
#include "Constraint.h"
#include "Variable.h"
#include "lp_lib.h"
/** /**
@@ -25,78 +18,34 @@ LinearSpec::LinearSpec()
printf("Couldn't construct a new model."); printf("Couldn't construct a new model.");
set_verbose(fLP, 1); set_verbose(fLP, 1);
fObjFunctionSummands = new BList(1); fObjFunction = new BList();
fVariables = new BList(1); fVariables = new BList();
fConstraints = new BList(1); fConstraints = new BList();
fColumns = 0; fCountColumns = 0;
fLpPresolved = NULL; fLpPresolved = NULL;
fOptimization = MINIMIZE; fOptimization = MINIMIZE;
fResult = ERROR; fResult = ERROR;
fObjectiveValue = NULL; fObjectiveValue = NAN;
fSolvingTime = NAN;
} }
/** /**
* Destructor. * Destructor.
* Removes the specification. * Removes the specification and deletes all constraints,
* objective function summands and variables.
*/ */
LinearSpec::~LinearSpec() LinearSpec::~LinearSpec()
{ {
delete_lp(fLP);
}
/**
* Updates the objective function.
*/
void
LinearSpec::UpdateObjFunction()
{
int32 size = fObjFunctionSummands->CountItems();
double coeffs[size];
int varIndexes[size];
ObjFunctionSummand* current;
for (int32 i = 0; i < size; i++) {
current = (ObjFunctionSummand*)fObjFunctionSummands->ItemAt(i);
coeffs[i] = current->Coeff();
varIndexes[i] = current->Var()->Index();
}
if (!set_obj_fnex(fLP, size, &coeffs[0], &varIndexes[0]))
printf("Error in set_obj_fnex.");
RemovePresolved(); RemovePresolved();
} int i;
for (i=0; i<fConstraints->CountItems(); i++)
delete (Constraint*)fConstraints->ItemAt(i);
/** for (i=0; i<fObjFunction->CountItems(); i++)
* Sets the objective function. delete (Summand*)fObjFunction->ItemAt(i);
* for (i=0; i<fVariables->CountItems(); i++)
* @param coeffs the objective function's coefficients delete (Variable*)fVariables->ItemAt(i);
* @param vars the objective function's variables delete_lp(fLP);
*/
void
LinearSpec::SetObjFunction(BList* summands)
{
fObjFunctionSummands = summands;
UpdateObjFunction();
}
/**
* Adds a new summand to the objective function.
*
* @param coeff the summand's coefficient
* @param var the summand's variable
* @return the new summand
*/
ObjFunctionSummand*
LinearSpec::AddObjFunctionSummand(double coeff, Variable* var)
{
ObjFunctionSummand* s = new ObjFunctionSummand(this, coeff, var);
fObjFunctionSummands->AddItem(s);
UpdateObjFunction();
return s;
} }
@@ -116,7 +65,7 @@ LinearSpec::AddVariable()
* Adds a new hard linear constraint to the specification. * Adds a new hard linear constraint to the specification.
* *
* @param coeffs the constraint's coefficients * @param coeffs the constraint's coefficients
* @param vars the constraint's variables * @param vars the constraint's variables
* @param op the constraint's operand * @param op the constraint's operand
* @param rightSide the constant value on the constraint's right side * @param rightSide the constant value on the constraint's right side
* @return the new constraint * @return the new constraint
@@ -135,7 +84,7 @@ LinearSpec::AddConstraint(BList* summands, OperatorType op, double rightSide)
* Adds a new hard linear constraint to the specification with a single summand. * Adds a new hard linear constraint to the specification with a single summand.
* *
* @param coeff1 the constraint's first coefficient * @param coeff1 the constraint's first coefficient
* @param var1 the constraint's first variable * @param var1 the constraint's first variable
* @param op the constraint's operand * @param op the constraint's operand
* @param rightSide the constant value on the constraint's right side * @param rightSide the constant value on the constraint's right side
* @return the new constraint * @return the new constraint
@@ -157,9 +106,9 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
* Adds a new hard linear constraint to the specification with two summands. * Adds a new hard linear constraint to the specification with two summands.
* *
* @param coeff1 the constraint's first coefficient * @param coeff1 the constraint's first coefficient
* @param var1 the constraint's first variable * @param var1 the constraint's first variable
* @param coeff2 the constraint's second coefficient * @param coeff2 the constraint's second coefficient
* @param var2 the constraint's second variable * @param var2 the constraint's second variable
* @param op the constraint's operand * @param op the constraint's operand
* @param rightSide the constant value on the constraint's right side * @param rightSide the constant value on the constraint's right side
* @return the new constraint * @return the new constraint
@@ -182,11 +131,11 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
* Adds a new hard linear constraint to the specification with three summands. * Adds a new hard linear constraint to the specification with three summands.
* *
* @param coeff1 the constraint's first coefficient * @param coeff1 the constraint's first coefficient
* @param var1 the constraint's first variable * @param var1 the constraint's first variable
* @param coeff2 the constraint's second coefficient * @param coeff2 the constraint's second coefficient
* @param var2 the constraint's second variable * @param var2 the constraint's second variable
* @param coeff3 the constraint's third coefficient * @param coeff3 the constraint's third coefficient
* @param var3 the constraint's third variable * @param var3 the constraint's third variable
* @param op the constraint's operand * @param op the constraint's operand
* @param rightSide the constant value on the constraint's right side * @param rightSide the constant value on the constraint's right side
* @return the new constraint * @return the new constraint
@@ -211,13 +160,13 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
* Adds a new hard linear constraint to the specification with four summands. * Adds a new hard linear constraint to the specification with four summands.
* *
* @param coeff1 the constraint's first coefficient * @param coeff1 the constraint's first coefficient
* @param var1 the constraint's first variable * @param var1 the constraint's first variable
* @param coeff2 the constraint's second coefficient * @param coeff2 the constraint's second coefficient
* @param var2 the constraint's second variable * @param var2 the constraint's second variable
* @param coeff3 the constraint's third coefficient * @param coeff3 the constraint's third coefficient
* @param var3 the constraint's third variable * @param var3 the constraint's third variable
* @param coeff4 the constraint's fourth coefficient * @param coeff4 the constraint's fourth coefficient
* @param var4 the constraint's fourth variable * @param var4 the constraint's fourth variable
* @param op the constraint's operand * @param op the constraint's operand
* @param rightSide the constant value on the constraint's right side * @param rightSide the constant value on the constraint's right side
* @return the new constraint * @return the new constraint
@@ -244,9 +193,9 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
* i.e. a constraint that does not always have to be satisfied. * i.e. a constraint that does not always have to be satisfied.
* *
* @param coeffs the constraint's coefficients * @param coeffs the constraint's coefficients
* @param vars the constraint's variables * @param vars the constraint's variables
* @param op the constraint's operand * @param op the constraint's operand
* @param rightSide the constant value on the constraint's right side * @param rightSide the constant value on the constraint's right side
* @param penaltyNeg the coefficient penalizing negative deviations from the exact solution * @param penaltyNeg the coefficient penalizing negative deviations from the exact solution
* @param penaltyPos the coefficient penalizing positive deviations from the exact solution * @param penaltyPos the coefficient penalizing positive deviations from the exact solution
*/ */
@@ -265,9 +214,9 @@ LinearSpec::AddConstraint(BList* summands, OperatorType op,
* Adds a new soft linear constraint to the specification with a single summand. * Adds a new soft linear constraint to the specification with a single summand.
* *
* @param coeff1 the constraint's first coefficient * @param coeff1 the constraint's first coefficient
* @param var1 the constraint's first variable * @param var1 the constraint's first variable
* @param op the constraint's operand * @param op the constraint's operand
* @param rightSide the constant value on the constraint's right side * @param rightSide the constant value on the constraint's right side
* @param penaltyNeg the coefficient penalizing negative deviations from the exact solution * @param penaltyNeg the coefficient penalizing negative deviations from the exact solution
* @param penaltyPos the coefficient penalizing positive deviations from the exact solution * @param penaltyPos the coefficient penalizing positive deviations from the exact solution
*/ */
@@ -288,11 +237,11 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
* Adds a new soft linear constraint to the specification with two summands. * Adds a new soft linear constraint to the specification with two summands.
* *
* @param coeff1 the constraint's first coefficient * @param coeff1 the constraint's first coefficient
* @param var1 the constraint's first variable * @param var1 the constraint's first variable
* @param coeff2 the constraint's second coefficient * @param coeff2 the constraint's second coefficient
* @param var2 the constraint's second variable * @param var2 the constraint's second variable
* @param op the constraint's operand * @param op the constraint's operand
* @param rightSide the constant value on the constraint's right side * @param rightSide the constant value on the constraint's right side
* @param penaltyNeg the coefficient penalizing negative deviations from the exact solution * @param penaltyNeg the coefficient penalizing negative deviations from the exact solution
* @param penaltyPos the coefficient penalizing positive deviations from the exact solution * @param penaltyPos the coefficient penalizing positive deviations from the exact solution
*/ */
@@ -315,13 +264,13 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
* Adds a new soft linear constraint to the specification with three summands. * Adds a new soft linear constraint to the specification with three summands.
* *
* @param coeff1 the constraint's first coefficient * @param coeff1 the constraint's first coefficient
* @param var1 the constraint's first variable * @param var1 the constraint's first variable
* @param coeff2 the constraint's second coefficient * @param coeff2 the constraint's second coefficient
* @param var2 the constraint's second variable * @param var2 the constraint's second variable
* @param coeff3 the constraint's third coefficient * @param coeff3 the constraint's third coefficient
* @param var3 the constraint's third variable * @param var3 the constraint's third variable
* @param op the constraint's operand * @param op the constraint's operand
* @param rightSide the constant value on the constraint's right side * @param rightSide the constant value on the constraint's right side
* @param penaltyNeg the coefficient penalizing negative deviations from the exact solution * @param penaltyNeg the coefficient penalizing negative deviations from the exact solution
* @param penaltyPos the coefficient penalizing positive deviations from the exact solution * @param penaltyPos the coefficient penalizing positive deviations from the exact solution
*/ */
@@ -345,15 +294,15 @@ LinearSpec::AddConstraint(double coeff1, Variable* var1,
* Adds a new soft linear constraint to the specification with four summands. * Adds a new soft linear constraint to the specification with four summands.
* *
* @param coeff1 the constraint's first coefficient * @param coeff1 the constraint's first coefficient
* @param var1 the constraint's first variable * @param var1 the constraint's first variable
* @param coeff2 the constraint's second coefficient * @param coeff2 the constraint's second coefficient
* @param var2 the constraint's second variable * @param var2 the constraint's second variable
* @param coeff3 the constraint's third coefficient * @param coeff3 the constraint's third coefficient
* @param var3 the constraint's third variable * @param var3 the constraint's third variable
* @param coeff4 the constraint's fourth coefficient * @param coeff4 the constraint's fourth coefficient
* @param var4 the constraint's fourth variable * @param var4 the constraint's fourth variable
* @param op the constraint's operand * @param op the constraint's operand
* @param rightSide the constant value on the constraint's right side * @param rightSide the constant value on the constraint's right side
* @param penaltyNeg the coefficient penalizing negative deviations from the exact solution * @param penaltyNeg the coefficient penalizing negative deviations from the exact solution
* @param penaltyPos the coefficient penalizing positive deviations from the exact solution * @param penaltyPos the coefficient penalizing positive deviations from the exact solution
*/ */
@@ -390,6 +339,56 @@ LinearSpec::AddPenaltyFunction(Variable* var, BList* xs, BList* gs)
} }
/**
* Gets the objective function.
*
* @return BList containing the objective function's summands
*/
BList*
LinearSpec::ObjFunction()
{
return fObjFunction;
}
/**
* Sets a new objective function.
* The old objective function summands are NOT deleted.
*
* @param summands BList containing the objective function's summands
*/
void
LinearSpec::SetObjFunction(BList* summands)
{
fObjFunction = summands;
UpdateObjFunction();
}
/**
* Updates the internal representation of the objective function.
* Must be called whenever the summands of the objective function are changed.
*/
void
LinearSpec::UpdateObjFunction()
{
int32 size = fObjFunction->CountItems();
double coeffs[size];
int varIndexes[size];
Summand* current;
for (int32 i = 0; i < size; i++) {
current = (Summand*)fObjFunction->ItemAt(i);
coeffs[i] = current->Coeff();
varIndexes[i] = current->Var()->Index();
}
if (!set_obj_fnex(fLP, size, &coeffs[0], &varIndexes[0]))
printf("Error in set_obj_fnex.");
RemovePresolved();
}
/** /**
* Remove a cached presolved model, if existent. * Remove a cached presolved model, if existent.
* This is automatically done each time after the model has been changed, * This is automatically done each time after the model has been changed,
@@ -501,21 +500,9 @@ LinearSpec::Save(char* fname)
* @return the number of columns * @return the number of columns
*/ */
int32 int32
LinearSpec::Columns() const LinearSpec::CountColumns() const
{ {
return fColumns; return fCountColumns;
}
/**
* Sets the number of columns.
*
* @param value the number of columns
*/
void
LinearSpec::SetColumns(int32 value)
{
fColumns = value;
} }
@@ -549,54 +536,6 @@ LinearSpec::SetOptimization(OptimizationType value)
} }
/**
* Gets the lpsolve variable.
*
* @return the lpsolve variable
*/
lprec*
LinearSpec::LP() const
{
return fLP;
}
/**
* Sets the lpsolve variable.
*
* @param value the lpsolve variable
*/
void
LinearSpec::SetLP(lprec* value)
{
fLP = value;
}
/**
* Gets the objective function summand.
*
* @return the objective function summand
*/
BList*
LinearSpec::ObjFunctionSummands() const
{
return fObjFunctionSummands;
}
/**
* Sets the objective function summand.
*
* @param value the objective function summand
*/
void
LinearSpec::SetObjFunctionSummands(BList* value)
{
fObjFunctionSummands = value;
}
/** /**
* Gets the the variables. * Gets the the variables.
* *
@@ -609,18 +548,6 @@ LinearSpec::Variables() const
} }
/**
* Sets the the variables.
*
* @param value the variables
*/
void
LinearSpec::SetVariables(BList* value)
{
fVariables = value;
}
/** /**
* Gets the constraints. * Gets the constraints.
* *
@@ -633,16 +560,6 @@ LinearSpec::Constraints() const
} }
/**
* Sets the constraints.
*
* @param value the constraints
*/
void LinearSpec::SetConstraints(BList* value) {
fConstraints = value;
}
/** /**
* Gets the result type. * Gets the result type.
* *
@@ -655,18 +572,6 @@ LinearSpec::Result() const
} }
/**
* Sets the result type.
*
* @param value the result type
*/
void
LinearSpec::SetResult(ResultType value)
{
fResult = value;
}
/** /**
* Gets the objective value. * Gets the objective value.
* *
@@ -679,18 +584,6 @@ LinearSpec::ObjectiveValue() const
} }
/**
* Sets the objective value.
*
* @param value the objective value
*/
void
LinearSpec::SetObjectiveValue(double value)
{
fObjectiveValue = value;
}
/** /**
* Gets the solving time. * Gets the solving time.
* *
@@ -702,15 +595,3 @@ LinearSpec::SolvingTime() const
return fSolvingTime; return fSolvingTime;
} }
/**
* Sets the solving time.
*
* @param value the solving time
*/
void
LinearSpec::SetSolvingTime(double value)
{
fSolvingTime = value;
}
-57
View File
@@ -1,57 +0,0 @@
/*
* Copyright 2007-2008, Christof Lutteroth, lutteroth@cs.auckland.ac.nz
* Copyright 2007-2008, James Kim, jkim202@ec.auckland.ac.nz
* Distributed under the terms of the MIT License.
*/
#include "ObjFunctionSummand.h"
#include "Variable.h"
#include "LinearSpec.h"
/**
* Sets the summmand's coefficient.
*
* @param coeff coefficient
*/
void
ObjFunctionSummand::SetCoeff(double coeff)
{
Summand::SetCoeff(coeff);
fLS->UpdateObjFunction();
}
/**
* Sets the summand's variable.
*
* @param var variable
*/
void
ObjFunctionSummand::SetVar(Variable* var)
{
Summand::SetVar(var);
fLS->UpdateObjFunction();
}
/**
* Destructor.
* Removes the summand from the objective function.
*/
ObjFunctionSummand::~ObjFunctionSummand()
{
fLS->ObjFunctionSummands()->RemoveItem(this);
fLS->UpdateObjFunction();
}
/**
* Constructor.
*/
ObjFunctionSummand::ObjFunctionSummand(LinearSpec* ls, double coeff, Variable* var)
: Summand(coeff, var)
{
fLS = ls;
}
+11 -52
View File
@@ -6,7 +6,7 @@
#include "PenaltyFunction.h" #include "PenaltyFunction.h"
#include "Constraint.h" #include "Constraint.h"
#include "ObjFunctionSummand.h" #include "Summand.h"
#include "OperatorType.h" #include "OperatorType.h"
#include "Variable.h" #include "Variable.h"
#include "LinearSpec.h" #include "LinearSpec.h"
@@ -31,8 +31,8 @@ PenaltyFunction::PenaltyFunction(LinearSpec* ls, Variable* var, BList* xs, BList
fVar = var; fVar = var;
fXs = xs; fXs = xs;
fGs = gs; fGs = gs;
fConstraints = new BList(1); fConstraints = new BList(sizeGs + 1);
fObjFunctionSummands = new BList(1); fObjFunctionSummands = new BList(sizeGs);
fConstraints->AddItem(ls->AddConstraint(1.0, var, OperatorType(EQ), fConstraints->AddItem(ls->AddConstraint(1.0, var, OperatorType(EQ),
*(double*)(xs->ItemAt(0)), -*(double*)(gs->ItemAt(0)), *(double*)(xs->ItemAt(0)), -*(double*)(gs->ItemAt(0)),
@@ -44,9 +44,11 @@ PenaltyFunction::PenaltyFunction(LinearSpec* ls, Variable* var, BList* xs, BList
fConstraints->AddItem(ls->AddConstraint(1.0, var, -1.0, dPos, OperatorType(LE), fConstraints->AddItem(ls->AddConstraint(1.0, var, -1.0, dPos, OperatorType(LE),
*(double*)(xs->ItemAt(i)))); *(double*)(xs->ItemAt(i))));
fObjFunctionSummands->AddItem(ls->AddObjFunctionSummand( Summand* objSummand = new Summand(*(double*)(gs->ItemAt(i + 1)) - *(double*)(gs->ItemAt(i)), dPos);
*(double*)(gs->ItemAt(i + 1)) - *(double*)(gs->ItemAt(i)), dPos)); ls->ObjFunction()->AddItem(objSummand);
fObjFunctionSummands->AddItem(objSummand);
} }
ls->UpdateObjFunction();
} }
@@ -56,53 +58,10 @@ PenaltyFunction::PenaltyFunction(LinearSpec* ls, Variable* var, BList* xs, BList
*/ */
PenaltyFunction::~PenaltyFunction() PenaltyFunction::~PenaltyFunction()
{ {
int32 sizeConstraints = fConstraints->CountItems(); for (int32 i = 0; i < fConstraints->CountItems(); i++)
for (int32 i = 0; i < sizeConstraints; i++) { delete (Constraint*)fConstraints->ItemAt(i);
Constraint* currentConstraint = (Constraint*)fConstraints->ItemAt(i);
delete currentConstraint;
}
int32 sizeObjFunctionSummands = fObjFunctionSummands->CountItems(); for (int32 i = 0; i < fObjFunctionSummands->CountItems(); i++)
for (int32 i = 0; i < sizeObjFunctionSummands; i++) { delete (Summand*)fObjFunctionSummands->ItemAt(i);
ObjFunctionSummand* currentObjFunctionSummand =
(ObjFunctionSummand*)fObjFunctionSummands->ItemAt(i);
delete currentObjFunctionSummand;
}
}
/**
* Gets the variable.
*
* @return the variable
*/
const Variable*
PenaltyFunction::Var() const
{
return fVar;
}
/**
* Gets the sampling points.
*
* @return the sampling points
*/
const BList*
PenaltyFunction::Xs() const
{
return fXs;
}
/**
* Gets the sampling gradients.
*
* @return the sampling gradients
*/
const
BList* PenaltyFunction::Gs() const
{
return fGs;
} }
+6 -7
View File
@@ -98,7 +98,7 @@ void
Variable::SetMin(double min) Variable::SetMin(double min)
{ {
fMin = min; fMin = min;
set_bounds(fLS->LP(), this->Index(), fMin, fMax); set_bounds(fLS->fLP, this->Index(), fMin, fMax);
} }
@@ -123,7 +123,7 @@ void
Variable::SetMax(double max) Variable::SetMax(double max)
{ {
fMax = max; fMax = max;
set_bounds(fLS->LP(), this->Index(), fMin, fMax); set_bounds(fLS->fLP, this->Index(), fMin, fMax);
} }
@@ -138,7 +138,7 @@ Variable::SetRange(double min, double max)
{ {
fMin = min; fMin = min;
fMax = max; fMax = max;
set_bounds(fLS->LP(), this->Index(), fMin, fMax); set_bounds(fLS->fLP, this->Index(), fMin, fMax);
} }
@@ -204,11 +204,10 @@ Variable::Variable(LinearSpec* ls)
ls->Variables()->AddItem(this); ls->Variables()->AddItem(this);
int32 size = ls->Variables()->CountItems(); if (ls->Variables()->CountItems() > ls->CountColumns()) {
if (size > ls->Columns()) {
double d = 0; double d = 0;
int i = 0; int i = 0;
if (!add_columnex(ls->LP(), 0, &d, &i)) if (!add_columnex(ls->fLP, 0, &d, &i))
printf("Error in add_columnex."); printf("Error in add_columnex.");
} }
} }
@@ -220,7 +219,7 @@ Variable::Variable(LinearSpec* ls)
*/ */
Variable::~Variable() Variable::~Variable()
{ {
del_column(fLS->LP(), this->Index()); del_column(fLS->fLP, this->Index());
fLS->Variables()->RemoveItem(this); fLS->Variables()->RemoveItem(this);
} }
+7 -25
View File
@@ -7,10 +7,7 @@
#include <List.h> #include <List.h>
#include <SupportDefs.h> #include <SupportDefs.h>
#include "Constraint.h"
#include "LinearSpec.h" #include "LinearSpec.h"
#include "OperatorType.h"
#include "Variable.h"
#include <stdio.h> #include <stdio.h>
@@ -35,25 +32,14 @@ Test1()
Variable* x1 = ls->AddVariable(); Variable* x1 = ls->AddVariable();
Variable* x2 = ls->AddVariable(); Variable* x2 = ls->AddVariable();
BList* coeffs1 = new BList(1); Constraint* c1 = ls->AddConstraint(1.0, x1, OperatorType(LE), 108);
coeffs1->AddItem(new double(1.0)); Constraint* c2 = ls->AddConstraint(1.0, x2, OperatorType(GE), 113);
BList* vars1 = new BList(1);
vars1->AddItem(x1);
Constraint* c1 = ls->AddConstraint(coeffs1, vars1, OperatorType(LE), 108);
BList* coeffs2 = new BList(1); BList* summands = new BList(2);
coeffs2->AddItem(new double(1.0)); summands->AddItem(new Summand(1.0, x1));
BList* vars2 = new BList(1); summands->AddItem(new Summand(1.0, x2));
vars2->AddItem(x2); ls->SetObjFunction(summands);
Constraint* c2 = ls->AddConstraint(coeffs2, vars2, OperatorType(GE), 113);
BList* coeffs3 = new BList(2);
coeffs3->AddItem(new double(1.0));
coeffs3->AddItem(new double(1.0));
BList* vars3 = new BList(2);
vars3->AddItem(x1);
vars3->AddItem(x2);
ls->SetObjFunction(coeffs3, vars3);
ls->Solve(); ls->Solve();
PrintVars(ls); PrintVars(ls);
@@ -61,11 +47,7 @@ Test1()
ls->Solve(); ls->Solve();
PrintVars(ls); PrintVars(ls);
BList* coeffs4 = new BList(1); c2 = ls->AddConstraint(1.0, x2, OperatorType(GE), 113);
coeffs4->AddItem(new double(1.0));
BList* vars4 = new BList(1);
vars4->AddItem(x2);
c2 = ls->AddConstraint(coeffs4, vars4, OperatorType(GE), 113);
ls->Solve(); ls->Solve();
PrintVars(ls); PrintVars(ls);
} }