- Remove lp_solve dependencies form Variable class and put everything into LinearSpec. As a side effect Variable management is a bit more consistence now. We want to replace lp_solve soon so it will be easier to replace it just in LinearSpec.

- Update copyrights.
- Lot of small things related to the Variable refactoring.



git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@38892 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Clemens Zeidler
2010-10-05 20:15:55 +00:00
parent 64141b1b74
commit fc691d7de2
12 changed files with 168 additions and 120 deletions
+2 -2
View File
@@ -8,12 +8,12 @@
#include "Constraint.h"
#include "LinearSpec.h"
#include "Tab.h"
namespace BALM {
class BALMLayout;
class XTab;
/**
* Represents a column defined by two x-tabs.
@@ -36,7 +36,7 @@ public:
ConstraintList* Constraints() const;
protected:
Column(LinearSpec* ls);
Column(BALMLayout* layout);
protected:
LinearSpec* fLS;
+3 -3
View File
@@ -8,13 +8,13 @@
#include "Constraint.h"
#include "LinearSpec.h"
#include "Tab.h"
namespace BALM {
class BALMLayout;
class YTab;
/**
* Represents a row defined by two y-tabs.
*/
@@ -34,7 +34,7 @@ public:
ConstraintList* Constraints() const;
protected:
Row(LinearSpec* ls);
Row(BALMLayout* layout);
protected:
LinearSpec* fLS;
-2
View File
@@ -27,7 +27,6 @@ protected:
public:
friend class BALMLayout;
friend class Column;
};
@@ -42,7 +41,6 @@ protected:
public:
friend class BALMLayout;
friend class Row;
};
+10 -8
View File
@@ -36,6 +36,12 @@ public:
virtual ~LinearSpec();
Variable* AddVariable();
bool AddVariable(Variable* variable);
bool RemoveVariable(Variable* variable,
bool deleteVariable = true);
int32 IndexOf(const Variable* variable) const;
bool SetRange(Variable* variable, double min,
double max);
Constraint* AddConstraint(SummandList* summands,
OperatorType op, double rightSide);
@@ -86,8 +92,6 @@ public:
void SetObjectiveFunction(SummandList* objFunction);
void UpdateObjectiveFunction();
ResultType Presolve();
void RemovePresolved();
ResultType Solve();
void Save(const char* fileName);
@@ -102,13 +106,12 @@ public:
operator BString() const;
void GetString(BString& string) const;
protected:
VariableList* Variables() const;
ConstraintList* Constraints() const;
int32 fCountColumns;
const ConstraintList& Constraints() const;
private:
ResultType Presolve();
void RemovePresolved();
lprec* fLpPresolved;
OptimizationType fOptimization;
lprec* fLP;
@@ -121,7 +124,6 @@ private:
public:
friend class Constraint;
friend class Variable;
};
+5 -6
View File
@@ -6,11 +6,9 @@
#ifndef VARIABLE_H
#define VARIABLE_H
#include <File.h>
#include <ObjectList.h>
#include <String.h>
#include <SupportDefs.h>
namespace LinearProgramming {
@@ -51,15 +49,18 @@ public:
double penaltyNeg, double penaltyPos);
bool IsValid();
//! Dangerous the variable don't belong to the LinearSpec anymore,
//! delete it yourself!
void Invalidate();
virtual ~Variable();
~Variable();
protected:
Variable(LinearSpec* ls);
private:
LinearSpec* fLS;
BObjectList<Summand> fUsingSummands;
// All Summands that link to this Variable
double fValue;
@@ -71,9 +72,7 @@ private:
public:
friend class LinearSpec;
friend class Constraint;
friend class Summand;
};
+28 -11
View File
@@ -10,6 +10,7 @@
#include <math.h> // for floor
#include <new>
#include <iostream>
#include "ViewLayoutItem.h"
@@ -31,10 +32,10 @@ BALMLayout::BALMLayout(float spacing)
fSpacing(spacing),
fCurrentArea(NULL)
{
fLeft = new XTab(&fSolver);
fRight = new XTab(&fSolver);
fTop = new YTab(&fSolver);
fBottom = new YTab(&fSolver);
fLeft = AddXTab();
fRight = AddXTab();
fTop = AddYTab();
fBottom = AddYTab();
// the Left tab is always at x-position 0, and the Top tab is always at y-position 0
fLeft->SetRange(0, 0);
@@ -64,7 +65,15 @@ BALMLayout::~BALMLayout()
XTab*
BALMLayout::AddXTab()
{
return new XTab(&fSolver);
XTab* tab = new XTab(&fSolver);
if (!tab)
return NULL;
if (!fSolver.AddVariable(tab)) {
delete tab;
return NULL;
}
return tab;
}
@@ -76,7 +85,15 @@ BALMLayout::AddXTab()
YTab*
BALMLayout::AddYTab()
{
return new YTab(&fSolver);
YTab* tab = new YTab(&fSolver);
if (!tab)
return NULL;
if (!fSolver.AddVariable(tab)) {
delete tab;
return NULL;
}
return tab;
}
@@ -88,7 +105,7 @@ BALMLayout::AddYTab()
Row*
BALMLayout::AddRow()
{
return new Row(&fSolver);
return new Row(this);
}
@@ -102,7 +119,7 @@ BALMLayout::AddRow()
Row*
BALMLayout::AddRow(YTab* top, YTab* bottom)
{
Row* row = new Row(&fSolver);
Row* row = new Row(this);
if (top != NULL)
row->Constraints()->AddItem(row->Top()->IsEqual(top));
if (bottom != NULL)
@@ -119,7 +136,7 @@ BALMLayout::AddRow(YTab* top, YTab* bottom)
Column*
BALMLayout::AddColumn()
{
return new Column(&fSolver);
return new Column(this);
}
@@ -133,7 +150,7 @@ BALMLayout::AddColumn()
Column*
BALMLayout::AddColumn(XTab* left, XTab* right)
{
Column* column = new Column(&fSolver);
Column* column = new Column(this);
if (left != NULL)
column->Constraints()->AddItem(column->Left()->IsEqual(left));
if (right != NULL)
@@ -677,7 +694,7 @@ BALMLayout::DerivedLayoutItems()
_SolveLayout();
// if new layout is infasible, use previous layout
// if new layout is infeasible, use previous layout
if (fSolver.Result() == INFEASIBLE)
return;
+1
View File
@@ -1,6 +1,7 @@
/*
* Copyright 2007-2008, Christof Lutteroth, [email protected]
* Copyright 2007-2008, James Kim, [email protected]
* Copyright 2010, Clemens Zeidler <[email protected]>
* Distributed under the terms of the MIT License.
*/
+8 -9
View File
@@ -1,6 +1,7 @@
/*
* Copyright 2007-2008, Christof Lutteroth, lutteroth@cs.auckland.ac.nz
* Copyright 2007-2008, James Kim, jkim202@ec.auckland.ac.nz
* Copyright 2010, Clemens Zeidler <haiku@clemens-zeidler.de>
* Distributed under the terms of the MIT License.
*/
@@ -11,8 +12,6 @@
#include "OperatorType.h"
#include "Tab.h"
#include <SupportDefs.h>
/**
* The left boundary of the column.
@@ -72,7 +71,7 @@ Column::SetPrevious(Column* value)
fPrevious = value;
fPrevious->fNext = this;
value->fNextGlue = value->fRight->IsEqual(fLeft);
value->fNextGlue = value->Right()->IsEqual(Left());
fPreviousGlue = value->fNextGlue;
}
@@ -115,7 +114,7 @@ Column::SetNext(Column* value)
fNext = value;
fNext->fPrevious = this;
value->fPreviousGlue = fRight->IsEqual(value->fLeft);
value->fPreviousGlue = Right()->IsEqual(value->Left());
fNextGlue = value->fPreviousGlue;
}
@@ -156,7 +155,7 @@ Constraint*
Column::HasSameWidthAs(Column* column)
{
Constraint* constraint = fLS->AddConstraint(
-1.0, fLeft, 1.0, fRight, 1.0, column->fLeft, -1.0, column->fRight,
-1.0, Left(), 1.0, Right(), 1.0, column->Left(), -1.0, column->Right(),
OperatorType(EQ), 0.0);
fConstraints.AddItem(constraint);
return constraint;
@@ -188,10 +187,10 @@ Column::~Column()
/**
* Constructor.
*/
Column::Column(LinearSpec* ls)
Column::Column(BALMLayout* layout)
{
fLS = ls;
fLeft = new XTab(ls);
fRight = new XTab(ls);
fLS = layout->Solver();
fLeft = layout->AddXTab();
fRight = layout->AddXTab();
}
+8 -7
View File
@@ -1,6 +1,7 @@
/*
* Copyright 2007-2008, Christof Lutteroth, lutteroth@cs.auckland.ac.nz
* Copyright 2007-2008, James Kim, jkim202@ec.auckland.ac.nz
* Copyright 2010, Clemens Zeidler <haiku@clemens-zeidler.de>
* Distributed under the terms of the MIT License.
*/
@@ -73,7 +74,7 @@ Row::SetPrevious(Row* value)
fPrevious = value;
fPrevious->fNext = this;
value->fNextGlue = value->fBottom->IsEqual(fTop);
value->fNextGlue = value->Bottom()->IsEqual(Top());
fPreviousGlue = value->fNextGlue;
}
@@ -117,7 +118,7 @@ Row::SetNext(Row* value)
fNext = value;
fNext->fPrevious = this;
value->fPreviousGlue = fBottom->IsEqual(value->fTop);
value->fPreviousGlue = Bottom()->IsEqual(value->Top());
fNextGlue = value->fPreviousGlue;
}
@@ -158,7 +159,7 @@ Constraint*
Row::HasSameHeightAs(Row* row)
{
Constraint* constraint = fLS->AddConstraint(
-1.0, fTop, 1.0, fBottom, 1.0, row->fTop, -1.0, row->fBottom,
-1.0, Top(), 1.0, Bottom(), 1.0, row->Top(), -1.0, row->Bottom(),
OperatorType(EQ), 0.0);
fConstraints.AddItem(constraint);
return constraint;
@@ -193,10 +194,10 @@ Row::~Row()
/**
* Constructor.
*/
Row::Row(LinearSpec* ls)
Row::Row(BALMLayout* layout)
{
fLS = ls;
fTop = new YTab(ls);
fBottom = new YTab(ls);
fLS = layout->Solver();
fTop = layout->AddYTab();
fBottom = layout->AddYTab();
}
+7 -9
View File
@@ -8,8 +8,6 @@
#include "LinearSpec.h"
#include "Variable.h"
#include "lp_lib.h"
// Toggle debug output
//#define DEBUG_CONSTRAINT
@@ -29,7 +27,7 @@
int32
Constraint::Index() const
{
int32 i = fLS->Constraints()->IndexOf(this);
int32 i = fLS->Constraints().IndexOf(this);
if (i == -1) {
STRACE(("Constraint not part of fLS->Constraints()."));
return -1;
@@ -265,7 +263,7 @@ Constraint::SetPenaltyNeg(double value)
return;
if (fDNegObjSummand == NULL) {
fDNegObjSummand = new Summand(value, new Variable(fLS));
fDNegObjSummand = new Summand(value, fLS->AddVariable());
fLS->ObjectiveFunction()->AddItem(fDNegObjSummand);
UpdateLeftSide();
fLS->UpdateObjectiveFunction();
@@ -307,7 +305,7 @@ Constraint::SetPenaltyPos(double value)
return;
if (fDPosObjSummand == NULL) {
fDPosObjSummand = new Summand(value, new Variable(fLS));
fDPosObjSummand = new Summand(value, fLS->AddVariable());
fLS->ObjectiveFunction()->AddItem(fDPosObjSummand);
UpdateLeftSide();
fLS->UpdateObjectiveFunction();
@@ -441,7 +439,7 @@ Constraint::Invalidate()
}
del_constraint(fLS->fLP, this->Index());
fLS->Constraints()->RemoveItem(this);
const_cast<ConstraintList&>(fLS->Constraints()).RemoveItem(this);
}
@@ -502,7 +500,7 @@ Constraint::Constraint(LinearSpec* ls, SummandList* summands, OperatorType op,
if (penaltyNeg != INFINITY
&& fOp != OperatorType(LE)) {
fDNegObjSummand = new Summand(penaltyNeg, new Variable(fLS));
fDNegObjSummand = new Summand(penaltyNeg, ls->AddVariable());
fLS->fObjFunction->AddItem(fDNegObjSummand);
varIndexes[i] = fDNegObjSummand->Var()->Index();
coeffs[i] = 1.0;
@@ -513,7 +511,7 @@ Constraint::Constraint(LinearSpec* ls, SummandList* summands, OperatorType op,
if (penaltyPos != INFINITY
&& fOp != OperatorType(GE)) {
fDPosObjSummand = new Summand(penaltyPos, new Variable(fLS));
fDPosObjSummand = new Summand(penaltyPos, ls->AddVariable());
fLS->fObjFunction->AddItem(fDPosObjSummand);
varIndexes[i] = fDPosObjSummand->Var()->Index();
coeffs[i] = -1.0;
@@ -529,7 +527,7 @@ Constraint::Constraint(LinearSpec* ls, SummandList* summands, OperatorType op,
STRACE(("Error in add_constraintex."));
fLS->UpdateObjectiveFunction();
fLS->Constraints()->AddItem(this);
const_cast<ConstraintList&>(fLS->Constraints()).AddItem(this);
}
+80 -34
View File
@@ -1,9 +1,11 @@
/*
* Copyright 2007-2008, Christof Lutteroth, lutteroth@cs.auckland.ac.nz
* Copyright 2007-2008, James Kim, jkim202@ec.auckland.ac.nz
* Copyright 2010, Clemens Zeidler <haiku@clemens-zeidler.de>
* Distributed under the terms of the MIT License.
*/
#include "LinearSpec.h"
@@ -13,7 +15,6 @@
*/
LinearSpec::LinearSpec()
:
fCountColumns(0),
fLpPresolved(NULL),
fOptimization(MINIMIZE),
fObjFunction(new SummandList()),
@@ -40,8 +41,9 @@ LinearSpec::~LinearSpec()
delete (Constraint*)fConstraints.ItemAt(i);
for (int32 i = 0; i < fObjFunction->CountItems(); i++)
delete (Summand*)fObjFunction->ItemAt(i);
for (int32 i = 0; i < fVariables.CountItems(); i++)
delete (Variable*)fVariables.ItemAt(i);
while (fVariables.CountItems() > 0)
RemoveVariable(fVariables.ItemAt(0));
delete_lp(fLP);
delete fObjFunction;
@@ -56,7 +58,75 @@ LinearSpec::~LinearSpec()
Variable*
LinearSpec::AddVariable()
{
return new Variable(this);
Variable* variable = new Variable(this);
if (!variable)
return NULL;
if (!AddVariable(variable)) {
delete variable;
return NULL;
}
return variable;
}
bool
LinearSpec::AddVariable(Variable* variable)
{
double d = 0;
int i = 0;
if (!fVariables.AddItem(variable))
return false;
if (add_columnex(fLP, 0, &d, &i) == 0) {
fVariables.RemoveItem(variable);
return false;
}
if (!SetRange(variable, -20000, 20000)) {
RemoveVariable(variable, false);
return false;
}
variable->fIsValid = true;
return true;
}
bool
LinearSpec::RemoveVariable(Variable* variable, bool deleteVariable)
{
int32 index = IndexOf(variable);
if (index < 0)
return false;
if (!del_column(fLP, index))
return false;
fVariables.RemoveItemAt(index - 1);
variable->Invalidate();
if (deleteVariable)
delete variable;
return true;
}
int32
LinearSpec::IndexOf(const Variable* variable) const
{
int32 i = fVariables.IndexOf(variable);
if (i == -1) {
printf("Variable 0x%p not part of fLS->Variables().\n", variable);
return -1;
}
return i + 1;
}
bool
LinearSpec::SetRange(Variable* variable, double min, double max)
{
return set_bounds(fLP, IndexOf(variable), min, max);
}
@@ -396,7 +466,7 @@ LinearSpec::UpdateObjectiveFunction()
}
if (!set_obj_fnex(fLP, size, &coeffs[0], &varIndexes[0]))
printf("Error in set_obj_fnex.");
printf("Error in set_obj_fnex.\n");
RemovePresolved();
}
@@ -433,8 +503,8 @@ LinearSpec::Presolve()
if (fLpPresolved == NULL) {
fLpPresolved = copy_lp(fLP);
set_presolve(fLpPresolved, PRESOLVE_ROWS | PRESOLVE_COLS | PRESOLVE_LINDEP,
get_presolveloops(fLpPresolved));
set_presolve(fLpPresolved, PRESOLVE_ROWS | PRESOLVE_COLS
| PRESOLVE_LINDEP, get_presolveloops(fLpPresolved));
}
fResult = (ResultType)solve(fLpPresolved);
@@ -478,7 +548,7 @@ LinearSpec::Solve()
int32 size = fVariables.CountItems();
double x[size];
if (!get_variables(fLP, &x[0]))
printf("Error in get_variables.");
printf("Error in get_variables.\n");
int32 i = 0;
while (i < size) {
@@ -508,18 +578,6 @@ LinearSpec::Save(const char* fileName)
}
/**
* Gets the number of columns.
*
* @return the number of columns
*/
int32
LinearSpec::CountColumns() const
{
return fCountColumns;
}
/**
* Gets the current optimization.
* The default is minimization.
@@ -550,27 +608,15 @@ LinearSpec::SetOptimization(OptimizationType value)
}
/**
* Gets the the variables.
*
* @return the variables
*/
VariableList*
LinearSpec::Variables() const
{
return const_cast<VariableList*>(&fVariables);
}
/**
* Gets the constraints.
*
* @return the constraints
*/
ConstraintList*
const ConstraintList&
LinearSpec::Constraints() const
{
return const_cast<ConstraintList*>(&fConstraints);
return fConstraints;
}
+16 -29
View File
@@ -1,18 +1,19 @@
/*
* Copyright 2007-2008, Christof Lutteroth, lutteroth@cs.auckland.ac.nz
* Copyright 2007-2008, James Kim, jkim202@ec.auckland.ac.nz
* Copyright 2010, Clemens Zeidler <haiku@clemens-zeidler.de>
* Distributed under the terms of the MIT License.
*/
#include "Variable.h"
#include "Constraint.h"
#include "LinearSpec.h"
#include "OperatorType.h"
#include "lp_lib.h"
#include "Variable.h"
#include <float.h> // for DBL_MAX
#include <File.h>
#include "Constraint.h"
#include "LinearSpec.h"
// Toggle debug output
//#define DEBUG_VARIABLE
@@ -32,12 +33,7 @@
int32
Variable::Index() const
{
int32 i = fLS->Variables()->IndexOf(this);
if (i == -1) {
printf("Variable not part of fLS->Variables().");
return -1;
}
return i + 1;
return fLS->IndexOf(this);
}
@@ -139,7 +135,7 @@ Variable::SetRange(double min, double max)
fMin = min;
fMax = max;
set_bounds(fLS->fLP, this->Index(), fMin, fMax);
fLS->SetRange(this, fMin, fMax);
}
@@ -279,20 +275,20 @@ Variable::IsValid()
void
Variable::Invalidate()
{
STRACE(("Variable::Invalidate() on %s\n", ToString()));
STRACE(("Variable::Invalidate() on %s\n", BString(*this).String()));
if (!fIsValid)
return;
fIsValid = false;
del_column(fLS->fLP, Index());
fLS->Variables()->RemoveItem(this);
fLS->RemoveVariable(this, false);
// invalidate all constraints that use this variable
ConstraintList markedForInvalidation;
ConstraintList* constraints = fLS->Constraints();
for (int i = 0; i < constraints->CountItems(); i++) {
Constraint* constraint = constraints->ItemAt(i);
const ConstraintList& constraints = fLS->Constraints();
for (int i = 0; i < constraints.CountItems(); i++) {
Constraint* constraint = constraints.ItemAt(i);
if (!constraint->IsValid())
continue;
@@ -321,18 +317,9 @@ Variable::Variable(LinearSpec* ls)
fMin(0),
fMax(DBL_MAX),
fLabel(NULL),
fIsValid(true)
fIsValid(false)
{
fLS->Variables()->AddItem(this);
if (fLS->Variables()->CountItems() > fLS->CountColumns()) {
double d = 0;
int i = 0;
if (!add_columnex(fLS->fLP, 0, &d, &i))
printf("Error in add_columnex.");
}
SetRange(-20000, 20000);
}
@@ -342,6 +329,6 @@ Variable::Variable(LinearSpec* ls)
*/
Variable::~Variable()
{
Invalidate();
fLS->RemoveVariable(this, false);
}