Added libalm.so and its dependency liblinprog.so. libalm.so provides a
BLayout implementation (BALMLayout) using the Auckland Layout Model (ALM). The original ALM was implemented by Christof Lutteroth, the Haiku/C++ version by James Kim. The code needs some review, but the test programs seem to work fine. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23889 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
38d596cb81
commit
a101e99aad
@ -65,7 +65,7 @@ BEOS_SYSTEM_LIB = libbe.so $(HAIKU_LIBSTDC++) libmedia.so libtracker.so
|
|||||||
libtranslation.so libnetwork.so libdebug.so libbsd.so libmail.so
|
libtranslation.so libnetwork.so libdebug.so libbsd.so libmail.so
|
||||||
libtextencoding.so libz.so libfreetype.so libpng.so libmidi.so libmidi2.so
|
libtextencoding.so libz.so libfreetype.so libpng.so libmidi.so libmidi2.so
|
||||||
libdevice.so libgame.so libscreensaver.so <revisioned>libroot.so
|
libdevice.so libgame.so libscreensaver.so <revisioned>libroot.so
|
||||||
$(X86_ONLY)libGL.so libfluidsynth.so
|
$(X86_ONLY)libGL.so libfluidsynth.so liblpsolve55.so liblinprog.so libalm.so
|
||||||
;
|
;
|
||||||
BEOS_SYSTEM_SERVERS = registrar debug_server syslog_daemon media_server
|
BEOS_SYSTEM_SERVERS = registrar debug_server syslog_daemon media_server
|
||||||
net_server media_addon_server input_server app_server fake_app_server
|
net_server media_addon_server input_server app_server fake_app_server
|
||||||
|
149
headers/libs/alm/Area.h
Normal file
149
headers/libs/alm/Area.h
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
#ifndef AREA_H
|
||||||
|
#define AREA_H
|
||||||
|
|
||||||
|
#include "Constraint.h"
|
||||||
|
#include "SoftConstraint.h"
|
||||||
|
|
||||||
|
#include <Alignment.h>
|
||||||
|
#include <List.h>
|
||||||
|
#include <Size.h>
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
#include <View.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace BALM {
|
||||||
|
|
||||||
|
class Column;
|
||||||
|
class BALMLayout;
|
||||||
|
class Row;
|
||||||
|
class XTab;
|
||||||
|
class YTab;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Rectangular area in the GUI, defined by a tab on each side.
|
||||||
|
*/
|
||||||
|
class Area {
|
||||||
|
|
||||||
|
public:
|
||||||
|
bool AutoPrefContentSize() const;
|
||||||
|
void SetAutoPrefContentSize(bool value);
|
||||||
|
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);
|
||||||
|
Row* GetRow() const;
|
||||||
|
void SetRow(Row* row);
|
||||||
|
Column* GetColumn() const;
|
||||||
|
void SetColumn(Column* column);
|
||||||
|
BView* Content() const;
|
||||||
|
void SetContent(BView* content);
|
||||||
|
XTab* ContentLeft() const;
|
||||||
|
YTab* ContentTop() const;
|
||||||
|
XTab* ContentRight() const;
|
||||||
|
YTab* ContentBottom() const;
|
||||||
|
BSize MinContentSize() const;
|
||||||
|
void SetMinContentSize(BSize min);
|
||||||
|
BSize MaxContentSize() const;
|
||||||
|
void SetMaxContentSize(BSize max);
|
||||||
|
BSize PrefContentSize() const;
|
||||||
|
void SetPrefContentSize(BSize pref);
|
||||||
|
BSize ShrinkRigidity() const;
|
||||||
|
void SetShrinkRigidity(BSize shrink);
|
||||||
|
BSize ExpandRigidity() const;
|
||||||
|
void SetExpandRigidity(BSize expand);
|
||||||
|
double ContentAspectRatio() const;
|
||||||
|
void SetContentAspectRatio(double ratio);
|
||||||
|
BAlignment Alignment() const;
|
||||||
|
void SetAlignment(BAlignment alignment);
|
||||||
|
void SetHAlignment(alignment horizontal);
|
||||||
|
void SetVAlignment(vertical_alignment vertical);
|
||||||
|
int32 LeftInset() const;
|
||||||
|
void SetLeftInset(int32 left);
|
||||||
|
int32 TopInset() const;
|
||||||
|
void SetTopInset(int32 top);
|
||||||
|
int32 RightInset() const;
|
||||||
|
void SetRightInset(int32 right);
|
||||||
|
int32 BottomInset() const;
|
||||||
|
void SetBottomInset(int32 bottom);
|
||||||
|
void SetDefaultPrefContentSize();
|
||||||
|
//~ string ToString();
|
||||||
|
Constraint* HasSameWidthAs(Area* area);
|
||||||
|
Constraint* HasSameHeightAs(Area* area);
|
||||||
|
BList* HasSameSizetAs(Area* area);
|
||||||
|
~Area();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Area(BALMLayout* ls, XTab* left, YTab* top,
|
||||||
|
XTab* right, YTab* bottom,
|
||||||
|
BView* content,
|
||||||
|
BSize minContentSize);
|
||||||
|
Area(BALMLayout* ls, Row* row, Column* column,
|
||||||
|
BView* content,
|
||||||
|
BSize minContentSize);
|
||||||
|
void DoLayout();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void InitChildArea();
|
||||||
|
void UpdateHorizontal();
|
||||||
|
void UpdateVertical();
|
||||||
|
void Init(BALMLayout* ls, XTab* left, YTab* top,
|
||||||
|
XTab* right, YTab* bottom,
|
||||||
|
BView* content,
|
||||||
|
BSize minContentSize);
|
||||||
|
|
||||||
|
public:
|
||||||
|
static BSize kMaxSize;
|
||||||
|
static BSize kMinSize;
|
||||||
|
static BSize kUndefinedSize;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BView* fContent;
|
||||||
|
BList* fConstraints;
|
||||||
|
|
||||||
|
private:
|
||||||
|
BALMLayout* fLS;
|
||||||
|
XTab* fLeft;
|
||||||
|
XTab* fRight;
|
||||||
|
YTab* fTop;
|
||||||
|
YTab* fBottom;
|
||||||
|
Row* fRow;
|
||||||
|
Column* fColumn;
|
||||||
|
BSize fMinContentSize;
|
||||||
|
BSize fMaxContentSize;
|
||||||
|
Constraint* fMinContentWidth;
|
||||||
|
Constraint* fMaxContentWidth;
|
||||||
|
Constraint* fMinContentHeight;
|
||||||
|
Constraint* fMaxContentHeight;
|
||||||
|
BSize fPrefContentSize;
|
||||||
|
BSize fShrinkRigidity;
|
||||||
|
BSize fExpandRigidity;
|
||||||
|
double fContentAspectRatio;
|
||||||
|
Constraint* fContentAspectRatioC;
|
||||||
|
bool fAutoPrefContentSize;
|
||||||
|
SoftConstraint* fPrefContentWidth;
|
||||||
|
SoftConstraint* fPrefContentHeight;
|
||||||
|
Area* fChildArea;
|
||||||
|
BAlignment fAlignment;
|
||||||
|
int32 fLeftInset;
|
||||||
|
int32 fTopInset;
|
||||||
|
int32 fRightInset;
|
||||||
|
int32 fBottomInset;
|
||||||
|
Constraint* fLeftConstraint;
|
||||||
|
Constraint* fTopConstraint;
|
||||||
|
Constraint* fRightConstraint;
|
||||||
|
Constraint* fBottomConstraint;
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class BALMLayout;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BALM
|
||||||
|
|
||||||
|
using BALM::Area;
|
||||||
|
|
||||||
|
#endif // AREA_H
|
106
headers/libs/alm/BALMLayout.h
Normal file
106
headers/libs/alm/BALMLayout.h
Normal file
@ -0,0 +1,106 @@
|
|||||||
|
#ifndef BALM_LAYOUT_H
|
||||||
|
#define BALM_LAYOUT_H
|
||||||
|
|
||||||
|
#include <File.h>
|
||||||
|
#include <Layout.h>
|
||||||
|
#include <List.h>
|
||||||
|
#include <Size.h>
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
#include <View.h>
|
||||||
|
|
||||||
|
#include "LayoutStyleType.h"
|
||||||
|
#include "LinearSpec.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace BALM {
|
||||||
|
|
||||||
|
class Area;
|
||||||
|
class Column;
|
||||||
|
class Row;
|
||||||
|
class XTab;
|
||||||
|
class YTab;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A GUI layout engine using the ALM.
|
||||||
|
*/
|
||||||
|
class BALMLayout : public BLayout, public LinearSpec {
|
||||||
|
|
||||||
|
public:
|
||||||
|
BALMLayout();
|
||||||
|
void SolveLayout();
|
||||||
|
|
||||||
|
XTab* AddXTab();
|
||||||
|
YTab* AddYTab();
|
||||||
|
Row* AddRow();
|
||||||
|
Row* AddRow(YTab* top, YTab* bottom);
|
||||||
|
Column* AddColumn();
|
||||||
|
Column* AddColumn(XTab* left, XTab* right);
|
||||||
|
Area* AddArea(XTab* left, YTab* top, XTab* right, YTab* bottom,
|
||||||
|
BView* content, BSize minContentSize);
|
||||||
|
Area* AddArea(Row* row, Column* column, BView* content,
|
||||||
|
BSize minContentSize);
|
||||||
|
Area* AddArea(XTab* left, YTab* top, XTab* right, YTab* bottom,
|
||||||
|
BView* content);
|
||||||
|
Area* AddArea(Row* row, Column* column, BView* content);
|
||||||
|
Area* AreaOf(BView* control);
|
||||||
|
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);
|
||||||
|
BLayoutItem* AddView(int32 index, BView* child);
|
||||||
|
bool AddItem(BLayoutItem* item);
|
||||||
|
bool AddItem(int32 index, BLayoutItem* item);
|
||||||
|
bool RemoveView(BView* child);
|
||||||
|
bool RemoveItem(BLayoutItem* item);
|
||||||
|
BLayoutItem* RemoveItem(int32 index);
|
||||||
|
|
||||||
|
BSize MinSize();
|
||||||
|
BSize MaxSize();
|
||||||
|
BSize PreferredSize();
|
||||||
|
BAlignment Alignment();
|
||||||
|
bool HasHeightForWidth();
|
||||||
|
void GetHeightForWidth(float width, float* min,
|
||||||
|
float* max, float* preferred);
|
||||||
|
void InvalidateLayout();
|
||||||
|
void LayoutView();
|
||||||
|
|
||||||
|
char* PerformancePath() const;
|
||||||
|
void SetPerformancePath(char* path);
|
||||||
|
|
||||||
|
private:
|
||||||
|
BSize CalculateMinSize();
|
||||||
|
BSize CalculateMaxSize();
|
||||||
|
BSize CalculatePreferredSize();
|
||||||
|
|
||||||
|
private:
|
||||||
|
LayoutStyleType fLayoutStyle;
|
||||||
|
bool fActivated;
|
||||||
|
|
||||||
|
BList* fAreas;
|
||||||
|
XTab* fLeft;
|
||||||
|
XTab* fRight;
|
||||||
|
YTab* fTop;
|
||||||
|
YTab* fBottom;
|
||||||
|
BSize fMinSize;
|
||||||
|
BSize fMaxSize;
|
||||||
|
BSize fPreferredSize;
|
||||||
|
char* fPerformancePath;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BALM
|
||||||
|
|
||||||
|
using BALM::BALMLayout;
|
||||||
|
|
||||||
|
#endif // BALM_LAYOUT_H
|
58
headers/libs/alm/Column.h
Normal file
58
headers/libs/alm/Column.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#ifndef COLUMN_H
|
||||||
|
#define COLUMN_H
|
||||||
|
|
||||||
|
#include "Constraint.h"
|
||||||
|
|
||||||
|
#include <List.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace BALM {
|
||||||
|
|
||||||
|
class BALMLayout;
|
||||||
|
class XTab;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a column defined by two x-tabs.
|
||||||
|
*/
|
||||||
|
class Column {
|
||||||
|
|
||||||
|
public:
|
||||||
|
XTab* Left() const;
|
||||||
|
XTab* Right() const;
|
||||||
|
Column* Previous() const;
|
||||||
|
void SetPrevious(Column* value);
|
||||||
|
Column* Next() const;
|
||||||
|
void SetNext(Column* value);
|
||||||
|
//~ string ToString();
|
||||||
|
void InsertBefore(Column* column);
|
||||||
|
void InsertAfter(Column* column);
|
||||||
|
Constraint* HasSameWidthAs(Column* column);
|
||||||
|
BList* Constraints() const;
|
||||||
|
void SetConstraints(BList* constraints);
|
||||||
|
~Column();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Column(BALMLayout* ls);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BALMLayout* fLS;
|
||||||
|
XTab* fLeft;
|
||||||
|
XTab* fRight;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Column* fPrevious;
|
||||||
|
Column* fNext;
|
||||||
|
Constraint* fPreviousGlue;
|
||||||
|
Constraint* fNextGlue;
|
||||||
|
BList* fConstraints;
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class BALMLayout;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BALM
|
||||||
|
|
||||||
|
using BALM::Column;
|
||||||
|
|
||||||
|
#endif // COLUMN_H
|
20
headers/libs/alm/LayoutStyleType.h
Normal file
20
headers/libs/alm/LayoutStyleType.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef LAYOUT_STYLE_TYPE_H
|
||||||
|
#define LAYOUT_STYLE_TYPE_H
|
||||||
|
|
||||||
|
|
||||||
|
namespace BALM {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The possibilities for adjusting a GUI's layout.
|
||||||
|
* Either change the child controls so that they fit into their parent control, or adjust
|
||||||
|
* the size of the parent control so that the children have as much space as they want.
|
||||||
|
*/
|
||||||
|
enum LayoutStyleType {
|
||||||
|
FIT_TO_SIZE, ADJUST_SIZE
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BALM
|
||||||
|
|
||||||
|
using BALM::LayoutStyleType;
|
||||||
|
|
||||||
|
#endif
|
58
headers/libs/alm/Row.h
Normal file
58
headers/libs/alm/Row.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
#ifndef ROW_H
|
||||||
|
#define ROW_H
|
||||||
|
|
||||||
|
#include "Constraint.h"
|
||||||
|
|
||||||
|
#include <List.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace BALM {
|
||||||
|
|
||||||
|
class BALMLayout;
|
||||||
|
class YTab;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a row defined by two y-tabs.
|
||||||
|
*/
|
||||||
|
class Row {
|
||||||
|
|
||||||
|
public:
|
||||||
|
YTab* Top() const;
|
||||||
|
YTab* Bottom() const;
|
||||||
|
Row* Previous() const;
|
||||||
|
void SetPrevious(Row* value);
|
||||||
|
Row* Next() const;
|
||||||
|
void SetNext(Row* value);
|
||||||
|
//~ string ToString();
|
||||||
|
void InsertBefore(Row* row);
|
||||||
|
void InsertAfter(Row* row);
|
||||||
|
Constraint* HasSameHeightAs(Row* row);
|
||||||
|
BList* Constraints() const;
|
||||||
|
void SetConstraints(BList* constraints);
|
||||||
|
~Row();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Row(BALMLayout* ls);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BALMLayout* fLS;
|
||||||
|
YTab* fTop;
|
||||||
|
YTab* fBottom;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Row* fPrevious;
|
||||||
|
Row* fNext;
|
||||||
|
Constraint* fPreviousGlue;
|
||||||
|
Constraint* fNextGlue;
|
||||||
|
BList* fConstraints;
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class BALMLayout;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BALM
|
||||||
|
|
||||||
|
using BALM::Row;
|
||||||
|
|
||||||
|
#endif // ROW_H
|
38
headers/libs/alm/XTab.h
Normal file
38
headers/libs/alm/XTab.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
#ifndef X_TAB_H
|
||||||
|
#define X_TAB_H
|
||||||
|
|
||||||
|
#include "Variable.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace BALM {
|
||||||
|
|
||||||
|
class BALMLayout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Vertical grid line (x-tab).
|
||||||
|
*/
|
||||||
|
class XTab : public Variable {
|
||||||
|
|
||||||
|
protected:
|
||||||
|
XTab(BALMLayout* ls);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Property signifying if there is a constraint which relates
|
||||||
|
* this tab to a different tab that is further to the left.
|
||||||
|
* Only used for reverse engineering.
|
||||||
|
*/
|
||||||
|
bool fLeftLink;
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class Area;
|
||||||
|
friend class Column;
|
||||||
|
friend class BALMLayout;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BALM
|
||||||
|
|
||||||
|
using BALM::XTab;
|
||||||
|
|
||||||
|
#endif // X_TAB_H
|
37
headers/libs/alm/YTab.h
Normal file
37
headers/libs/alm/YTab.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#ifndef Y_TAB_H
|
||||||
|
#define Y_TAB_H
|
||||||
|
|
||||||
|
#include "Variable.h"
|
||||||
|
|
||||||
|
namespace BALM {
|
||||||
|
|
||||||
|
class BALMLayout;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Horizontal grid line (y-tab).
|
||||||
|
*/
|
||||||
|
class YTab : public Variable {
|
||||||
|
|
||||||
|
protected:
|
||||||
|
YTab(BALMLayout* ls);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
/**
|
||||||
|
* Property signifying if there is a constraint which relates
|
||||||
|
* this tab to a different tab that is further to the top.
|
||||||
|
* Only used for reverse engineering.
|
||||||
|
*/
|
||||||
|
bool fTopLink;
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class Area;
|
||||||
|
friend class Row;
|
||||||
|
friend class BALMLayout;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace BALM
|
||||||
|
|
||||||
|
using BALM::YTab;
|
||||||
|
|
||||||
|
#endif // Y_TAB_H
|
56
headers/libs/linprog/Constraint.h
Normal file
56
headers/libs/linprog/Constraint.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
#ifndef CONSTRAINT_H
|
||||||
|
#define CONSTRAINT_H
|
||||||
|
|
||||||
|
#include "OperatorType.h"
|
||||||
|
|
||||||
|
#include <List.h>
|
||||||
|
#include <String.h>
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace LinearProgramming {
|
||||||
|
|
||||||
|
class LinearSpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hard linear constraint, i.e. one that must be satisfied.
|
||||||
|
* May render a specification infeasible.
|
||||||
|
*/
|
||||||
|
class Constraint {
|
||||||
|
|
||||||
|
public:
|
||||||
|
int32 Index();
|
||||||
|
BList* Coeffs();
|
||||||
|
BList* Vars();
|
||||||
|
virtual void ChangeLeftSide(BList* coeffs, BList* vars);
|
||||||
|
virtual OperatorType Op();
|
||||||
|
virtual void SetOp(OperatorType value);
|
||||||
|
double RightSide();
|
||||||
|
void SetRightSide(double value);
|
||||||
|
BString ToString();
|
||||||
|
virtual ~Constraint();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Constraint();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Constraint(LinearSpec* ls, BList* coeffs, BList* vars,
|
||||||
|
OperatorType op, double rightSide);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
LinearSpec* fLS;
|
||||||
|
BList* fCoeffs;
|
||||||
|
BList* fVars;
|
||||||
|
OperatorType fOp;
|
||||||
|
double fRightSide;
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class LinearSpec;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LinearProgramming
|
||||||
|
|
||||||
|
using LinearProgramming::Constraint;
|
||||||
|
|
||||||
|
#endif // CONSTRAINT_H
|
124
headers/libs/linprog/LinearSpec.h
Normal file
124
headers/libs/linprog/LinearSpec.h
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
#ifndef LINEAR_SPEC_H
|
||||||
|
#define LINEAR_SPEC_H
|
||||||
|
|
||||||
|
#include "OperatorType.h"
|
||||||
|
#include "ResultType.h"
|
||||||
|
#include "OptimizationType.h"
|
||||||
|
|
||||||
|
#include "lp_lib.h"
|
||||||
|
|
||||||
|
#include <List.h>
|
||||||
|
#include <OS.h>
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace LinearProgramming {
|
||||||
|
|
||||||
|
class Constraint;
|
||||||
|
class ObjFunctionSummand;
|
||||||
|
class PenaltyFunction;
|
||||||
|
class SoftConstraint;
|
||||||
|
class Variable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Specification of a linear programming problem.
|
||||||
|
*/
|
||||||
|
class LinearSpec {
|
||||||
|
|
||||||
|
public:
|
||||||
|
LinearSpec();
|
||||||
|
~LinearSpec();
|
||||||
|
void UpdateObjFunction();
|
||||||
|
void SetObjFunction(BList* coeffs, BList* vars);
|
||||||
|
ObjFunctionSummand* AddObjFunctionSummand(double coeff, Variable* var);
|
||||||
|
Variable* AddVariable();
|
||||||
|
|
||||||
|
Constraint* AddConstraint(BList* coeffs, BList* vars,
|
||||||
|
OperatorType op, double rightSide);
|
||||||
|
Constraint* AddConstraint(double coeff1, Variable* var1,
|
||||||
|
OperatorType op, double rightSide);
|
||||||
|
Constraint* AddConstraint(double coeff1, Variable* var1,
|
||||||
|
double coeff2, Variable* var2,
|
||||||
|
OperatorType op, double rightSide);
|
||||||
|
Constraint* AddConstraint(double coeff1, Variable* var1,
|
||||||
|
double coeff2, Variable* var2,
|
||||||
|
double coeff3, Variable* var3,
|
||||||
|
OperatorType op, double rightSide);
|
||||||
|
Constraint* AddConstraint(double coeff1, Variable* var1,
|
||||||
|
double coeff2, Variable* var2,
|
||||||
|
double coeff3, Variable* var3,
|
||||||
|
double coeff4, Variable* var4,
|
||||||
|
OperatorType op, double rightSide);
|
||||||
|
|
||||||
|
SoftConstraint* AddSoftConstraint(BList* coeffs, BList* vars,
|
||||||
|
OperatorType op, double rightSide,
|
||||||
|
double penaltyNeg, double penaltyPos);
|
||||||
|
SoftConstraint* AddSoftConstraint(double coeff1, Variable* var1,
|
||||||
|
OperatorType op, double rightSide,
|
||||||
|
double penaltyNeg, double penaltyPos);
|
||||||
|
SoftConstraint* AddSoftConstraint(double coeff1, Variable* var1,
|
||||||
|
double coeff2, Variable* var2,
|
||||||
|
OperatorType op, double rightSide,
|
||||||
|
double penaltyNeg, double penaltyPos);
|
||||||
|
SoftConstraint* AddSoftConstraint(double coeff1, Variable* var1,
|
||||||
|
double coeff2, Variable* var2,
|
||||||
|
double coeff3, Variable* var3,
|
||||||
|
OperatorType op, double rightSide,
|
||||||
|
double penaltyNeg, double penaltyPos);
|
||||||
|
SoftConstraint* AddSoftConstraint(double coeff1, Variable* var1,
|
||||||
|
double coeff2, Variable* var2,
|
||||||
|
double coeff3, Variable* var3,
|
||||||
|
double coeff4, Variable* var4,
|
||||||
|
OperatorType op, double rightSide,
|
||||||
|
double penaltyNeg, double penaltyPos);
|
||||||
|
|
||||||
|
PenaltyFunction* AddPenaltyFunction(Variable* var, BList* xs, BList* gs);
|
||||||
|
void RemovePresolved();
|
||||||
|
ResultType Presolve();
|
||||||
|
ResultType Solve();
|
||||||
|
void Save(char* fname);
|
||||||
|
|
||||||
|
int32 Columns() const;
|
||||||
|
void SetColumns(int32 value);
|
||||||
|
OptimizationType Optimization() const;
|
||||||
|
void SetOptimization(OptimizationType value);
|
||||||
|
lprec* LP() const;
|
||||||
|
void SetLP(lprec* value);
|
||||||
|
BList* ObjFunctionSummands() const;
|
||||||
|
void SetObjFunctionSummands(BList* value);
|
||||||
|
BList* Variables() const;
|
||||||
|
void SetVariables(BList* value);
|
||||||
|
BList* Constraints() const;
|
||||||
|
void SetConstraints(BList* value);
|
||||||
|
ResultType Result() const;
|
||||||
|
void SetResult(ResultType value);
|
||||||
|
double ObjectiveValue() const;
|
||||||
|
void SetObjectiveValue(double value);
|
||||||
|
double SolvingTime() const;
|
||||||
|
void SetSolvingTime(double value);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
int32 fColumns;
|
||||||
|
|
||||||
|
private:
|
||||||
|
lprec* fLpPresolved;
|
||||||
|
OptimizationType fOptimization;
|
||||||
|
lprec* fLP;
|
||||||
|
BList* fObjFunctionSummands;
|
||||||
|
BList* fVariables;
|
||||||
|
BList* fConstraints;
|
||||||
|
ResultType fResult;
|
||||||
|
double fObjectiveValue;
|
||||||
|
double fSolvingTime; // = Double.Nan
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class ObjFunctionSummand;
|
||||||
|
friend class SoftConstraint;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LinearProgramming
|
||||||
|
|
||||||
|
using LinearProgramming::LinearSpec;
|
||||||
|
|
||||||
|
#endif // LINEAR_SPEC_H
|
39
headers/libs/linprog/ObjFunctionSummand.h
Normal file
39
headers/libs/linprog/ObjFunctionSummand.h
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#ifndef OBJ_FUNCTION_SUMMAND_H
|
||||||
|
#define OBJ_FUNCTION_SUMMAND_H
|
||||||
|
|
||||||
|
|
||||||
|
namespace LinearProgramming {
|
||||||
|
|
||||||
|
class LinearSpec;
|
||||||
|
class Variable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A summand of the objective function.
|
||||||
|
*/
|
||||||
|
class ObjFunctionSummand {
|
||||||
|
|
||||||
|
public:
|
||||||
|
double Coeff();
|
||||||
|
void SetCoeff(double coeff);
|
||||||
|
Variable* Var();
|
||||||
|
void SetVar(Variable* var);
|
||||||
|
~ObjFunctionSummand();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ObjFunctionSummand(LinearSpec* ls, double coeff, Variable* var);
|
||||||
|
|
||||||
|
private:
|
||||||
|
LinearSpec* fLS;
|
||||||
|
double fCoeff;
|
||||||
|
Variable* fVar;
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class LinearSpec;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LinearProgramming
|
||||||
|
|
||||||
|
using LinearProgramming::ObjFunctionSummand;
|
||||||
|
|
||||||
|
#endif // OBJ_FUNCTION_SUMMAND_H
|
18
headers/libs/linprog/OperatorType.h
Normal file
18
headers/libs/linprog/OperatorType.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef OPERATOR_TYPE_H
|
||||||
|
#define OPERATOR_TYPE_H
|
||||||
|
|
||||||
|
|
||||||
|
namespace LinearProgramming {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Possible operators for linear constraints.
|
||||||
|
*/
|
||||||
|
enum OperatorType {
|
||||||
|
EQ, LE, GE
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LinearProgramming
|
||||||
|
|
||||||
|
using LinearProgramming::OperatorType;
|
||||||
|
|
||||||
|
#endif
|
18
headers/libs/linprog/OptimizationType.h
Normal file
18
headers/libs/linprog/OptimizationType.h
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
#ifndef OPTIMIZATION_TYPE_H
|
||||||
|
#define OPTIMIZATION_TYPE_H
|
||||||
|
|
||||||
|
|
||||||
|
namespace LinearProgramming {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The two possibilities for optimizing the objective function.
|
||||||
|
*/
|
||||||
|
enum OptimizationType {
|
||||||
|
MINIMIZE, MAXIMIZE
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LinearProgramming
|
||||||
|
|
||||||
|
using LinearProgramming::OptimizationType;
|
||||||
|
|
||||||
|
#endif
|
43
headers/libs/linprog/PenaltyFunction.h
Normal file
43
headers/libs/linprog/PenaltyFunction.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
#ifndef PENALTY_FUNCTION_H
|
||||||
|
#define PENALTY_FUNCTION_H
|
||||||
|
|
||||||
|
#include <List.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace LinearProgramming {
|
||||||
|
|
||||||
|
class LinearSpec;
|
||||||
|
class Variable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Penalty function.
|
||||||
|
*/
|
||||||
|
class PenaltyFunction {
|
||||||
|
|
||||||
|
protected:
|
||||||
|
PenaltyFunction(LinearSpec* ls, Variable* var, BList* xs, BList* gs);
|
||||||
|
|
||||||
|
public:
|
||||||
|
~PenaltyFunction();
|
||||||
|
const Variable* Var() const;
|
||||||
|
const BList* Xs() const;
|
||||||
|
const BList* Gs() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
LinearSpec* fLS;
|
||||||
|
Variable* fVar;
|
||||||
|
BList* fXs; // double
|
||||||
|
BList* fGs; // double
|
||||||
|
BList* fConstraints;
|
||||||
|
BList* fObjFunctionSummands;
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class LinearSpec;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LinearProgramming
|
||||||
|
|
||||||
|
using LinearProgramming::PenaltyFunction;
|
||||||
|
|
||||||
|
#endif // PENALTY_FUNCTION_H
|
20
headers/libs/linprog/ResultType.h
Normal file
20
headers/libs/linprog/ResultType.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef RESULT_TYPE_H
|
||||||
|
#define RESULT_TYPE_H
|
||||||
|
|
||||||
|
|
||||||
|
namespace LinearProgramming {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The possible results of a solving attempt.
|
||||||
|
*/
|
||||||
|
enum ResultType {
|
||||||
|
NOMEMORY = -2, ERROR = -1, OPTIMAL = 0, SUBOPTIMAL = 1, INFEASIBLE = 2, UNBOUNDED = 3,
|
||||||
|
DEGENERATE = 4, NUMFAILURE = 5, USERABORT = 6, TIMEOUT = 7, PRESOLVED = 9, PROCFAIL = 10,
|
||||||
|
PROCBREAK = 11, FEASFOUND = 12, NOFEASFOUND = 13
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LinearProgramming
|
||||||
|
|
||||||
|
using LinearProgramming::ResultType;
|
||||||
|
|
||||||
|
#endif
|
54
headers/libs/linprog/SoftConstraint.h
Normal file
54
headers/libs/linprog/SoftConstraint.h
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
#ifndef SOFT_CONSTRAINT_H
|
||||||
|
#define SOFT_CONSTRAINT_H
|
||||||
|
|
||||||
|
#include "Constraint.h"
|
||||||
|
|
||||||
|
#include <List.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace LinearProgramming {
|
||||||
|
|
||||||
|
class LinearSpec;
|
||||||
|
class ObjFunctionSummand;
|
||||||
|
class Variable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Soft constraint, i.e. one that does not necessarily have to be satisfied.
|
||||||
|
* Use this instead of hard constraints to avoid over-constrained specifications.
|
||||||
|
*/
|
||||||
|
class SoftConstraint : public Constraint {
|
||||||
|
|
||||||
|
public:
|
||||||
|
void ChangeLeftSide(BList* coeffs, BList* vars);
|
||||||
|
OperatorType Op();
|
||||||
|
void SetOp(OperatorType value);
|
||||||
|
double PenaltyNeg();
|
||||||
|
void SetPenaltyNeg(double value);
|
||||||
|
double PenaltyPos();
|
||||||
|
void SetPenaltyPos(double value);
|
||||||
|
//~ string ToString();
|
||||||
|
Variable* DNeg() const;
|
||||||
|
Variable* DPos() const;
|
||||||
|
~SoftConstraint();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
SoftConstraint(LinearSpec* ls, BList* coeffs, BList* vars,
|
||||||
|
OperatorType op, double rightSide,
|
||||||
|
double penaltyNeg, double penaltyPos);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Variable* fDNeg;
|
||||||
|
Variable* fDPos;
|
||||||
|
ObjFunctionSummand* fDNegSummand;
|
||||||
|
ObjFunctionSummand* fDPosSummand;
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class LinearSpec;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LinearProgramming
|
||||||
|
|
||||||
|
using LinearProgramming::SoftConstraint;
|
||||||
|
|
||||||
|
#endif // SOFT_CONSTRAINT_H
|
53
headers/libs/linprog/Variable.h
Normal file
53
headers/libs/linprog/Variable.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
#ifndef VARIABLE_H
|
||||||
|
#define VARIABLE_H
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
|
||||||
|
namespace LinearProgramming {
|
||||||
|
|
||||||
|
class Constraint;
|
||||||
|
class LinearSpec;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contains minimum and maximum values.
|
||||||
|
*/
|
||||||
|
class Variable {
|
||||||
|
|
||||||
|
public:
|
||||||
|
int32 Index();
|
||||||
|
LinearSpec* LS() const;
|
||||||
|
void SetLS(LinearSpec* value);
|
||||||
|
double Value() const;
|
||||||
|
void SetValue(double value);
|
||||||
|
double Min() const;
|
||||||
|
void SetMin(double min);
|
||||||
|
double Max() const;
|
||||||
|
void SetMax(double max);
|
||||||
|
void SetRange(double min, double max);
|
||||||
|
//~ string ToString();
|
||||||
|
Constraint* IsEqual(Variable* var);
|
||||||
|
Constraint* IsSmallerOrEqual(Variable* var);
|
||||||
|
Constraint* IsGreaterorEqual(Variable* var);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
Variable(LinearSpec* ls);
|
||||||
|
~Variable();
|
||||||
|
|
||||||
|
private:
|
||||||
|
LinearSpec* fLS;
|
||||||
|
double fValue;
|
||||||
|
double fMin;
|
||||||
|
double fMax;
|
||||||
|
|
||||||
|
public:
|
||||||
|
friend class LinearSpec;
|
||||||
|
friend class SoftConstraint;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LinearProgramming
|
||||||
|
|
||||||
|
using LinearProgramming::Variable;
|
||||||
|
|
||||||
|
#endif // VARIABLE_H
|
@ -1,6 +1,7 @@
|
|||||||
SubDir HAIKU_TOP src libs ;
|
SubDir HAIKU_TOP src libs ;
|
||||||
|
|
||||||
SubInclude HAIKU_TOP src libs agg ;
|
SubInclude HAIKU_TOP src libs agg ;
|
||||||
|
SubInclude HAIKU_TOP src libs alm ;
|
||||||
SubInclude HAIKU_TOP src libs bsd ;
|
SubInclude HAIKU_TOP src libs bsd ;
|
||||||
SubInclude HAIKU_TOP src libs compat ;
|
SubInclude HAIKU_TOP src libs compat ;
|
||||||
SubInclude HAIKU_TOP src libs crypt ;
|
SubInclude HAIKU_TOP src libs crypt ;
|
||||||
@ -10,6 +11,8 @@ SubInclude HAIKU_TOP src libs fluidsynth ;
|
|||||||
SubInclude HAIKU_TOP src libs freetype2 ;
|
SubInclude HAIKU_TOP src libs freetype2 ;
|
||||||
SubInclude HAIKU_TOP src libs icon ;
|
SubInclude HAIKU_TOP src libs icon ;
|
||||||
SubInclude HAIKU_TOP src libs libtelnet ;
|
SubInclude HAIKU_TOP src libs libtelnet ;
|
||||||
|
SubInclude HAIKU_TOP src libs linprog ;
|
||||||
|
SubInclude HAIKU_TOP src libs lp_solve ;
|
||||||
SubInclude HAIKU_TOP src libs ncurses ;
|
SubInclude HAIKU_TOP src libs ncurses ;
|
||||||
SubInclude HAIKU_TOP src libs pdflib ;
|
SubInclude HAIKU_TOP src libs pdflib ;
|
||||||
SubInclude HAIKU_TOP src libs png ;
|
SubInclude HAIKU_TOP src libs png ;
|
||||||
|
1267
src/libs/alm/Area.cpp
Normal file
1267
src/libs/alm/Area.cpp
Normal file
File diff suppressed because it is too large
Load Diff
699
src/libs/alm/BALMLayout.cpp
Normal file
699
src/libs/alm/BALMLayout.cpp
Normal file
@ -0,0 +1,699 @@
|
|||||||
|
#include "BALMLayout.h"
|
||||||
|
#include "Area.h"
|
||||||
|
#include "Column.h"
|
||||||
|
#include "ResultType.h"
|
||||||
|
#include "Row.h"
|
||||||
|
#include "XTab.h"
|
||||||
|
#include "YTab.h"
|
||||||
|
|
||||||
|
#include <math.h> // for floor
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* Creates new layout engine.
|
||||||
|
*/
|
||||||
|
BALMLayout::BALMLayout()
|
||||||
|
: BLayout(),
|
||||||
|
LinearSpec()
|
||||||
|
{
|
||||||
|
fLayoutStyle = FIT_TO_SIZE;
|
||||||
|
fActivated = true;
|
||||||
|
|
||||||
|
fAreas = new BList(1);
|
||||||
|
fLeft = new XTab(this);
|
||||||
|
fRight = new XTab(this);
|
||||||
|
fTop = new YTab(this);
|
||||||
|
fBottom = new YTab(this);
|
||||||
|
|
||||||
|
// the Left tab is always at x-position 0, and the Top tab is always at y-position 0
|
||||||
|
fLeft->SetRange(0, 0);
|
||||||
|
fTop->SetRange(0, 0);
|
||||||
|
|
||||||
|
// cached layout values
|
||||||
|
// need to be invalidated whenever the layout specification is changed
|
||||||
|
fMinSize = Area::kUndefinedSize;
|
||||||
|
fMaxSize = Area::kUndefinedSize;
|
||||||
|
fPreferredSize = Area::kUndefinedSize;
|
||||||
|
|
||||||
|
fPerformancePath = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Solves the layout.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
BALMLayout::SolveLayout()
|
||||||
|
{
|
||||||
|
// if autoPrefContentSize is set on an area, readjust its prefContentSize and
|
||||||
|
// rigidity settings
|
||||||
|
int32 sizeAreas = fAreas->CountItems();
|
||||||
|
Area* currentArea;
|
||||||
|
for (int32 i = 0; i < sizeAreas; i++) {
|
||||||
|
currentArea = (Area*)fAreas->ItemAt(i);
|
||||||
|
if (currentArea->AutoPrefContentSize())
|
||||||
|
currentArea->SetDefaultPrefContentSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
// try to solve the layout until the result is OPTIMAL or INFEASIBLE, maximally
|
||||||
|
// 15 tries sometimes the solving algorithm encounters numerical problems
|
||||||
|
// (NUMFAILURE), and repeating the solving often helps to overcome them
|
||||||
|
BFile* file = new BFile(fPerformancePath,
|
||||||
|
B_READ_WRITE | B_CREATE_FILE | B_OPEN_AT_END);
|
||||||
|
|
||||||
|
ResultType result;
|
||||||
|
for (int32 tries = 0; tries < 15; tries++) {
|
||||||
|
result = Solve();
|
||||||
|
if (fPerformancePath != NULL) {
|
||||||
|
char buffer [100];
|
||||||
|
file->Write(buffer, sprintf(buffer, "%d\t%fms\t#vars=%d\t#constraints=%d\n",
|
||||||
|
result, SolvingTime(), Variables()->CountItems(),
|
||||||
|
Constraints()->CountItems()));
|
||||||
|
}
|
||||||
|
if (result == OPTIMAL || result == INFEASIBLE) break;
|
||||||
|
}
|
||||||
|
delete file;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new x-tab to the specification.
|
||||||
|
*
|
||||||
|
* @return the new x-tab
|
||||||
|
*/
|
||||||
|
XTab*
|
||||||
|
BALMLayout::AddXTab()
|
||||||
|
{
|
||||||
|
return new XTab(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new y-tab to the specification.
|
||||||
|
*
|
||||||
|
* @return the new y-tab
|
||||||
|
*/
|
||||||
|
YTab*
|
||||||
|
BALMLayout::AddYTab()
|
||||||
|
{
|
||||||
|
return new YTab(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new row to the specification.
|
||||||
|
*
|
||||||
|
* @return the new row
|
||||||
|
*/
|
||||||
|
Row*
|
||||||
|
BALMLayout::AddRow()
|
||||||
|
{
|
||||||
|
return new Row(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new row to the specification that is glued to the given y-tabs.
|
||||||
|
*
|
||||||
|
* @param top
|
||||||
|
* @param bottom
|
||||||
|
* @return the new row
|
||||||
|
*/
|
||||||
|
Row*
|
||||||
|
BALMLayout::AddRow(YTab* top, YTab* bottom)
|
||||||
|
{
|
||||||
|
Row* row = new Row(this);
|
||||||
|
if (top != NULL) row->Constraints()->AddItem(row->Top()->IsEqual(top));
|
||||||
|
if (bottom != NULL) row->Constraints()->AddItem(row->Bottom()->IsEqual(bottom));
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new column to the specification.
|
||||||
|
*
|
||||||
|
* @return the new column
|
||||||
|
*/
|
||||||
|
Column*
|
||||||
|
BALMLayout::AddColumn()
|
||||||
|
{
|
||||||
|
return new Column(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new column to the specification that is glued to the given x-tabs.
|
||||||
|
*
|
||||||
|
* @param left
|
||||||
|
* @param right
|
||||||
|
* @return the new column
|
||||||
|
*/
|
||||||
|
Column*
|
||||||
|
BALMLayout::AddColumn(XTab* left, XTab* right)
|
||||||
|
{
|
||||||
|
Column* column = new Column(this);
|
||||||
|
if (left != NULL) column->Constraints()->AddItem(column->Left()->IsEqual(left));
|
||||||
|
if (right != NULL) column->Constraints()->AddItem(column->Right()->IsEqual(right));
|
||||||
|
return column;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new area to the specification, setting only the necessary minimum size constraints.
|
||||||
|
*
|
||||||
|
* @param left left border
|
||||||
|
* @param top top border
|
||||||
|
* @param right right border
|
||||||
|
* @param bottom bottom border
|
||||||
|
* @param content the control which is the area content
|
||||||
|
* @param minContentSize minimum content size
|
||||||
|
* @return the new area
|
||||||
|
*/
|
||||||
|
Area*
|
||||||
|
BALMLayout::AddArea(XTab* left, YTab* top, XTab* right, YTab* bottom,
|
||||||
|
BView* content, BSize minContentSize)
|
||||||
|
{
|
||||||
|
InvalidateLayout();
|
||||||
|
if (content != NULL)
|
||||||
|
View()->AddChild(content);
|
||||||
|
Area* area = new Area(this, left, top, right, bottom, content, minContentSize);
|
||||||
|
fAreas->AddItem(area);
|
||||||
|
return area;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new area to the specification, setting only the necessary minimum size constraints.
|
||||||
|
*
|
||||||
|
* @param row the row that defines the top and bottom border
|
||||||
|
* @param column the column that defines the left and right border
|
||||||
|
* @param content the control which is the area content
|
||||||
|
* @param minContentSize minimum content size
|
||||||
|
* @return the new area
|
||||||
|
*/
|
||||||
|
Area*
|
||||||
|
BALMLayout::AddArea(Row* row, Column* column, BView* content,
|
||||||
|
BSize minContentSize)
|
||||||
|
{
|
||||||
|
InvalidateLayout();
|
||||||
|
if (content != NULL)
|
||||||
|
View()->AddChild(content);
|
||||||
|
Area* area = new Area(this, row, column, content, minContentSize);
|
||||||
|
fAreas->AddItem(area);
|
||||||
|
return area;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new area to the specification, automatically setting preferred size constraints.
|
||||||
|
*
|
||||||
|
* @param left left border
|
||||||
|
* @param top top border
|
||||||
|
* @param right right border
|
||||||
|
* @param bottom bottom border
|
||||||
|
* @param content the control which is the area content
|
||||||
|
* @return the new area
|
||||||
|
*/
|
||||||
|
Area*
|
||||||
|
BALMLayout::AddArea(XTab* left, YTab* top, XTab* right, YTab* bottom,
|
||||||
|
BView* content)
|
||||||
|
{
|
||||||
|
InvalidateLayout();
|
||||||
|
if (content != NULL)
|
||||||
|
View()->AddChild(content);
|
||||||
|
Area* area = new Area(this, left, top, right, bottom, content, BSize(0, 0));
|
||||||
|
area->SetDefaultPrefContentSize();
|
||||||
|
area->SetAutoPrefContentSize(true);
|
||||||
|
fAreas->AddItem(area);
|
||||||
|
return area;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new area to the specification, automatically setting preferred size constraints.
|
||||||
|
*
|
||||||
|
* @param row the row that defines the top and bottom border
|
||||||
|
* @param column the column that defines the left and right border
|
||||||
|
* @param content the control which is the area content
|
||||||
|
* @return the new area
|
||||||
|
*/
|
||||||
|
Area*
|
||||||
|
BALMLayout::AddArea(Row* row, Column* column, BView* content)
|
||||||
|
{
|
||||||
|
InvalidateLayout();
|
||||||
|
if (content != NULL)
|
||||||
|
View()->AddChild(content);
|
||||||
|
Area* area = new Area(this, row, column, content, BSize(0, 0));
|
||||||
|
area->SetDefaultPrefContentSize();
|
||||||
|
area->SetAutoPrefContentSize(true);
|
||||||
|
fAreas->AddItem(area);
|
||||||
|
return area;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the area that contains the given control.
|
||||||
|
*
|
||||||
|
* @param control the control to look for
|
||||||
|
* @return the area that contains the control
|
||||||
|
*/
|
||||||
|
Area*
|
||||||
|
BALMLayout::AreaOf(BView* control)
|
||||||
|
{
|
||||||
|
Area* area;
|
||||||
|
for (int32 i = 0; i < fAreas->CountItems(); i++) {
|
||||||
|
area = (Area*)fAreas->ItemAt(i);
|
||||||
|
if (area->Content() == control)
|
||||||
|
return area;
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the ares.
|
||||||
|
*
|
||||||
|
* @return the areas
|
||||||
|
*/
|
||||||
|
BList*
|
||||||
|
BALMLayout::Areas() const
|
||||||
|
{
|
||||||
|
return fAreas;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the ares.
|
||||||
|
*
|
||||||
|
* @param areas the areas
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
BALMLayout::SetAreas(BList* areas)
|
||||||
|
{
|
||||||
|
fAreas = areas;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the left variable.
|
||||||
|
*/
|
||||||
|
XTab*
|
||||||
|
BALMLayout::Left() const
|
||||||
|
{
|
||||||
|
return fLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the left variable.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
BALMLayout::SetLeft(XTab* left)
|
||||||
|
{
|
||||||
|
fLeft = left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the right variable.
|
||||||
|
*/
|
||||||
|
XTab*
|
||||||
|
BALMLayout::Right() const
|
||||||
|
{
|
||||||
|
return fRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the right variable.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
BALMLayout::SetRight(XTab* right)
|
||||||
|
{
|
||||||
|
fRight = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the top variable.
|
||||||
|
*/
|
||||||
|
YTab*
|
||||||
|
BALMLayout::Top() const
|
||||||
|
{
|
||||||
|
return fTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the top variable.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
BALMLayout::SetTop(YTab* top)
|
||||||
|
{
|
||||||
|
fTop = top;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the bottom variable.
|
||||||
|
*/
|
||||||
|
YTab*
|
||||||
|
BALMLayout::Bottom() const
|
||||||
|
{
|
||||||
|
return fBottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the bottom variable.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
BALMLayout::SetBottom(YTab* bottom)
|
||||||
|
{
|
||||||
|
fBottom = bottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse engineers a GUI and recovers an ALM specification.
|
||||||
|
* @param parent the parent container of the GUI
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
BALMLayout::RecoverLayout(BView* parent) {} // Still working on it.
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current layout style.
|
||||||
|
*/
|
||||||
|
LayoutStyleType
|
||||||
|
BALMLayout::LayoutStyle() const
|
||||||
|
{
|
||||||
|
return fLayoutStyle;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current layout style.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
BALMLayout::SetLayoutStyle(LayoutStyleType style)
|
||||||
|
{
|
||||||
|
fLayoutStyle = style;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds view to layout.
|
||||||
|
*/
|
||||||
|
BLayoutItem*
|
||||||
|
BALMLayout::AddView(BView* child)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds view to layout.
|
||||||
|
*/
|
||||||
|
BLayoutItem*
|
||||||
|
BALMLayout::AddView(int32 index, BView* child)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds item to layout.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
BALMLayout::AddItem(BLayoutItem* item)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds item to layout.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
BALMLayout::AddItem(int32 index, BLayoutItem* item)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes view from layout.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
BALMLayout::RemoveView(BView* child)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes item from layout.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
BALMLayout::RemoveItem(BLayoutItem* item)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes item from layout.
|
||||||
|
*/
|
||||||
|
BLayoutItem*
|
||||||
|
BALMLayout::RemoveItem(int32 index)
|
||||||
|
{
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets and gets minimum size.
|
||||||
|
*/
|
||||||
|
BSize BALMLayout::MinSize() {
|
||||||
|
if (fMinSize == Area::kUndefinedSize)
|
||||||
|
fMinSize = CalculateMinSize();
|
||||||
|
return fMinSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets and gets maximum size.
|
||||||
|
*/
|
||||||
|
BSize
|
||||||
|
BALMLayout::MaxSize()
|
||||||
|
{
|
||||||
|
if (fMaxSize == Area::kUndefinedSize)
|
||||||
|
fMaxSize = CalculateMaxSize();
|
||||||
|
return fMaxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets and gets preferred size.
|
||||||
|
*/
|
||||||
|
BSize
|
||||||
|
BALMLayout::PreferredSize()
|
||||||
|
{
|
||||||
|
if (fPreferredSize == Area::kUndefinedSize)
|
||||||
|
fPreferredSize = CalculatePreferredSize();
|
||||||
|
return fPreferredSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the alignment.
|
||||||
|
*/
|
||||||
|
BAlignment
|
||||||
|
BALMLayout::Alignment()
|
||||||
|
{
|
||||||
|
BAlignment alignment;
|
||||||
|
alignment.SetHorizontal(B_ALIGN_HORIZONTAL_CENTER);
|
||||||
|
alignment.SetVertical(B_ALIGN_VERTICAL_CENTER);
|
||||||
|
return alignment;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets whether the height of the layout depends on its width.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
BALMLayout::HasHeightForWidth()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the height of the layout depends on its width.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
BALMLayout::GetHeightForWidth(float width, float* min, float* max, float* preferred) {}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invalidates the layout.
|
||||||
|
* Resets minimum/maximum/preferred size.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
BALMLayout::InvalidateLayout()
|
||||||
|
{
|
||||||
|
fMinSize = Area::kUndefinedSize;
|
||||||
|
fMaxSize = Area::kUndefinedSize;
|
||||||
|
fPreferredSize = Area::kUndefinedSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate and set the layout.
|
||||||
|
* If no layout specification is given, a specification is reverse engineered automatically.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
BALMLayout::LayoutView()
|
||||||
|
{
|
||||||
|
// make sure that layout events occuring during layout are ignored
|
||||||
|
// i.e. activated is set to false during layout caluclation
|
||||||
|
if (!fActivated)
|
||||||
|
return;
|
||||||
|
fActivated = false;
|
||||||
|
|
||||||
|
if (View() == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// reverse engineer a layout specification if none was given
|
||||||
|
//~ if (this == NULL) RecoverLayout(View());
|
||||||
|
|
||||||
|
// if the layout engine is set to fit the GUI to the given size,
|
||||||
|
// then the given size is enforced by setting absolute positions for Right and Bottom
|
||||||
|
if (fLayoutStyle == FIT_TO_SIZE) {
|
||||||
|
Right()->SetRange(View()->Bounds().Width(), View()->Bounds().Width());
|
||||||
|
Bottom()->SetRange(View()->Bounds().Height(), View()->Bounds().Height());
|
||||||
|
}
|
||||||
|
|
||||||
|
SolveLayout();
|
||||||
|
|
||||||
|
// if new layout is infasible, use previous layout
|
||||||
|
if (Result() == INFEASIBLE) {
|
||||||
|
fActivated = true; // now layout calculation is allowed to run again
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Result() != OPTIMAL) {
|
||||||
|
Save("failed-layout.txt");
|
||||||
|
printf("Could not solve the layout specification (%d). ", Result());
|
||||||
|
printf("Saved specification in file failed-layout.txt\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// change the size of the GUI according to the calculated size
|
||||||
|
// if the layout engine was configured to do so
|
||||||
|
if (fLayoutStyle == ADJUST_SIZE) {
|
||||||
|
View()->ResizeTo(floor(Right()->Value() - Left()->Value() + 0.5),
|
||||||
|
floor(Bottom()->Value() - Top()->Value() + 0.5));
|
||||||
|
}
|
||||||
|
|
||||||
|
// set the calculated positions and sizes for every area
|
||||||
|
for (int32 i = 0; i < Areas()->CountItems(); i++)
|
||||||
|
((Area*)Areas()->ItemAt(i))->DoLayout();
|
||||||
|
|
||||||
|
fActivated = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the path of the performance log file.
|
||||||
|
*
|
||||||
|
* @return the path of the performance log file
|
||||||
|
*/
|
||||||
|
char*
|
||||||
|
BALMLayout::PerformancePath() const
|
||||||
|
{
|
||||||
|
return fPerformancePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the path of the performance log file.
|
||||||
|
*
|
||||||
|
* @param path the path of the performance log file
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
BALMLayout::SetPerformancePath(char* path)
|
||||||
|
{
|
||||||
|
fPerformancePath = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caculates the miminum size.
|
||||||
|
*/
|
||||||
|
BSize
|
||||||
|
BALMLayout::CalculateMinSize()
|
||||||
|
{
|
||||||
|
printf("CalculateMinSize");
|
||||||
|
BList* buf = ObjFunctionSummands();
|
||||||
|
SetObjFunctionSummands(new BList(2));
|
||||||
|
AddObjFunctionSummand(1.0, fRight);
|
||||||
|
AddObjFunctionSummand(1.0, fBottom);
|
||||||
|
SolveLayout();
|
||||||
|
SetObjFunctionSummands(buf);
|
||||||
|
UpdateObjFunction();
|
||||||
|
|
||||||
|
if (Result() == UNBOUNDED)
|
||||||
|
return Area::kMinSize;
|
||||||
|
if (Result() != OPTIMAL) {
|
||||||
|
Save("failed-layout.txt");
|
||||||
|
printf("Could not solve the layout specification (%d). Saved specification in file failed-layout.txt", Result());
|
||||||
|
}
|
||||||
|
|
||||||
|
return BSize(Right()->Value() - Left()->Value(), Bottom()->Value() - Top()->Value());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caculates the maximum size.
|
||||||
|
*/
|
||||||
|
BSize
|
||||||
|
BALMLayout::CalculateMaxSize()
|
||||||
|
{
|
||||||
|
printf("CalculateMaxSize");
|
||||||
|
BList* buf = ObjFunctionSummands();
|
||||||
|
SetObjFunctionSummands(new BList(2));
|
||||||
|
AddObjFunctionSummand(-1.0, fRight);
|
||||||
|
AddObjFunctionSummand(-1.0, fBottom);
|
||||||
|
SolveLayout();
|
||||||
|
SetObjFunctionSummands(buf);
|
||||||
|
UpdateObjFunction();
|
||||||
|
|
||||||
|
if (Result() == UNBOUNDED)
|
||||||
|
return Area::kMaxSize;
|
||||||
|
if (Result() != OPTIMAL) {
|
||||||
|
Save("failed-layout.txt");
|
||||||
|
printf("Could not solve the layout specification (%d). Saved specification in file failed-layout.txt", Result());
|
||||||
|
}
|
||||||
|
|
||||||
|
return BSize(Right()->Value() - Left()->Value(), Bottom()->Value() - Top()->Value());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Caculates the preferred size.
|
||||||
|
*/
|
||||||
|
BSize
|
||||||
|
BALMLayout::CalculatePreferredSize()
|
||||||
|
{
|
||||||
|
printf("CalculatePreferredSize");
|
||||||
|
SolveLayout();
|
||||||
|
if (Result() != OPTIMAL) {
|
||||||
|
Save("failed-layout.txt");
|
||||||
|
printf("Could not solve the layout specification (%d). Saved specification in file failed-layout.txt", Result());
|
||||||
|
}
|
||||||
|
|
||||||
|
return BSize(Right()->Value() - Left()->Value(), Bottom()->Value() - Top()->Value());
|
||||||
|
}
|
||||||
|
|
218
src/libs/alm/Column.cpp
Normal file
218
src/libs/alm/Column.cpp
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
#include "Column.h"
|
||||||
|
#include "BALMLayout.h"
|
||||||
|
#include "OperatorType.h"
|
||||||
|
#include "XTab.h"
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The left boundary of the column.
|
||||||
|
*/
|
||||||
|
XTab*
|
||||||
|
Column::Left() const
|
||||||
|
{
|
||||||
|
return fLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The right boundary of the column.
|
||||||
|
*/
|
||||||
|
XTab*
|
||||||
|
Column::Right() const
|
||||||
|
{
|
||||||
|
return fRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the column directly to the left of this column.
|
||||||
|
*/
|
||||||
|
Column*
|
||||||
|
Column::Previous() const
|
||||||
|
{
|
||||||
|
return fPrevious;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the column directly to the left of this column.
|
||||||
|
* May be null.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Column::SetPrevious(Column* value)
|
||||||
|
{
|
||||||
|
// if there should be no column directly left of this column, then we have to
|
||||||
|
// separate any such column and can remove any constraint that was used
|
||||||
|
// to glue this column to it
|
||||||
|
if (value == NULL) {
|
||||||
|
if (fPrevious == NULL) return;
|
||||||
|
fPrevious->fNext = NULL;
|
||||||
|
fPrevious->fNextGlue = NULL;
|
||||||
|
fPrevious = NULL;
|
||||||
|
delete fPreviousGlue;
|
||||||
|
fPreviousGlue = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise we have to set up the pointers and the glue constraint accordingly
|
||||||
|
if (value->fNext != NULL)
|
||||||
|
value->SetNext(NULL);
|
||||||
|
if (fPrevious != NULL)
|
||||||
|
SetPrevious(NULL);
|
||||||
|
|
||||||
|
fPrevious = value;
|
||||||
|
fPrevious->fNext = this;
|
||||||
|
value->fNextGlue = value->fRight->IsEqual(fLeft);
|
||||||
|
fPreviousGlue = value->fNextGlue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the column directly to the right of this column.
|
||||||
|
*/
|
||||||
|
Column*
|
||||||
|
Column::Next() const
|
||||||
|
{
|
||||||
|
return fNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the column directly to the right of this column.
|
||||||
|
* May be null.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Column::SetNext(Column* value)
|
||||||
|
{
|
||||||
|
// if there should be no column directly right of this column, then we have to
|
||||||
|
// separate any such column and can remove any constraint that was used
|
||||||
|
// to glue this column to it
|
||||||
|
if (value == NULL) {
|
||||||
|
if (fNext == NULL) return;
|
||||||
|
fNext->fPrevious = NULL;
|
||||||
|
fNext->fPreviousGlue = NULL;
|
||||||
|
fNext = NULL;
|
||||||
|
delete fNextGlue;
|
||||||
|
fNextGlue = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise we have to set up the pointers and the glue constraint accordingly
|
||||||
|
if (value->fPrevious != NULL)
|
||||||
|
value->SetPrevious(NULL);
|
||||||
|
if (fNext != NULL)
|
||||||
|
SetNext(NULL);
|
||||||
|
|
||||||
|
fNext = value;
|
||||||
|
fNext->fPrevious = this;
|
||||||
|
value->fPreviousGlue = fRight->IsEqual(value->fLeft);
|
||||||
|
fNextGlue = value->fPreviousGlue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//~ string Column::ToString() {
|
||||||
|
//~ return "Column(" + fLeft.ToString() + ", " + fRight.ToString() + ")";
|
||||||
|
//~ }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts the given column directly to the left of this column.
|
||||||
|
*
|
||||||
|
* @param column the column to insert
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Column::InsertBefore(Column* column)
|
||||||
|
{
|
||||||
|
SetPrevious(column->fPrevious);
|
||||||
|
SetNext(column);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts the given column directly to the right of this column.
|
||||||
|
*
|
||||||
|
* @param column the column to insert
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Column::InsertAfter(Column* column)
|
||||||
|
{
|
||||||
|
SetNext(column->fNext);
|
||||||
|
SetPrevious(column);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constrains this column to have the same width as the given column.
|
||||||
|
*
|
||||||
|
* @param column the column that should have the same width
|
||||||
|
* @return the resulting same-width constraint
|
||||||
|
*/
|
||||||
|
Constraint*
|
||||||
|
Column::HasSameWidthAs(Column* column)
|
||||||
|
{
|
||||||
|
BList* coeffs = new BList(4);
|
||||||
|
coeffs->AddItem(new double(-1.0));
|
||||||
|
coeffs->AddItem(new double(1.0));
|
||||||
|
coeffs->AddItem(new double(1.0));
|
||||||
|
coeffs->AddItem(new double(-1.0));
|
||||||
|
|
||||||
|
BList* vars = new BList(4);
|
||||||
|
vars->AddItem(fLeft);
|
||||||
|
vars->AddItem(fRight);
|
||||||
|
vars->AddItem(column->fLeft);
|
||||||
|
vars->AddItem(column->fRight);
|
||||||
|
|
||||||
|
Constraint* constraint = fLS->AddConstraint(coeffs, vars, OperatorType(EQ), 0.0);
|
||||||
|
fConstraints->AddItem(constraint);
|
||||||
|
return constraint;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the constraints.
|
||||||
|
*/
|
||||||
|
BList*
|
||||||
|
Column::Constraints() const
|
||||||
|
{
|
||||||
|
return fConstraints;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the constraints.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Column::SetConstraints(BList* constraints)
|
||||||
|
{
|
||||||
|
fConstraints = constraints;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor.
|
||||||
|
* Removes the column from the specification.
|
||||||
|
*/
|
||||||
|
Column::~Column()
|
||||||
|
{
|
||||||
|
if (fPrevious != NULL)
|
||||||
|
fPrevious->SetNext(fNext);
|
||||||
|
for (int32 i = 0; i < fConstraints->CountItems(); i++)
|
||||||
|
delete (Constraint*)fConstraints->ItemAt(i);
|
||||||
|
delete fLeft;
|
||||||
|
delete fRight;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
Column::Column(BALMLayout* ls)
|
||||||
|
{
|
||||||
|
fLS = ls;
|
||||||
|
fLeft = new XTab(ls);
|
||||||
|
fRight = new XTab(ls);
|
||||||
|
fConstraints = new BList(1);
|
||||||
|
}
|
||||||
|
|
17
src/libs/alm/Jamfile
Normal file
17
src/libs/alm/Jamfile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
SubDir HAIKU_TOP src libs alm ;
|
||||||
|
|
||||||
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
|
||||||
|
UseLibraryHeaders lp_solve linprog alm ;
|
||||||
|
|
||||||
|
SharedLibrary libalm.so :
|
||||||
|
Area.cpp
|
||||||
|
Column.cpp
|
||||||
|
BALMLayout.cpp
|
||||||
|
Row.cpp
|
||||||
|
XTab.cpp
|
||||||
|
YTab.cpp
|
||||||
|
:
|
||||||
|
be liblpsolve55.so liblinprog.so
|
||||||
|
;
|
||||||
|
|
220
src/libs/alm/Row.cpp
Normal file
220
src/libs/alm/Row.cpp
Normal file
@ -0,0 +1,220 @@
|
|||||||
|
#include "Row.h"
|
||||||
|
#include "BALMLayout.h"
|
||||||
|
#include "OperatorType.h"
|
||||||
|
#include "YTab.h"
|
||||||
|
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The top boundary of the row.
|
||||||
|
*/
|
||||||
|
YTab*
|
||||||
|
Row::Top() const
|
||||||
|
{
|
||||||
|
return fTop;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The bottom boundary of the row.
|
||||||
|
*/
|
||||||
|
YTab*
|
||||||
|
Row::Bottom() const
|
||||||
|
{
|
||||||
|
return fBottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the row directly above this row.
|
||||||
|
*/
|
||||||
|
Row*
|
||||||
|
Row::Previous() const
|
||||||
|
{
|
||||||
|
return fPrevious;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the row directly above this row.
|
||||||
|
* May be null.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Row::SetPrevious(Row* value)
|
||||||
|
{
|
||||||
|
// if there should be no row directly above this row, then we have to
|
||||||
|
// separate any such row and can remove any constraint that was used
|
||||||
|
// to glue this row to it
|
||||||
|
if (value == NULL) {
|
||||||
|
if (fPrevious == NULL)
|
||||||
|
return;
|
||||||
|
fPrevious->fNext = NULL;
|
||||||
|
fPrevious->fNextGlue = NULL;
|
||||||
|
fPrevious = NULL;
|
||||||
|
delete fPreviousGlue;
|
||||||
|
fPreviousGlue = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise we have to set up the pointers and the glue constraint accordingly
|
||||||
|
if (value->fNext != NULL)
|
||||||
|
value->SetNext(NULL);
|
||||||
|
if (fPrevious != NULL)
|
||||||
|
SetPrevious(NULL);
|
||||||
|
|
||||||
|
fPrevious = value;
|
||||||
|
fPrevious->fNext = this;
|
||||||
|
value->fNextGlue = value->fBottom->IsEqual(fTop);
|
||||||
|
fPreviousGlue = value->fNextGlue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the row directly below this row.
|
||||||
|
*/
|
||||||
|
Row*
|
||||||
|
Row::Next() const
|
||||||
|
{
|
||||||
|
return fNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the row directly below this row.
|
||||||
|
* May be null.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Row::SetNext(Row* value)
|
||||||
|
{
|
||||||
|
// if there should be no row directly below this row, then we have to
|
||||||
|
// separate any such row and can remove any constraint that was used
|
||||||
|
// to glue this row to it
|
||||||
|
if (value == NULL) {
|
||||||
|
if (fNext == NULL)
|
||||||
|
return;
|
||||||
|
fNext->fPrevious = NULL;
|
||||||
|
fNext->fPreviousGlue = NULL;
|
||||||
|
fNext = NULL;
|
||||||
|
delete fNextGlue;
|
||||||
|
fNextGlue = NULL;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// otherwise we have to set up the pointers and the glue constraint accordingly
|
||||||
|
if (value->fPrevious != NULL)
|
||||||
|
value->SetPrevious(NULL);
|
||||||
|
if (fNext != NULL)
|
||||||
|
SetNext(NULL);
|
||||||
|
|
||||||
|
fNext = value;
|
||||||
|
fNext->fPrevious = this;
|
||||||
|
value->fPreviousGlue = fBottom->IsEqual(value->fTop);
|
||||||
|
fNextGlue = value->fPreviousGlue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//~ string Row::ToString() {
|
||||||
|
//~ return "Row(" + fTop.ToString() + ", " + fBottom.ToString() + ")";
|
||||||
|
//~ }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts the given row directly above this row.
|
||||||
|
*
|
||||||
|
* @param row the row to insert
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Row::InsertBefore(Row* row)
|
||||||
|
{
|
||||||
|
SetPrevious(row->fPrevious);
|
||||||
|
SetNext(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts the given row directly below this row.
|
||||||
|
*
|
||||||
|
* @param row the row to insert
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Row::InsertAfter(Row* row)
|
||||||
|
{
|
||||||
|
SetNext(row->fNext);
|
||||||
|
SetPrevious(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constrains this row to have the same height as the given row.
|
||||||
|
*
|
||||||
|
* @param row the row that should have the same height
|
||||||
|
* @return the resulting same-height constraint
|
||||||
|
*/
|
||||||
|
Constraint*
|
||||||
|
Row::HasSameHeightAs(Row* row)
|
||||||
|
{
|
||||||
|
BList* coeffs = new BList(4);
|
||||||
|
coeffs->AddItem(new double(-1.0));
|
||||||
|
coeffs->AddItem(new double(1.0));
|
||||||
|
coeffs->AddItem(new double(1.0));
|
||||||
|
coeffs->AddItem(new double(-1.0));
|
||||||
|
|
||||||
|
BList* vars = new BList(4);
|
||||||
|
vars->AddItem(fTop);
|
||||||
|
vars->AddItem(fBottom);
|
||||||
|
vars->AddItem(row->fTop);
|
||||||
|
vars->AddItem(row->fBottom);
|
||||||
|
|
||||||
|
Constraint* constraint = fLS->AddConstraint(coeffs, vars, OperatorType(EQ), 0.0);
|
||||||
|
fConstraints->AddItem(constraint);
|
||||||
|
return constraint;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the constraints.
|
||||||
|
*/
|
||||||
|
BList*
|
||||||
|
Row::Constraints() const
|
||||||
|
{
|
||||||
|
return fConstraints;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the constraints.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Row::SetConstraints(BList* constraints)
|
||||||
|
{
|
||||||
|
fConstraints = constraints;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor.
|
||||||
|
* Removes the row from the specification.
|
||||||
|
*/
|
||||||
|
Row::~Row()
|
||||||
|
{
|
||||||
|
if (fPrevious != NULL)
|
||||||
|
fPrevious->SetNext(fNext);
|
||||||
|
for (int32 i = 0; i < fConstraints->CountItems(); i++)
|
||||||
|
delete (Constraint*)fConstraints->ItemAt(i);
|
||||||
|
delete fTop;
|
||||||
|
delete fBottom;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
Row::Row(BALMLayout* ls)
|
||||||
|
{
|
||||||
|
fLS = ls;
|
||||||
|
fTop = new YTab(ls);
|
||||||
|
fBottom = new YTab(ls);
|
||||||
|
fConstraints = new BList(1);
|
||||||
|
}
|
||||||
|
|
13
src/libs/alm/XTab.cpp
Normal file
13
src/libs/alm/XTab.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include "XTab.h"
|
||||||
|
#include "BALMLayout.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
XTab::XTab(BALMLayout* ls)
|
||||||
|
: Variable(ls)
|
||||||
|
{
|
||||||
|
fLeftLink = false;
|
||||||
|
}
|
||||||
|
|
13
src/libs/alm/YTab.cpp
Normal file
13
src/libs/alm/YTab.cpp
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#include "YTab.h"
|
||||||
|
#include "BALMLayout.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
YTab::YTab(BALMLayout* ls)
|
||||||
|
: Variable(ls)
|
||||||
|
{
|
||||||
|
fTopLink = false;
|
||||||
|
}
|
||||||
|
|
206
src/libs/linprog/Constraint.cpp
Normal file
206
src/libs/linprog/Constraint.cpp
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
#include "Constraint.h"
|
||||||
|
#include "LinearSpec.h"
|
||||||
|
#include "Variable.h"
|
||||||
|
|
||||||
|
#include "lp_lib.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the index of the constraint.
|
||||||
|
*
|
||||||
|
* @return the index of the constraint
|
||||||
|
*/
|
||||||
|
int32
|
||||||
|
Constraint::Index()
|
||||||
|
{
|
||||||
|
int32 i = fLS->Constraints()->IndexOf(this);
|
||||||
|
if (i == -1)
|
||||||
|
printf("Constraint not part of fLS->Constraints().");
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the coefficients of the constraint.
|
||||||
|
*
|
||||||
|
* @return the coefficients of the constraint
|
||||||
|
*/
|
||||||
|
BList*
|
||||||
|
Constraint::Coeffs()
|
||||||
|
{
|
||||||
|
return fCoeffs;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the variables of the constraint.
|
||||||
|
*
|
||||||
|
* @return the variables of the constraint
|
||||||
|
*/
|
||||||
|
BList*
|
||||||
|
Constraint::Vars()
|
||||||
|
{
|
||||||
|
return fVars;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the left side of the constraint, i.e. its coefficients and variables.
|
||||||
|
* There must be exactly one coefficient for each variable.
|
||||||
|
*
|
||||||
|
* @param coeffs the new coefficients
|
||||||
|
* @param vars the new variables
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Constraint::ChangeLeftSide(BList* coeffs, BList* vars)
|
||||||
|
{
|
||||||
|
int32 sizeCoeffs = coeffs->CountItems();
|
||||||
|
int32 sizeVars = vars->CountItems();
|
||||||
|
if (sizeCoeffs != sizeVars)
|
||||||
|
printf("Number of coefficients and number of variables in a constraint must be equal.");
|
||||||
|
|
||||||
|
fCoeffs = coeffs;
|
||||||
|
fVars = vars;
|
||||||
|
|
||||||
|
double coeffsArray[sizeCoeffs];
|
||||||
|
for (int32 i = 0; i < sizeCoeffs; i++)
|
||||||
|
coeffsArray[i] = *(double*)coeffs->ItemAt(i);
|
||||||
|
|
||||||
|
int vIndexes[sizeCoeffs];
|
||||||
|
for (int32 i = 0; i < sizeVars; i++)
|
||||||
|
vIndexes[i] = ((Variable*)vars->ItemAt(i))->Index();
|
||||||
|
|
||||||
|
if (!set_rowex(fLS->LP(), this->Index(), sizeCoeffs, &coeffsArray[0], &vIndexes[0]))
|
||||||
|
printf("Error in set_rowex.");
|
||||||
|
|
||||||
|
fLS->RemovePresolved();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the operator used for this constraint.
|
||||||
|
*
|
||||||
|
* @return the operator used for this constraint
|
||||||
|
*/
|
||||||
|
OperatorType
|
||||||
|
Constraint::Op()
|
||||||
|
{
|
||||||
|
return fOp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the operator used for this constraint.
|
||||||
|
*
|
||||||
|
* @param value operator
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Constraint::SetOp(OperatorType value)
|
||||||
|
{
|
||||||
|
fOp = value;
|
||||||
|
if (!set_constr_type(fLS->LP(), this->Index(),
|
||||||
|
((fOp == OperatorType(EQ)) ? EQ
|
||||||
|
: (fOp == OperatorType(GE)) ? GE
|
||||||
|
: LE)))
|
||||||
|
printf("Error in set_constr_type.");
|
||||||
|
|
||||||
|
fLS->RemovePresolved();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets 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
|
||||||
|
Constraint::RightSide()
|
||||||
|
{
|
||||||
|
return fRightSide;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the constant value that is on the right side of the operator.
|
||||||
|
*
|
||||||
|
* @param value constant value that is on the right side of the operator
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Constraint::SetRightSide(double value)
|
||||||
|
{
|
||||||
|
fRightSide = value;
|
||||||
|
if (!set_rh(fLS->LP(), Index(), fRightSide))
|
||||||
|
printf("Error in set_rh.");
|
||||||
|
|
||||||
|
fLS->RemovePresolved();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Needs to be fixed. Use BString. Substring?
|
||||||
|
//~ string Constraint::ToString() {
|
||||||
|
//~ string s = "";
|
||||||
|
//~ for (int32 i = 0; i < fVars->CountItems(); i++)
|
||||||
|
//~ s += (double)fCoeffs->ItemAt(i) + "*" + (Variable*)fVars->ItemAt(i).ToString() + " + ";
|
||||||
|
//~ s = s.Substring(0, s.Length - 2);
|
||||||
|
//~ if (Op == OperatorType.EQ) s += "= ";
|
||||||
|
//~ else if (Op == OperatorType.GE) s += ">= ";
|
||||||
|
//~ else s += "<= ";
|
||||||
|
//~ s += rightSide.ToString();
|
||||||
|
//~ return s;
|
||||||
|
//~ }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor.
|
||||||
|
* Removes the constraint from its specification.
|
||||||
|
*/
|
||||||
|
Constraint::~Constraint()
|
||||||
|
{
|
||||||
|
del_constraint(fLS->LP(), Index());
|
||||||
|
delete fCoeffs;
|
||||||
|
delete fVars;
|
||||||
|
fLS->Constraints()->RemoveItem(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor.
|
||||||
|
*/
|
||||||
|
Constraint::Constraint() {}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
Constraint::Constraint(LinearSpec* ls, BList* coeffs, BList* vars, OperatorType op,
|
||||||
|
double rightSide)
|
||||||
|
{
|
||||||
|
|
||||||
|
int32 sizeCoeffs = coeffs->CountItems();
|
||||||
|
int32 sizeVars = vars->CountItems();
|
||||||
|
if (sizeCoeffs != sizeVars)
|
||||||
|
printf("Number of coefficients and number of variables in a constraint must be equal.");
|
||||||
|
|
||||||
|
fLS = ls;
|
||||||
|
fCoeffs = coeffs;
|
||||||
|
fVars = vars;
|
||||||
|
fOp = op;
|
||||||
|
fRightSide = rightSide;
|
||||||
|
|
||||||
|
double coeffsArray[sizeCoeffs];
|
||||||
|
for (int32 i = 0; i < sizeCoeffs; i++)
|
||||||
|
coeffsArray[i] = *(double*)coeffs->ItemAt(i);
|
||||||
|
|
||||||
|
int vIndexes[sizeCoeffs];
|
||||||
|
for (int32 i = 0; i < sizeVars; i++)
|
||||||
|
vIndexes[i] = ((Variable*)vars->ItemAt(i))->Index();
|
||||||
|
|
||||||
|
if (!add_constraintex(ls->LP(), sizeCoeffs, &coeffsArray[0], &vIndexes[0],
|
||||||
|
((op == OperatorType(EQ)) ? EQ
|
||||||
|
: (op == OperatorType(GE)) ? GE
|
||||||
|
: LE), rightSide))
|
||||||
|
printf("Error in add_constraintex.");
|
||||||
|
|
||||||
|
ls->Constraints()->AddItem(this);
|
||||||
|
}
|
||||||
|
|
17
src/libs/linprog/Jamfile
Normal file
17
src/libs/linprog/Jamfile
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
SubDir HAIKU_TOP src libs linprog ;
|
||||||
|
|
||||||
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
|
||||||
|
UseLibraryHeaders lp_solve linprog ;
|
||||||
|
|
||||||
|
SharedLibrary liblinprog.so :
|
||||||
|
Constraint.cpp
|
||||||
|
LinearSpec.cpp
|
||||||
|
ObjFunctionSummand.cpp
|
||||||
|
PenaltyFunction.cpp
|
||||||
|
SoftConstraint.cpp
|
||||||
|
Variable.cpp
|
||||||
|
:
|
||||||
|
be liblpsolve55.so
|
||||||
|
;
|
||||||
|
|
736
src/libs/linprog/LinearSpec.cpp
Normal file
736
src/libs/linprog/LinearSpec.cpp
Normal file
@ -0,0 +1,736 @@
|
|||||||
|
#include "LinearSpec.h"
|
||||||
|
#include "Constraint.h"
|
||||||
|
#include "ObjFunctionSummand.h"
|
||||||
|
#include "PenaltyFunction.h"
|
||||||
|
#include "SoftConstraint.h"
|
||||||
|
#include "Variable.h"
|
||||||
|
|
||||||
|
#include "lp_lib.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
* Creates a new specification for a linear programming problem.
|
||||||
|
*/
|
||||||
|
LinearSpec::LinearSpec()
|
||||||
|
{
|
||||||
|
fLP = make_lp(0, 0);
|
||||||
|
if (fLP == NULL)
|
||||||
|
printf("Couldn't construct a new model.");
|
||||||
|
set_verbose(fLP, 1);
|
||||||
|
|
||||||
|
fObjFunctionSummands = new BList(1);
|
||||||
|
fVariables = new BList(1);
|
||||||
|
fConstraints = new BList(1);
|
||||||
|
fColumns = 0;
|
||||||
|
fLpPresolved = NULL;
|
||||||
|
fOptimization = MINIMIZE;
|
||||||
|
fResult = ERROR;
|
||||||
|
fObjectiveValue = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor.
|
||||||
|
* Removes the specification.
|
||||||
|
*/
|
||||||
|
LinearSpec::~LinearSpec()
|
||||||
|
{
|
||||||
|
delete_lp(fLP);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the objective function.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
LinearSpec::UpdateObjFunction()
|
||||||
|
{
|
||||||
|
int32 size = fObjFunctionSummands->CountItems();;
|
||||||
|
double coeffs[size];
|
||||||
|
int vIndexes[size];
|
||||||
|
ObjFunctionSummand* current;
|
||||||
|
for (int32 i = 0; i < size; i++) {
|
||||||
|
current = (ObjFunctionSummand*)fObjFunctionSummands->ItemAt(i);
|
||||||
|
coeffs[i] = current->Coeff();
|
||||||
|
vIndexes[i] = current->Var()->Index();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!set_obj_fnex(fLP, size, &coeffs[0], &vIndexes[0]))
|
||||||
|
printf("Error in set_obj_fnex.");
|
||||||
|
|
||||||
|
RemovePresolved();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the objective function.
|
||||||
|
*
|
||||||
|
* @param coeffs the objective function's coefficients
|
||||||
|
* @param vars the objective function's variables
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
LinearSpec::SetObjFunction(BList* coeffs, BList* vars)
|
||||||
|
{
|
||||||
|
int32 sizeCoeffs = coeffs->CountItems();
|
||||||
|
int32 sizeVars = vars->CountItems();
|
||||||
|
if (sizeCoeffs != sizeVars)
|
||||||
|
printf("Number of coefficients and number of fVariables in objective function must be equal.");
|
||||||
|
|
||||||
|
fObjFunctionSummands = new BList(1);
|
||||||
|
for (int32 i = 0; i < sizeCoeffs; i++)
|
||||||
|
fObjFunctionSummands->AddItem(new ObjFunctionSummand(this,
|
||||||
|
*(double*)coeffs->ItemAt(i), (Variable*)vars->ItemAt(i)));
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new variable to the specification.
|
||||||
|
*
|
||||||
|
* @return the new variable
|
||||||
|
*/
|
||||||
|
Variable*
|
||||||
|
LinearSpec::AddVariable()
|
||||||
|
{
|
||||||
|
return new Variable(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new hard linear constraint to the specification.
|
||||||
|
*
|
||||||
|
* @param coeffs the constraint's coefficients
|
||||||
|
* @param vars the constraint's variables
|
||||||
|
* @param op the constraint's operand
|
||||||
|
* @param rightSide the constant value on the constraint's right side
|
||||||
|
* @return the new constraint
|
||||||
|
*/
|
||||||
|
Constraint*
|
||||||
|
LinearSpec::AddConstraint(BList* coeffs, BList* vars, OperatorType op,
|
||||||
|
double rightSide)
|
||||||
|
{
|
||||||
|
Constraint* c = new Constraint(this, coeffs, vars, op, rightSide);
|
||||||
|
RemovePresolved();
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new hard linear constraint to the specification with a single summand.
|
||||||
|
*
|
||||||
|
* @param coeff1 the constraint's first coefficient
|
||||||
|
* @param var1 the constraint's first variable
|
||||||
|
* @param op the constraint's operand
|
||||||
|
* @param rightSide the constant value on the constraint's right side
|
||||||
|
* @return the new constraint
|
||||||
|
*/
|
||||||
|
Constraint*
|
||||||
|
LinearSpec::AddConstraint(double coeff1, Variable* var1,
|
||||||
|
OperatorType op, double rightSide)
|
||||||
|
{
|
||||||
|
BList* coeffs = new BList(1);
|
||||||
|
coeffs->AddItem(new double(coeff1));
|
||||||
|
BList* vars = new BList(1);
|
||||||
|
vars->AddItem(var1);
|
||||||
|
Constraint* c = AddConstraint(coeffs, vars, op, rightSide);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new hard linear constraint to the specification with two summands.
|
||||||
|
*
|
||||||
|
* @param coeff1 the constraint's first coefficient
|
||||||
|
* @param var1 the constraint's first variable
|
||||||
|
* @param coeff2 the constraint's second coefficient
|
||||||
|
* @param var2 the constraint's second variable
|
||||||
|
* @param op the constraint's operand
|
||||||
|
* @param rightSide the constant value on the constraint's right side
|
||||||
|
* @return the new constraint
|
||||||
|
*/
|
||||||
|
Constraint*
|
||||||
|
LinearSpec::AddConstraint(double coeff1, Variable* var1,
|
||||||
|
double coeff2, Variable* var2, OperatorType op, double rightSide)
|
||||||
|
{
|
||||||
|
BList* coeffs = new BList(2);
|
||||||
|
coeffs->AddItem(new double(coeff1));
|
||||||
|
coeffs->AddItem(new double(coeff2));
|
||||||
|
BList* vars = new BList(2);
|
||||||
|
vars->AddItem(var1);
|
||||||
|
vars->AddItem(var2);
|
||||||
|
Constraint* c = AddConstraint(coeffs, vars, op, rightSide);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new hard linear constraint to the specification with three summands.
|
||||||
|
*
|
||||||
|
* @param coeff1 the constraint's first coefficient
|
||||||
|
* @param var1 the constraint's first variable
|
||||||
|
* @param coeff2 the constraint's second coefficient
|
||||||
|
* @param var2 the constraint's second variable
|
||||||
|
* @param coeff3 the constraint's third coefficient
|
||||||
|
* @param var3 the constraint's third variable
|
||||||
|
* @param op the constraint's operand
|
||||||
|
* @param rightSide the constant value on the constraint's right side
|
||||||
|
* @return the new constraint
|
||||||
|
*/
|
||||||
|
Constraint*
|
||||||
|
LinearSpec::AddConstraint(double coeff1, Variable* var1,
|
||||||
|
double coeff2, Variable* var2, double coeff3, Variable* var3,
|
||||||
|
OperatorType op, double rightSide)
|
||||||
|
{
|
||||||
|
BList* coeffs = new BList(3);
|
||||||
|
coeffs->AddItem(new double(coeff1));
|
||||||
|
coeffs->AddItem(new double(coeff2));
|
||||||
|
coeffs->AddItem(new double(coeff3));
|
||||||
|
BList* vars = new BList(3);
|
||||||
|
vars->AddItem(var1);
|
||||||
|
vars->AddItem(var2);
|
||||||
|
vars->AddItem(var3);
|
||||||
|
Constraint* c = AddConstraint(coeffs, vars, op, rightSide);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new hard linear constraint to the specification with four summands.
|
||||||
|
*
|
||||||
|
* @param coeff1 the constraint's first coefficient
|
||||||
|
* @param var1 the constraint's first variable
|
||||||
|
* @param coeff2 the constraint's second coefficient
|
||||||
|
* @param var2 the constraint's second variable
|
||||||
|
* @param coeff3 the constraint's third coefficient
|
||||||
|
* @param var3 the constraint's third variable
|
||||||
|
* @param coeff4 the constraint's fourth coefficient
|
||||||
|
* @param var4 the constraint's fourth variable
|
||||||
|
* @param op the constraint's operand
|
||||||
|
* @param rightSide the constant value on the constraint's right side
|
||||||
|
* @return the new constraint
|
||||||
|
*/
|
||||||
|
Constraint*
|
||||||
|
LinearSpec::AddConstraint(double coeff1, Variable* var1,
|
||||||
|
double coeff2, Variable* var2, double coeff3, Variable* var3,
|
||||||
|
double coeff4, Variable* var4, OperatorType op, double rightSide)
|
||||||
|
{
|
||||||
|
BList* coeffs = new BList(4);
|
||||||
|
coeffs->AddItem(new double(coeff1));
|
||||||
|
coeffs->AddItem(new double(coeff2));
|
||||||
|
coeffs->AddItem(new double(coeff3));
|
||||||
|
coeffs->AddItem(new double(coeff4));
|
||||||
|
BList* vars = new BList(4);
|
||||||
|
vars->AddItem(var1);
|
||||||
|
vars->AddItem(var2);
|
||||||
|
vars->AddItem(var3);
|
||||||
|
vars->AddItem(var4);
|
||||||
|
Constraint* c = AddConstraint(coeffs, vars, op, rightSide);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new soft linear constraint to the specification.
|
||||||
|
* i.e. a constraint that does not always have to be satisfied.
|
||||||
|
*
|
||||||
|
* @param coeffs the constraint's coefficients
|
||||||
|
* @param vars the constraint's variables
|
||||||
|
* @param op the constraint's operand
|
||||||
|
* @param rightSide the constant value on the constraint's right side
|
||||||
|
* @param penaltyNeg the coefficient penalizing negative deviations from the exact solution
|
||||||
|
* @param penaltyPos the coefficient penalizing positive deviations from the exact solution
|
||||||
|
*/
|
||||||
|
SoftConstraint*
|
||||||
|
LinearSpec::AddSoftConstraint(BList* coeffs, BList* vars, OperatorType op,
|
||||||
|
double rightSide, double penaltyNeg, double penaltyPos)
|
||||||
|
{
|
||||||
|
SoftConstraint* c = new SoftConstraint(this, coeffs, vars, op, rightSide,
|
||||||
|
penaltyNeg, penaltyPos);
|
||||||
|
|
||||||
|
RemovePresolved();
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new soft linear constraint to the specification with a single summand.
|
||||||
|
*
|
||||||
|
* @param coeff1 the constraint's first coefficient
|
||||||
|
* @param var1 the constraint's first variable
|
||||||
|
* @param op the constraint's operand
|
||||||
|
* @param rightSide the constant value on the constraint's right side
|
||||||
|
* @param penaltyNeg the coefficient penalizing negative deviations from the exact solution
|
||||||
|
* @param penaltyPos the coefficient penalizing positive deviations from the exact solution
|
||||||
|
*/
|
||||||
|
SoftConstraint*
|
||||||
|
LinearSpec::AddSoftConstraint(double coeff1, Variable* var1,
|
||||||
|
OperatorType op, double rightSide, double penaltyNeg, double penaltyPos)
|
||||||
|
{
|
||||||
|
BList* coeffs = new BList(1);
|
||||||
|
coeffs->AddItem(new double(coeff1));
|
||||||
|
BList* vars = new BList(1);
|
||||||
|
vars->AddItem(var1);
|
||||||
|
SoftConstraint* c = AddSoftConstraint(coeffs, vars, op, rightSide,
|
||||||
|
penaltyNeg, penaltyPos);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new soft linear constraint to the specification with two summands.
|
||||||
|
*
|
||||||
|
* @param coeff1 the constraint's first coefficient
|
||||||
|
* @param var1 the constraint's first variable
|
||||||
|
* @param coeff2 the constraint's second coefficient
|
||||||
|
* @param var2 the constraint's second variable
|
||||||
|
* @param op the constraint's operand
|
||||||
|
* @param rightSide the constant value on the constraint's right side
|
||||||
|
* @param penaltyNeg the coefficient penalizing negative deviations from the exact solution
|
||||||
|
* @param penaltyPos the coefficient penalizing positive deviations from the exact solution
|
||||||
|
*/
|
||||||
|
SoftConstraint*
|
||||||
|
LinearSpec::AddSoftConstraint(double coeff1, Variable* var1,
|
||||||
|
double coeff2, Variable* var2, OperatorType op, double rightSide,
|
||||||
|
double penaltyNeg, double penaltyPos)
|
||||||
|
{
|
||||||
|
BList* coeffs = new BList(2);
|
||||||
|
coeffs->AddItem(new double(coeff1));
|
||||||
|
coeffs->AddItem(new double(coeff2));
|
||||||
|
BList* vars = new BList(2);
|
||||||
|
vars->AddItem(var1);
|
||||||
|
vars->AddItem(var2);
|
||||||
|
SoftConstraint* c = AddSoftConstraint(coeffs, vars, op, rightSide,
|
||||||
|
penaltyNeg, penaltyPos);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new soft linear constraint to the specification with three summands.
|
||||||
|
*
|
||||||
|
* @param coeff1 the constraint's first coefficient
|
||||||
|
* @param var1 the constraint's first variable
|
||||||
|
* @param coeff2 the constraint's second coefficient
|
||||||
|
* @param var2 the constraint's second variable
|
||||||
|
* @param coeff3 the constraint's third coefficient
|
||||||
|
* @param var3 the constraint's third variable
|
||||||
|
* @param op the constraint's operand
|
||||||
|
* @param rightSide the constant value on the constraint's right side
|
||||||
|
* @param penaltyNeg the coefficient penalizing negative deviations from the exact solution
|
||||||
|
* @param penaltyPos the coefficient penalizing positive deviations from the exact solution
|
||||||
|
*/
|
||||||
|
SoftConstraint*
|
||||||
|
LinearSpec::AddSoftConstraint(double coeff1, Variable* var1,
|
||||||
|
double coeff2, Variable* var2, double coeff3, Variable* var3,
|
||||||
|
OperatorType op, double rightSide, double penaltyNeg, double penaltyPos)
|
||||||
|
{
|
||||||
|
BList* coeffs = new BList(3);
|
||||||
|
coeffs->AddItem(new double(coeff1));
|
||||||
|
coeffs->AddItem(new double(coeff2));
|
||||||
|
coeffs->AddItem(new double(coeff3));
|
||||||
|
BList* vars = new BList(3);
|
||||||
|
vars->AddItem(var1);
|
||||||
|
vars->AddItem(var2);
|
||||||
|
vars->AddItem(var3);
|
||||||
|
SoftConstraint* c = AddSoftConstraint(coeffs, vars, op, rightSide,
|
||||||
|
penaltyNeg, penaltyPos);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new soft linear constraint to the specification with four summands.
|
||||||
|
*
|
||||||
|
* @param coeff1 the constraint's first coefficient
|
||||||
|
* @param var1 the constraint's first variable
|
||||||
|
* @param coeff2 the constraint's second coefficient
|
||||||
|
* @param var2 the constraint's second variable
|
||||||
|
* @param coeff3 the constraint's third coefficient
|
||||||
|
* @param var3 the constraint's third variable
|
||||||
|
* @param coeff4 the constraint's fourth coefficient
|
||||||
|
* @param var4 the constraint's fourth variable
|
||||||
|
* @param op the constraint's operand
|
||||||
|
* @param rightSide the constant value on the constraint's right side
|
||||||
|
* @param penaltyNeg the coefficient penalizing negative deviations from the exact solution
|
||||||
|
* @param penaltyPos the coefficient penalizing positive deviations from the exact solution
|
||||||
|
*/
|
||||||
|
SoftConstraint*
|
||||||
|
LinearSpec::AddSoftConstraint(double coeff1, Variable* var1,
|
||||||
|
double coeff2, Variable* var2, double coeff3, Variable* var3,
|
||||||
|
double coeff4, Variable* var4, OperatorType op, double rightSide,
|
||||||
|
double penaltyNeg, double penaltyPos)
|
||||||
|
{
|
||||||
|
BList* coeffs = new BList(4);
|
||||||
|
coeffs->AddItem(new double(coeff1));
|
||||||
|
coeffs->AddItem(new double(coeff2));
|
||||||
|
coeffs->AddItem(new double(coeff3));
|
||||||
|
coeffs->AddItem(new double(coeff4));
|
||||||
|
BList* vars = new BList(4);
|
||||||
|
vars->AddItem(var1);
|
||||||
|
vars->AddItem(var2);
|
||||||
|
vars->AddItem(var3);
|
||||||
|
vars->AddItem(var4);
|
||||||
|
SoftConstraint* c = AddSoftConstraint(coeffs, vars, op, rightSide,
|
||||||
|
penaltyNeg, penaltyPos);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a new penalty function to the specification.
|
||||||
|
*
|
||||||
|
* @param var the penalty function's variable
|
||||||
|
* @param xs the penalty function's sampling points
|
||||||
|
* @param gs the penalty function's gradients
|
||||||
|
* @return the new penalty function
|
||||||
|
*/
|
||||||
|
PenaltyFunction*
|
||||||
|
LinearSpec::AddPenaltyFunction(Variable* var, BList* xs, BList* gs)
|
||||||
|
{
|
||||||
|
return new PenaltyFunction(this, var, xs, gs);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove a cached presolved model, if existent.
|
||||||
|
* This is automatically done each time after the model has been changed,
|
||||||
|
* to avoid an old cached presolved model getting out of sync.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
LinearSpec::RemovePresolved()
|
||||||
|
{
|
||||||
|
if (fLpPresolved == NULL)
|
||||||
|
return;
|
||||||
|
delete_lp(fLpPresolved);
|
||||||
|
fLpPresolved = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates and caches a simplified version of the linear programming problem,
|
||||||
|
* where redundant rows, columns and constraints are removed,
|
||||||
|
* if it has not been created before.
|
||||||
|
* Then, the simplified problem is solved.
|
||||||
|
*
|
||||||
|
* @return the result of the solving attempt
|
||||||
|
*/
|
||||||
|
ResultType
|
||||||
|
LinearSpec::Presolve()
|
||||||
|
{
|
||||||
|
bigtime_t start, end;
|
||||||
|
start = system_time();
|
||||||
|
|
||||||
|
if (fLpPresolved == NULL) {
|
||||||
|
fLpPresolved = copy_lp(fLP);
|
||||||
|
set_presolve(fLpPresolved, PRESOLVE_ROWS | PRESOLVE_COLS | PRESOLVE_LINDEP,
|
||||||
|
get_presolveloops(fLpPresolved));
|
||||||
|
}
|
||||||
|
|
||||||
|
fResult = (ResultType)solve(fLpPresolved);
|
||||||
|
fObjectiveValue = get_objective(fLpPresolved);
|
||||||
|
|
||||||
|
if (fResult == OPTIMAL) {
|
||||||
|
int32 size = fVariables->CountItems();
|
||||||
|
for (int32 i = 0; i < size; i++) {
|
||||||
|
Variable* current = (Variable*)fVariables->ItemAt(i);
|
||||||
|
current->SetValue(get_var_primalresult(fLpPresolved,
|
||||||
|
get_Norig_rows(fLpPresolved) + current->Index()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end = system_time();
|
||||||
|
fSolvingTime = (end - start) / 1000.0;
|
||||||
|
|
||||||
|
return fResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tries to solve the linear programming problem.
|
||||||
|
* If a cached simplified version of the problem exists, it is used instead.
|
||||||
|
*
|
||||||
|
* @return the result of the solving attempt
|
||||||
|
*/
|
||||||
|
ResultType
|
||||||
|
LinearSpec::Solve()
|
||||||
|
{
|
||||||
|
if (fLpPresolved != NULL)
|
||||||
|
return Presolve();
|
||||||
|
|
||||||
|
bigtime_t start, end;
|
||||||
|
start = system_time();
|
||||||
|
|
||||||
|
fResult = (ResultType)solve(fLP);
|
||||||
|
fObjectiveValue = get_objective(fLP);
|
||||||
|
|
||||||
|
if (fResult == OPTIMAL) {
|
||||||
|
int32 size = fVariables->CountItems();
|
||||||
|
double x[size];
|
||||||
|
if (!get_variables(fLP, &x[0]))
|
||||||
|
printf("Error in get_variables.");
|
||||||
|
|
||||||
|
int32 i = 0;
|
||||||
|
while (i < size) {
|
||||||
|
((Variable*)fVariables->ItemAt(i))->SetValue(x[i]);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
end = system_time();
|
||||||
|
fSolvingTime = (end - start) / 1000.0;
|
||||||
|
|
||||||
|
return fResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes the specification into a text file.
|
||||||
|
* The file will be overwritten if it exists.
|
||||||
|
*
|
||||||
|
* @param fname the file name
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
LinearSpec::Save(char* fname)
|
||||||
|
{
|
||||||
|
write_lp(fLP, fname);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the number of columns.
|
||||||
|
*
|
||||||
|
* @return the number of columns
|
||||||
|
*/
|
||||||
|
int32
|
||||||
|
LinearSpec::Columns() const
|
||||||
|
{
|
||||||
|
return fColumns;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the number of columns.
|
||||||
|
*
|
||||||
|
* @param value the number of columns
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
LinearSpec::SetColumns(int32 value)
|
||||||
|
{
|
||||||
|
fColumns = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current optimization.
|
||||||
|
* The default is minimization.
|
||||||
|
*
|
||||||
|
* @return the current optimization
|
||||||
|
*/
|
||||||
|
OptimizationType
|
||||||
|
LinearSpec::Optimization() const
|
||||||
|
{
|
||||||
|
return fOptimization;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the solver should minimize or maximize the objective function.
|
||||||
|
* The default is minimization.
|
||||||
|
*
|
||||||
|
* @param optimization the optimization type
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
LinearSpec::SetOptimization(OptimizationType value)
|
||||||
|
{
|
||||||
|
fOptimization = value;
|
||||||
|
if (fOptimization == MINIMIZE)
|
||||||
|
set_minim(fLP);
|
||||||
|
else
|
||||||
|
set_maxim(fLP);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
*
|
||||||
|
* @return the variables
|
||||||
|
*/
|
||||||
|
BList*
|
||||||
|
LinearSpec::Variables() const
|
||||||
|
{
|
||||||
|
return fVariables;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the the variables.
|
||||||
|
*
|
||||||
|
* @param value the variables
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
LinearSpec::SetVariables(BList* value)
|
||||||
|
{
|
||||||
|
fVariables = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the constraints.
|
||||||
|
*
|
||||||
|
* @return the constraints
|
||||||
|
*/
|
||||||
|
BList*
|
||||||
|
LinearSpec::Constraints() const
|
||||||
|
{
|
||||||
|
return fConstraints;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the constraints.
|
||||||
|
*
|
||||||
|
* @param value the constraints
|
||||||
|
*/
|
||||||
|
void LinearSpec::SetConstraints(BList* value) {
|
||||||
|
fConstraints = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the result type.
|
||||||
|
*
|
||||||
|
* @return the result type
|
||||||
|
*/
|
||||||
|
ResultType
|
||||||
|
LinearSpec::Result() const
|
||||||
|
{
|
||||||
|
return fResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the result type.
|
||||||
|
*
|
||||||
|
* @param value the result type
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
LinearSpec::SetResult(ResultType value)
|
||||||
|
{
|
||||||
|
fResult = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the objective value.
|
||||||
|
*
|
||||||
|
* @return the objective value
|
||||||
|
*/
|
||||||
|
double
|
||||||
|
LinearSpec::ObjectiveValue() const
|
||||||
|
{
|
||||||
|
return fObjectiveValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the objective value.
|
||||||
|
*
|
||||||
|
* @param value the objective value
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
LinearSpec::SetObjectiveValue(double value)
|
||||||
|
{
|
||||||
|
fObjectiveValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the solving time.
|
||||||
|
*
|
||||||
|
* @return the solving time
|
||||||
|
*/
|
||||||
|
double
|
||||||
|
LinearSpec::SolvingTime() const
|
||||||
|
{
|
||||||
|
return fSolvingTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the solving time.
|
||||||
|
*
|
||||||
|
* @param value the solving time
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
LinearSpec::SetSolvingTime(double value)
|
||||||
|
{
|
||||||
|
fSolvingTime = value;
|
||||||
|
}
|
||||||
|
|
76
src/libs/linprog/ObjFunctionSummand.cpp
Normal file
76
src/libs/linprog/ObjFunctionSummand.cpp
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
#include "ObjFunctionSummand.h"
|
||||||
|
#include "Variable.h"
|
||||||
|
#include "LinearSpec.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the summmand's coefficient.
|
||||||
|
*
|
||||||
|
* @return the summand's coefficient
|
||||||
|
*/
|
||||||
|
double
|
||||||
|
ObjFunctionSummand::Coeff()
|
||||||
|
{
|
||||||
|
return fCoeff;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the summmand's coefficient.
|
||||||
|
*
|
||||||
|
* @param coeff coefficient
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ObjFunctionSummand::SetCoeff(double coeff)
|
||||||
|
{
|
||||||
|
fCoeff = coeff;
|
||||||
|
fLS->UpdateObjFunction();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the summand's variable.
|
||||||
|
*
|
||||||
|
* @return the summand's variable
|
||||||
|
*/
|
||||||
|
Variable*
|
||||||
|
ObjFunctionSummand::Var()
|
||||||
|
{
|
||||||
|
return fVar;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the summand's variable.
|
||||||
|
*
|
||||||
|
* @param var variable
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ObjFunctionSummand::SetVar(Variable* var)
|
||||||
|
{
|
||||||
|
fVar = 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)
|
||||||
|
{
|
||||||
|
fLS = ls;
|
||||||
|
fCoeff = coeff;
|
||||||
|
fVar = var;
|
||||||
|
}
|
||||||
|
|
116
src/libs/linprog/PenaltyFunction.cpp
Normal file
116
src/libs/linprog/PenaltyFunction.cpp
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
#include "PenaltyFunction.h"
|
||||||
|
#include "Constraint.h"
|
||||||
|
#include "ObjFunctionSummand.h"
|
||||||
|
#include "OperatorType.h"
|
||||||
|
#include "Variable.h"
|
||||||
|
#include "LinearSpec.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
PenaltyFunction::PenaltyFunction(LinearSpec* ls, Variable* var, BList* xs, BList* gs)
|
||||||
|
{
|
||||||
|
int32 sizeXs = xs->CountItems();
|
||||||
|
int32 sizeGs = gs->CountItems();
|
||||||
|
if (var->LS() != ls)
|
||||||
|
printf("The variable must belong to the same linear specification as the penalty function.");
|
||||||
|
if (sizeXs + 1 != sizeGs)
|
||||||
|
printf("The number of sampling points must be exactly one less than the number of gradients.");
|
||||||
|
for (int32 i = 1; i < sizeGs; i++) {
|
||||||
|
if (*(double*)(gs->ItemAt(i - 1)) > *(double*)(gs->ItemAt(i)))
|
||||||
|
printf("Penalty function must be concave.");
|
||||||
|
}
|
||||||
|
|
||||||
|
fVar = var;
|
||||||
|
fXs = xs;
|
||||||
|
fGs = gs;
|
||||||
|
fConstraints = new BList(1);
|
||||||
|
fObjFunctionSummands = new BList(1);
|
||||||
|
|
||||||
|
BList* coeffs = new BList(1);
|
||||||
|
coeffs->AddItem(new double(1.0));
|
||||||
|
|
||||||
|
BList* vars = new BList(1);
|
||||||
|
vars->AddItem(var);
|
||||||
|
|
||||||
|
fConstraints->AddItem(ls->AddSoftConstraint(coeffs, vars, OperatorType(EQ),
|
||||||
|
*(double*)(xs->ItemAt(0)), -*(double*)(gs->ItemAt(0)),
|
||||||
|
*(double*)(gs->ItemAt(1))));
|
||||||
|
|
||||||
|
for (int32 i = 1; i < sizeGs; i++) {
|
||||||
|
Variable* dPos = ls->AddVariable();
|
||||||
|
|
||||||
|
BList* coeffs = new BList(2);
|
||||||
|
coeffs->AddItem(new double(1.0));
|
||||||
|
coeffs->AddItem(new double(-1.0));
|
||||||
|
|
||||||
|
BList* vars = new BList(2);
|
||||||
|
vars->AddItem(var);
|
||||||
|
vars->AddItem(dPos);
|
||||||
|
|
||||||
|
fConstraints->AddItem(ls->AddConstraint(coeffs, vars, OperatorType(LE),
|
||||||
|
*(double*)(xs->ItemAt(i))));
|
||||||
|
|
||||||
|
fObjFunctionSummands->AddItem(ls->AddObjFunctionSummand(
|
||||||
|
*(double*)(gs->ItemAt(i + 1)) - *(double*)(gs->ItemAt(i)), dPos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor.
|
||||||
|
* Removes all constraints and summands from the penalty function.
|
||||||
|
*/
|
||||||
|
PenaltyFunction::~PenaltyFunction()
|
||||||
|
{
|
||||||
|
int32 sizeConstraints = fConstraints->CountItems();
|
||||||
|
for (int32 i = 0; i < sizeConstraints; i++) {
|
||||||
|
Constraint* currentConstraint = (Constraint*)fConstraints->ItemAt(i);
|
||||||
|
delete currentConstraint;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32 sizeObjFunctionSummands = fObjFunctionSummands->CountItems();
|
||||||
|
for (int32 i = 0; i < sizeObjFunctionSummands; 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;
|
||||||
|
}
|
||||||
|
|
235
src/libs/linprog/SoftConstraint.cpp
Normal file
235
src/libs/linprog/SoftConstraint.cpp
Normal file
@ -0,0 +1,235 @@
|
|||||||
|
#include "SoftConstraint.h"
|
||||||
|
#include "ObjFunctionSummand.h"
|
||||||
|
#include "Variable.h"
|
||||||
|
#include "LinearSpec.h"
|
||||||
|
|
||||||
|
#include "lp_lib.h"
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Changes the left side of the soft constraint, i.e. its coefficients and variables.
|
||||||
|
* There must be exactly one coefficient for each variable.
|
||||||
|
*
|
||||||
|
* @param coeffs the constraint's coefficients
|
||||||
|
* @param vars the constraint's variables
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
SoftConstraint::ChangeLeftSide(BList* coeffs, BList* vars)
|
||||||
|
{
|
||||||
|
int32 sizeCoeffs = coeffs->CountItems();
|
||||||
|
int32 sizeVars = vars->CountItems();
|
||||||
|
if (sizeCoeffs != sizeVars)
|
||||||
|
printf("Number of coefficients and number of variables in a constraint must be equal.");
|
||||||
|
|
||||||
|
fCoeffs = coeffs;
|
||||||
|
fVars = vars;
|
||||||
|
|
||||||
|
int vIndexes[sizeCoeffs + 2];
|
||||||
|
double coeffs2[sizeCoeffs + 2];
|
||||||
|
|
||||||
|
int32 i;
|
||||||
|
for (i = 0; i < sizeVars; i++) {
|
||||||
|
vIndexes[i] = ((Variable*)vars->ItemAt(i))->Index();
|
||||||
|
coeffs2[i] = *(double*)coeffs->ItemAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fOp != OperatorType(LE)) {
|
||||||
|
vIndexes[i] = fDNegSummand->Var()->Index();
|
||||||
|
coeffs2[i] = 1.0;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fOp != OperatorType(GE)) {
|
||||||
|
vIndexes[i] = fDPosSummand->Var()->Index();
|
||||||
|
coeffs2[i] = -1.0;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!set_rowex(fLS->LP(), this->Index(), i, &coeffs2[0], &vIndexes[0]))
|
||||||
|
printf("Error in set_rowex.");
|
||||||
|
|
||||||
|
fLS->RemovePresolved();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the operator used for this constraint.
|
||||||
|
*
|
||||||
|
* @return the operator used for this constraint
|
||||||
|
*/
|
||||||
|
OperatorType
|
||||||
|
SoftConstraint::Op()
|
||||||
|
{
|
||||||
|
return fOp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the operator used for this constraint.
|
||||||
|
*
|
||||||
|
* @param value operator type
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
SoftConstraint::SetOp(OperatorType value)
|
||||||
|
{
|
||||||
|
fOp = value;
|
||||||
|
ChangeLeftSide(fCoeffs, fVars);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the coefficient of negative summand.
|
||||||
|
*
|
||||||
|
* @return the coefficient of negative summand.
|
||||||
|
*/
|
||||||
|
double
|
||||||
|
SoftConstraint::PenaltyNeg()
|
||||||
|
{
|
||||||
|
return fDNegSummand->Coeff();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The penalty coefficient for positive deviations from the soft constraint's exact solution,
|
||||||
|
* i.e. if the left side is too large.
|
||||||
|
*
|
||||||
|
* @param value coefficient of negative penalty <code>double</code>
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
SoftConstraint::SetPenaltyNeg(double value)
|
||||||
|
{
|
||||||
|
if (value == fDNegSummand->Coeff())
|
||||||
|
return;
|
||||||
|
fDNegSummand->SetCoeff(value);
|
||||||
|
fLS->UpdateObjFunction();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the coefficient of positive summand.
|
||||||
|
*
|
||||||
|
* @return the coefficient of positive summand.
|
||||||
|
*/
|
||||||
|
double
|
||||||
|
SoftConstraint::PenaltyPos()
|
||||||
|
{
|
||||||
|
return fDPosSummand->Coeff();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The penalty coefficient for negative deviations from the soft constraint's exact solution,
|
||||||
|
* i.e. if the left side is too small.
|
||||||
|
*
|
||||||
|
* @param value coefficient of positive penalty <code>double</code>
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
SoftConstraint::SetPenaltyPos(double value)
|
||||||
|
{
|
||||||
|
if (value == fDPosSummand->Coeff())
|
||||||
|
return;
|
||||||
|
fDPosSummand->SetCoeff(value);
|
||||||
|
fLS->UpdateObjFunction();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns positive and negative penalty coefficient as string.
|
||||||
|
*/
|
||||||
|
// Needs to be fixed.
|
||||||
|
//~ string SoftConstraint::ToString() {
|
||||||
|
//~ return base.ToString()
|
||||||
|
//~ + "; PenaltyNeg=" + PenaltyNeg()
|
||||||
|
//~ + "; PenaltyPos=" + PenaltyPos();
|
||||||
|
//~ }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the slack variable for the negative variations.
|
||||||
|
*
|
||||||
|
* @return the slack variable for the negative variations
|
||||||
|
*/
|
||||||
|
Variable*
|
||||||
|
SoftConstraint::DNeg() const
|
||||||
|
{
|
||||||
|
return fDNeg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the slack variable for the positive variations.
|
||||||
|
*
|
||||||
|
* @return the slack variable for the positive variations
|
||||||
|
*/
|
||||||
|
Variable*
|
||||||
|
SoftConstraint::DPos() const
|
||||||
|
{
|
||||||
|
return fDPos;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor.
|
||||||
|
* Removes the soft constraint from its specification.
|
||||||
|
*/
|
||||||
|
SoftConstraint::~SoftConstraint()
|
||||||
|
{
|
||||||
|
delete fDNegSummand->Var();
|
||||||
|
delete fDPosSummand->Var();
|
||||||
|
delete fDNegSummand;
|
||||||
|
delete fDPosSummand;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
SoftConstraint::SoftConstraint(LinearSpec* ls, BList* coeffs, BList* vars, OperatorType op,
|
||||||
|
double rightSide, double penaltyNeg, double penaltyPos)
|
||||||
|
{
|
||||||
|
int32 sizeCoeffs = coeffs->CountItems();
|
||||||
|
int32 sizeVars = vars->CountItems();
|
||||||
|
if (sizeCoeffs != sizeVars)
|
||||||
|
printf("Number of coefficients and number of variables in a constraint must be equal.");
|
||||||
|
|
||||||
|
fLS = ls;
|
||||||
|
fCoeffs = coeffs;
|
||||||
|
fVars = vars;
|
||||||
|
fOp = op;
|
||||||
|
fRightSide = rightSide;
|
||||||
|
|
||||||
|
fDNeg = new Variable(ls);
|
||||||
|
fDPos = new Variable(ls);
|
||||||
|
fDNegSummand = ls->AddObjFunctionSummand(penaltyNeg, DNeg());
|
||||||
|
fDPosSummand = ls->AddObjFunctionSummand(penaltyPos, DPos());
|
||||||
|
|
||||||
|
int vIndexes[sizeCoeffs + 2];
|
||||||
|
double coeffs2[sizeCoeffs + 2];
|
||||||
|
|
||||||
|
int32 i;
|
||||||
|
for (i=0; i < sizeVars; i++) {
|
||||||
|
vIndexes[i] = ((Variable*)vars->ItemAt(i))->Index();
|
||||||
|
coeffs2[i] = *(double*)coeffs->ItemAt(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fOp != OperatorType(LE)) {
|
||||||
|
vIndexes[i] = fDNegSummand->Var()->Index();
|
||||||
|
coeffs2[i] = 1.0;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fOp != OperatorType(GE)) {
|
||||||
|
vIndexes[i] = fDPosSummand->Var()->Index();
|
||||||
|
coeffs2[i] = -1.0;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!add_constraintex(ls->LP(), i, &coeffs2[0], &vIndexes[0],
|
||||||
|
((fOp == OperatorType(EQ)) ? EQ
|
||||||
|
: (fOp == OperatorType(GE)) ? GE
|
||||||
|
: LE), rightSide))
|
||||||
|
printf("Error in add_constraintex.");
|
||||||
|
|
||||||
|
ls->Constraints()->AddItem(this);
|
||||||
|
}
|
||||||
|
|
244
src/libs/linprog/Variable.cpp
Normal file
244
src/libs/linprog/Variable.cpp
Normal file
@ -0,0 +1,244 @@
|
|||||||
|
#include "Variable.h"
|
||||||
|
#include "Constraint.h"
|
||||||
|
#include "LinearSpec.h"
|
||||||
|
#include "OperatorType.h"
|
||||||
|
|
||||||
|
#include "lp_lib.h"
|
||||||
|
|
||||||
|
#include <float.h> // for DBL_MAX
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets index of the variable.
|
||||||
|
*
|
||||||
|
* @return the index of the variable
|
||||||
|
*/
|
||||||
|
int32
|
||||||
|
Variable::Index()
|
||||||
|
{
|
||||||
|
int32 i = fLS->Variables()->IndexOf(this);
|
||||||
|
if (i == -1)
|
||||||
|
printf("Variable not part of fLS->Variables().");
|
||||||
|
return i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current linear specification.
|
||||||
|
*
|
||||||
|
* @return the current linear specification
|
||||||
|
*/
|
||||||
|
LinearSpec*
|
||||||
|
Variable::LS() const
|
||||||
|
{
|
||||||
|
return fLS;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the current linear specification.
|
||||||
|
*
|
||||||
|
* @param value the current linear specification
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Variable::SetLS(LinearSpec* value)
|
||||||
|
{
|
||||||
|
fLS = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the value.
|
||||||
|
*
|
||||||
|
* @return the value
|
||||||
|
*/
|
||||||
|
double
|
||||||
|
Variable::Value() const
|
||||||
|
{
|
||||||
|
return fValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the value.
|
||||||
|
*
|
||||||
|
* @param value the value
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Variable::SetValue(double value)
|
||||||
|
{
|
||||||
|
fValue = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the minimum value of the variable.
|
||||||
|
*
|
||||||
|
* @return the minimum value of variable
|
||||||
|
*/
|
||||||
|
double
|
||||||
|
Variable::Min() const
|
||||||
|
{
|
||||||
|
return fMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the minimum value of the variable.
|
||||||
|
*
|
||||||
|
* @param min minimum value
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Variable::SetMin(double min)
|
||||||
|
{
|
||||||
|
fMin = min;
|
||||||
|
set_bounds(fLS->LP(), this->Index(), fMin, fMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the maximum value of the variable.
|
||||||
|
*
|
||||||
|
* @return the maximum value of variable
|
||||||
|
*/
|
||||||
|
double
|
||||||
|
Variable::Max() const
|
||||||
|
{
|
||||||
|
return fMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the maximum value of the variable.
|
||||||
|
*
|
||||||
|
* @param max maximum value
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Variable::SetMax(double max)
|
||||||
|
{
|
||||||
|
fMax = max;
|
||||||
|
set_bounds(fLS->LP(), this->Index(), fMin, fMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the minimum and maximum values of the variable.
|
||||||
|
*
|
||||||
|
* @param min minimum value
|
||||||
|
* @param max maximum value
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
Variable::SetRange(double min, double max)
|
||||||
|
{
|
||||||
|
fMin = min;
|
||||||
|
fMax = max;
|
||||||
|
set_bounds(fLS->LP(), this->Index(), fMin, fMax);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns index of the variable as String.
|
||||||
|
* E.g. "Var2"
|
||||||
|
*
|
||||||
|
* @return the <code>String</code> index of the variable
|
||||||
|
*/
|
||||||
|
//~ string Variable::ToString() {
|
||||||
|
//~ return "Var" + Index();
|
||||||
|
//~ }
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a constraint that sets this variable equal to the given one.
|
||||||
|
*
|
||||||
|
* @param var variable that should have the same value
|
||||||
|
* @return the new equality constraint
|
||||||
|
*/
|
||||||
|
Constraint*
|
||||||
|
Variable::IsEqual(Variable* var)
|
||||||
|
{
|
||||||
|
BList* coeffs = new BList(2);
|
||||||
|
coeffs->AddItem(new double(1.0));
|
||||||
|
coeffs->AddItem(new double(-1.0));
|
||||||
|
|
||||||
|
BList* vars = new BList(2);
|
||||||
|
vars->AddItem(this);
|
||||||
|
vars->AddItem(var);
|
||||||
|
|
||||||
|
return fLS->AddConstraint(coeffs, vars, OperatorType(EQ), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a constraint that sets this variable smaller or equal to the given one.
|
||||||
|
*
|
||||||
|
* @param var variable that should have a larger or equal value
|
||||||
|
* @return the new constraint
|
||||||
|
*/
|
||||||
|
Constraint*
|
||||||
|
Variable::IsSmallerOrEqual(Variable* var)
|
||||||
|
{
|
||||||
|
BList* coeffs = new BList(2);
|
||||||
|
coeffs->AddItem(new double(1.0));
|
||||||
|
coeffs->AddItem(new double(-1.0));
|
||||||
|
|
||||||
|
BList* vars = new BList(2);
|
||||||
|
vars->AddItem(this);
|
||||||
|
vars->AddItem(var);
|
||||||
|
|
||||||
|
return fLS->AddConstraint(coeffs, vars, OperatorType(LE), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a constraint that sets this variable greater or equal to the given one.
|
||||||
|
*
|
||||||
|
* @param var variable that should have a smaller or equal value
|
||||||
|
* @return the new constraint
|
||||||
|
*/
|
||||||
|
Constraint*
|
||||||
|
Variable::IsGreaterorEqual(Variable* var)
|
||||||
|
{
|
||||||
|
BList* coeffs = new BList(2);
|
||||||
|
coeffs->AddItem(new double(-1.0));
|
||||||
|
coeffs->AddItem(new double(1.0));
|
||||||
|
|
||||||
|
BList* vars = new BList(2);
|
||||||
|
vars->AddItem(var);
|
||||||
|
vars->AddItem(this);
|
||||||
|
|
||||||
|
return fLS->AddConstraint(coeffs, vars, OperatorType(GE), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
|
Variable::Variable(LinearSpec* ls)
|
||||||
|
{
|
||||||
|
fMin = 0;
|
||||||
|
fMax = DBL_MAX;
|
||||||
|
fValue = NULL;
|
||||||
|
fLS = ls;
|
||||||
|
|
||||||
|
ls->Variables()->AddItem(this);
|
||||||
|
|
||||||
|
int32 size = ls->Variables()->CountItems();
|
||||||
|
if (size > ls->Columns()) {
|
||||||
|
double d = 0;
|
||||||
|
int i = 0;
|
||||||
|
if (!add_columnex(ls->LP(), 0, &d, &i))
|
||||||
|
printf("Error in add_columnex.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destructor.
|
||||||
|
* Removes the variable from its specification.
|
||||||
|
*/
|
||||||
|
Variable::~Variable()
|
||||||
|
{
|
||||||
|
del_column(fLS->LP(), this->Index());
|
||||||
|
fLS->Variables()->RemoveItem(this);
|
||||||
|
}
|
||||||
|
|
@ -29,5 +29,6 @@ SubInclude HAIKU_TOP src tests apps ;
|
|||||||
SubInclude HAIKU_TOP src tests bin ;
|
SubInclude HAIKU_TOP src tests bin ;
|
||||||
SubInclude HAIKU_TOP src tests system ;
|
SubInclude HAIKU_TOP src tests system ;
|
||||||
SubInclude HAIKU_TOP src tests kits ;
|
SubInclude HAIKU_TOP src tests kits ;
|
||||||
|
SubInclude HAIKU_TOP src tests libs ;
|
||||||
SubInclude HAIKU_TOP src tests misc ;
|
SubInclude HAIKU_TOP src tests misc ;
|
||||||
SubInclude HAIKU_TOP src tests servers ;
|
SubInclude HAIKU_TOP src tests servers ;
|
||||||
|
6
src/tests/libs/Jamfile
Normal file
6
src/tests/libs/Jamfile
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
SubDir HAIKU_TOP src tests libs ;
|
||||||
|
|
||||||
|
SubInclude HAIKU_TOP src tests libs lp_solve ;
|
||||||
|
SubInclude HAIKU_TOP src tests libs linprog ;
|
||||||
|
SubInclude HAIKU_TOP src tests libs alm ;
|
||||||
|
|
24
src/tests/libs/alm/Jamfile
Normal file
24
src/tests/libs/alm/Jamfile
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
SubDir HAIKU_TOP src tests libs alm ;
|
||||||
|
|
||||||
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
|
||||||
|
UseLibraryHeaders lp_solve linprog alm ;
|
||||||
|
|
||||||
|
Application table_test :
|
||||||
|
TableTest.cpp
|
||||||
|
:
|
||||||
|
be liblpsolve55.so liblinprog.so libalm.so
|
||||||
|
;
|
||||||
|
|
||||||
|
Application test1 :
|
||||||
|
Test1.cpp
|
||||||
|
:
|
||||||
|
be liblpsolve55.so be liblinprog.so libalm.so
|
||||||
|
;
|
||||||
|
|
||||||
|
Application test2 :
|
||||||
|
Test2.cpp
|
||||||
|
:
|
||||||
|
be liblpsolve55.so be liblinprog.so libalm.so
|
||||||
|
;
|
||||||
|
|
70
src/tests/libs/alm/TableTest.cpp
Normal file
70
src/tests/libs/alm/TableTest.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
|
||||||
|
#include <Application.h>
|
||||||
|
#include <File.h>
|
||||||
|
#include <Button.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include "Area.h"
|
||||||
|
#include "Column.h"
|
||||||
|
#include "BALMLayout.h"
|
||||||
|
#include "Row.h"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace BALM;
|
||||||
|
|
||||||
|
class TableTestWindow : public BWindow {
|
||||||
|
public:
|
||||||
|
TableTestWindow(BRect frame) : BWindow(frame, "TableTest", B_TITLED_WINDOW,
|
||||||
|
B_QUIT_ON_WINDOW_CLOSE) {
|
||||||
|
|
||||||
|
BALMLayout* fLS = new BALMLayout();
|
||||||
|
|
||||||
|
SetLayout(fLS);
|
||||||
|
|
||||||
|
fLS->SetPerformancePath("/boot/home/Desktop/table_test_performance.txt");
|
||||||
|
|
||||||
|
Column* c1 = fLS->AddColumn(fLS->Left(), fLS->Right());
|
||||||
|
Row* r1 = fLS->AddRow(fLS->Top(), NULL);
|
||||||
|
Row* r3 = fLS->AddRow(NULL, fLS->Bottom());
|
||||||
|
r1->SetNext(r3);
|
||||||
|
Row* r2 = fLS->AddRow();
|
||||||
|
r2->InsertAfter(r1);
|
||||||
|
|
||||||
|
BButton* b1 = new BButton("A1");
|
||||||
|
Area* a1 = fLS->AddArea(r1, c1, b1);
|
||||||
|
a1->SetHAlignment(B_ALIGN_LEFT);
|
||||||
|
a1->SetVAlignment(B_ALIGN_TOP);
|
||||||
|
|
||||||
|
BButton* b2 = new BButton("A2");
|
||||||
|
Area* a2 = fLS->AddArea(r2, c1, b2);
|
||||||
|
a2->SetHAlignment(B_ALIGN_HORIZONTAL_CENTER);
|
||||||
|
a2->SetVAlignment(B_ALIGN_VERTICAL_CENTER);
|
||||||
|
|
||||||
|
BButton* b3 = new BButton("A3");
|
||||||
|
Area* a3 = fLS->AddArea(r3, c1, b3);
|
||||||
|
a3->SetHAlignment(B_ALIGN_RIGHT);
|
||||||
|
a3->SetVAlignment(B_ALIGN_BOTTOM);
|
||||||
|
|
||||||
|
r2->HasSameHeightAs(r1);
|
||||||
|
r3->HasSameHeightAs(r1);
|
||||||
|
|
||||||
|
Show();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class TableTest : public BApplication {
|
||||||
|
public:
|
||||||
|
TableTest() : BApplication("application/x-vnd.haiku.table-test") {
|
||||||
|
BRect frameRect;
|
||||||
|
frameRect.Set(100, 100, 400, 400);
|
||||||
|
TableTestWindow* theWindow = new TableTestWindow(frameRect);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
TableTest test;
|
||||||
|
test.Run();
|
||||||
|
return 0;
|
||||||
|
}
|
83
src/tests/libs/alm/Test1.cpp
Normal file
83
src/tests/libs/alm/Test1.cpp
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
#include <Application.h>
|
||||||
|
#include <Button.h>
|
||||||
|
#include <List.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include "Area.h"
|
||||||
|
#include "BALMLayout.h"
|
||||||
|
#include "OperatorType.h"
|
||||||
|
#include "XTab.h"
|
||||||
|
#include "YTab.h"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace BALM;
|
||||||
|
|
||||||
|
class Test1Window : public BWindow {
|
||||||
|
public:
|
||||||
|
Test1Window(BRect frame) : BWindow(frame, "Test1", B_TITLED_WINDOW,
|
||||||
|
B_QUIT_ON_WINDOW_CLOSE) {
|
||||||
|
|
||||||
|
fLS = new BALMLayout();
|
||||||
|
|
||||||
|
SetLayout(fLS);
|
||||||
|
|
||||||
|
button1 = new BButton("button1");
|
||||||
|
button2 = new BButton("button2");
|
||||||
|
button3 = new BButton("button3");
|
||||||
|
|
||||||
|
fLS->SetPerformancePath("/boot/home/Desktop/test1_performance.txt");
|
||||||
|
SetBALMLayout();
|
||||||
|
|
||||||
|
Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SetBALMLayout() {
|
||||||
|
XTab* x1 = fLS->AddXTab();
|
||||||
|
YTab* y1 = fLS->AddYTab();
|
||||||
|
|
||||||
|
fLS->AddArea(fLS->Left(), fLS->Top(), x1, y1, button1);
|
||||||
|
fLS->AddArea(x1, fLS->Top(), fLS->Right(), y1, button2);
|
||||||
|
fLS->AddArea(fLS->Left(), y1, fLS->Right(), fLS->Bottom(), button3);
|
||||||
|
|
||||||
|
//~ BList* coeffs1 = new BList(2);
|
||||||
|
//~ coeffs1->AddItem(new double(2.0));
|
||||||
|
//~ coeffs1->AddItem(new double(-1.0));
|
||||||
|
//~ BList* vars1 = new BList(2);
|
||||||
|
//~ vars1->AddItem(x1);
|
||||||
|
//~ vars1->AddItem(fLS->Right());
|
||||||
|
fLS->AddConstraint(2.0, x1, -1.0, fLS->Right(), OperatorType(EQ), 0.0);
|
||||||
|
|
||||||
|
//~ BList* coeffs2 = new BList(2);
|
||||||
|
//~ coeffs2->AddItem(new double(2.0));
|
||||||
|
//~ coeffs2->AddItem(new double(-1.0));
|
||||||
|
//~ BList* vars2 = new BList(2);
|
||||||
|
//~ vars2->AddItem(y1);
|
||||||
|
//~ vars2->AddItem(fLS->Bottom());
|
||||||
|
fLS->AddConstraint(2.0, y1, -1.0, fLS->Bottom(), OperatorType(EQ), 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
BALMLayout* fLS;
|
||||||
|
BButton* button1;
|
||||||
|
BButton* button2;
|
||||||
|
BButton* button3;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Test1 : public BApplication {
|
||||||
|
public:
|
||||||
|
Test1() : BApplication("application/x-vnd.haiku.test1") {
|
||||||
|
BRect frameRect;
|
||||||
|
frameRect.Set(100, 100, 392, 366);
|
||||||
|
Test1Window* theWindow = new Test1Window(frameRect);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Test1 test;
|
||||||
|
test.Run();
|
||||||
|
return 0;
|
||||||
|
}
|
162
src/tests/libs/alm/Test2.cpp
Normal file
162
src/tests/libs/alm/Test2.cpp
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
|
||||||
|
#include <Application.h>
|
||||||
|
#include <Button.h>
|
||||||
|
#include <List.h>
|
||||||
|
#include <StringView.h>
|
||||||
|
#include <TextControl.h>
|
||||||
|
#include <TextView.h>
|
||||||
|
#include <Window.h>
|
||||||
|
|
||||||
|
#include "Area.h"
|
||||||
|
#include "BALMLayout.h"
|
||||||
|
#include "OperatorType.h"
|
||||||
|
#include "XTab.h"
|
||||||
|
#include "YTab.h"
|
||||||
|
|
||||||
|
|
||||||
|
using namespace BALM;
|
||||||
|
|
||||||
|
class Test2Window : public BWindow {
|
||||||
|
public:
|
||||||
|
Test2Window(BRect frame) : BWindow(frame, "Test2", B_TITLED_WINDOW,
|
||||||
|
B_QUIT_ON_WINDOW_CLOSE) {
|
||||||
|
|
||||||
|
fLS = new BALMLayout();
|
||||||
|
|
||||||
|
SetLayout(fLS);
|
||||||
|
|
||||||
|
button1 = new BButton("button1");
|
||||||
|
button2 = new BButton("button2");
|
||||||
|
button3 = new BButton("button3");
|
||||||
|
button4 = new BButton("button4");
|
||||||
|
button5 = new BButton("button5");
|
||||||
|
button6 = new BButton("button6");
|
||||||
|
checkedListBox1 = new BButton("checkedListBox1");
|
||||||
|
textBox1 = new BButton("textBox1");
|
||||||
|
textBox2 = new BButton("textBox2");
|
||||||
|
richTextBox1 = new BButton("richTextBox1");
|
||||||
|
//~ textBox1 = new BTextView(frame, "textBox1", NULL, NULL);
|
||||||
|
//~ textBox2 = new BTextView(frame, "textBox2", NULL, NULL);
|
||||||
|
//~ richTextBox1 = new BTextControl(NULL, "richTextBox1", NULL);
|
||||||
|
listView1 = new BButton("listView1");
|
||||||
|
label1 = new BStringView(frame, "label1", "label1");
|
||||||
|
label2 = new BStringView(frame, "label2", "label2");
|
||||||
|
label3 = new BStringView(frame, "label3", "label3");
|
||||||
|
|
||||||
|
fLS->SetPerformancePath("/boot/home/Desktop/test2_performance.txt");
|
||||||
|
SetBALMLayout();
|
||||||
|
|
||||||
|
Show();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void SetBALMLayout() {
|
||||||
|
XTab* x1 = fLS->AddXTab();
|
||||||
|
XTab* x2 = fLS->AddXTab();
|
||||||
|
XTab* x3 = fLS->AddXTab();
|
||||||
|
YTab* y1 = fLS->AddYTab();
|
||||||
|
YTab* y2 = fLS->AddYTab();
|
||||||
|
YTab* y3 = fLS->AddYTab();
|
||||||
|
YTab* y4 = fLS->AddYTab();
|
||||||
|
YTab* y5 = fLS->AddYTab();
|
||||||
|
|
||||||
|
fLS->AddArea(fLS->Left(), fLS->Top(), x1, y1, button1);
|
||||||
|
fLS->AddArea(x1, fLS->Top(), x2, y1, button2);
|
||||||
|
fLS->AddArea(fLS->Left(), y1, x1, y2, button3);
|
||||||
|
fLS->AddArea(x1, y1, x2, y2, button4);
|
||||||
|
fLS->AddArea(fLS->Left(), y2, x1, y3, button5);
|
||||||
|
fLS->AddArea(x1, y2, x2, y3, button6);
|
||||||
|
|
||||||
|
//~ BList* coeffs1 = new BList(2);
|
||||||
|
//~ coeffs1->AddItem(new double(2.0));
|
||||||
|
//~ coeffs1->AddItem(new double(-1.0));
|
||||||
|
//~ BList* vars1 = new BList(2);
|
||||||
|
//~ vars1->AddItem(x1);
|
||||||
|
//~ vars1->AddItem(x2);
|
||||||
|
//~ fLS->AddConstraint(coeffs1, vars1, OperatorType(EQ), 0.0);
|
||||||
|
|
||||||
|
fLS->AddConstraint(2.0, x1, -1.0, x2, OperatorType(EQ), 0.0);
|
||||||
|
|
||||||
|
//~ BList* coeffs2 = new BList(2);
|
||||||
|
//~ coeffs2->AddItem(new double(2.0));
|
||||||
|
//~ coeffs2->AddItem(new double(-1.0));
|
||||||
|
//~ BList* vars2 = new BList(2);
|
||||||
|
//~ vars2->AddItem(y1);
|
||||||
|
//~ vars2->AddItem(y2);
|
||||||
|
fLS->AddConstraint(2.0, y1, -1.0, y2, OperatorType(EQ), 0.0);
|
||||||
|
|
||||||
|
//~ BList* coeffs3 = new BList(3);
|
||||||
|
//~ coeffs3->AddItem(new double(1.0));
|
||||||
|
//~ coeffs3->AddItem(new double(1.0));
|
||||||
|
//~ coeffs3->AddItem(new double(-1.0));
|
||||||
|
//~ BList* vars3 = new BList(3);
|
||||||
|
//~ vars3->AddItem(y1);
|
||||||
|
//~ vars3->AddItem(y2);
|
||||||
|
//~ vars3->AddItem(y3);
|
||||||
|
fLS->AddConstraint(1.0, y1, 1.0, y2, -1.0, y3, OperatorType(EQ), 0.0);
|
||||||
|
|
||||||
|
fLS->AddArea(fLS->Left(), y3, x2, y4, checkedListBox1);
|
||||||
|
fLS->AddArea(x2, fLS->Top(), fLS->Right(), y2, textBox1);
|
||||||
|
fLS->AddArea(fLS->Left(), y4, x3, y5, listView1);
|
||||||
|
fLS->AddArea(x3, y2, fLS->Right(), y5, textBox2);
|
||||||
|
|
||||||
|
Area* richTextBox1Area = fLS->AddArea(x2, y2, x3, y4, richTextBox1);
|
||||||
|
richTextBox1Area->SetLeftInset(10);
|
||||||
|
richTextBox1Area->SetTopInset(10);
|
||||||
|
richTextBox1Area->SetRightInset(10);
|
||||||
|
richTextBox1Area->SetBottomInset(10);
|
||||||
|
|
||||||
|
Area* label1Area = fLS->AddArea(fLS->Left(), y5, x2, fLS->Bottom(), label1);
|
||||||
|
label1Area->SetHAlignment(B_ALIGN_LEFT);
|
||||||
|
label1Area->SetTopInset(4);
|
||||||
|
label1Area->SetBottomInset(4);
|
||||||
|
|
||||||
|
Area* label2Area = fLS->AddArea(x2, y5, x3, fLS->Bottom(), label2);
|
||||||
|
label2Area->SetHAlignment(B_ALIGN_HORIZONTAL_CENTER);
|
||||||
|
label2Area->SetTopInset(4);
|
||||||
|
label2Area->SetBottomInset(4);
|
||||||
|
|
||||||
|
Area* label3Area = fLS->AddArea(x3, y5, fLS->Right(), fLS->Bottom(), label3);
|
||||||
|
label3Area->SetHAlignment(B_ALIGN_RIGHT);
|
||||||
|
label3Area->SetTopInset(4);
|
||||||
|
label3Area->SetBottomInset(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
BALMLayout* fLS;
|
||||||
|
BButton* button1;
|
||||||
|
BButton* button2;
|
||||||
|
BButton* button3;
|
||||||
|
BButton* button4;
|
||||||
|
BButton* button5;
|
||||||
|
BButton* button6;
|
||||||
|
BButton* checkedListBox1;
|
||||||
|
BButton* textBox1;
|
||||||
|
BButton* textBox2;
|
||||||
|
BButton* richTextBox1;
|
||||||
|
//~ BTextView* textBox1;
|
||||||
|
//~ BTextView* textBox2;
|
||||||
|
//~ BTextControl* richTextBox1;
|
||||||
|
BButton* listView1;
|
||||||
|
BStringView* label1;
|
||||||
|
BStringView* label2;
|
||||||
|
BStringView* label3;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
class Test2 : public BApplication {
|
||||||
|
public:
|
||||||
|
Test2() : BApplication("application/x-vnd.haiku.test2") {
|
||||||
|
BRect frameRect;
|
||||||
|
frameRect.Set(100, 100, 610, 456);
|
||||||
|
Test2Window* theWindow = new Test2Window(frameRect);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Test2 test;
|
||||||
|
test.Run();
|
||||||
|
return 0;
|
||||||
|
}
|
11
src/tests/libs/linprog/Jamfile
Normal file
11
src/tests/libs/linprog/Jamfile
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
SubDir HAIKU_TOP src tests libs linprog ;
|
||||||
|
|
||||||
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
|
||||||
|
UseLibraryHeaders lp_solve linprog ;
|
||||||
|
|
||||||
|
SimpleTest linprog :
|
||||||
|
Program.cpp
|
||||||
|
:
|
||||||
|
be liblpsolve55.so liblinprog.so
|
||||||
|
;
|
67
src/tests/libs/linprog/Program.cpp
Normal file
67
src/tests/libs/linprog/Program.cpp
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
|
||||||
|
#include <List.h>
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
#include "Constraint.h"
|
||||||
|
#include "LinearSpec.h"
|
||||||
|
#include "OperatorType.h"
|
||||||
|
#include "Variable.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
|
||||||
|
void PrintVars(LinearSpec* ls) {
|
||||||
|
int32 size = ls->Variables()->CountItems();
|
||||||
|
Variable* variable;
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
variable = (Variable*)ls->Variables()->ItemAt(i);
|
||||||
|
printf("%f ", variable->Value());
|
||||||
|
}
|
||||||
|
printf("%d\n", ls->Result());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void Test1() {
|
||||||
|
LinearSpec* ls = new LinearSpec();
|
||||||
|
Variable* x1 = ls->AddVariable();
|
||||||
|
Variable* x2 = ls->AddVariable();
|
||||||
|
|
||||||
|
BList* coeffs1 = new BList(1);
|
||||||
|
coeffs1->AddItem(new double(1.0));
|
||||||
|
BList* vars1 = new BList(1);
|
||||||
|
vars1->AddItem(x1);
|
||||||
|
Constraint* c1 = ls->AddConstraint(coeffs1, vars1, OperatorType(LE), 108);
|
||||||
|
|
||||||
|
BList* coeffs2 = new BList(1);
|
||||||
|
coeffs2->AddItem(new double(1.0));
|
||||||
|
BList* vars2 = new BList(1);
|
||||||
|
vars2->AddItem(x2);
|
||||||
|
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();
|
||||||
|
PrintVars(ls);
|
||||||
|
|
||||||
|
delete c2;
|
||||||
|
ls->Solve();
|
||||||
|
PrintVars(ls);
|
||||||
|
|
||||||
|
BList* coeffs4 = new BList(1);
|
||||||
|
coeffs4->AddItem(new double(1.0));
|
||||||
|
BList* vars4 = new BList(1);
|
||||||
|
vars4->AddItem(x2);
|
||||||
|
c2 = ls->AddConstraint(coeffs4, vars4, OperatorType(GE), 113);
|
||||||
|
ls->Solve();
|
||||||
|
PrintVars(ls);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
Test1();
|
||||||
|
}
|
12
src/tests/libs/lp_solve/Jamfile
Normal file
12
src/tests/libs/lp_solve/Jamfile
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
SubDir HAIKU_TOP src tests libs lp_solve ;
|
||||||
|
|
||||||
|
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||||
|
|
||||||
|
UseLibraryHeaders lp_solve ;
|
||||||
|
|
||||||
|
SimpleTest lp_solve :
|
||||||
|
demo.c
|
||||||
|
:
|
||||||
|
liblpsolve55.so
|
||||||
|
;
|
||||||
|
|
146
src/tests/libs/lp_solve/demo.c
Normal file
146
src/tests/libs/lp_solve/demo.c
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/* demo.c */
|
||||||
|
|
||||||
|
#include "lp_lib.h"
|
||||||
|
|
||||||
|
int demo()
|
||||||
|
{
|
||||||
|
lprec *lp;
|
||||||
|
int Ncol, *colno = NULL, j, ret = 0;
|
||||||
|
REAL *row = NULL;
|
||||||
|
|
||||||
|
/* We will build the model row by row
|
||||||
|
So we start with creating a model with 0 rows and 2 columns */
|
||||||
|
Ncol = 2; /* there are two variables in the model */
|
||||||
|
lp = make_lp(0, Ncol);
|
||||||
|
if(lp == NULL)
|
||||||
|
ret = 1; /* couldn't construct a new model... */
|
||||||
|
|
||||||
|
if(ret == 0) {
|
||||||
|
/* let us name our variables. Not required, but can be useful for debugging */
|
||||||
|
set_col_name(lp, 1, "x");
|
||||||
|
set_col_name(lp, 2, "y");
|
||||||
|
|
||||||
|
/* create space large enough for one row */
|
||||||
|
colno = (int *) malloc(Ncol * sizeof(*colno));
|
||||||
|
row = (REAL *) malloc(Ncol * sizeof(*row));
|
||||||
|
if((colno == NULL) || (row == NULL))
|
||||||
|
ret = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ret == 0) {
|
||||||
|
set_add_rowmode(lp, TRUE); /* makes building the model faster if it is done rows by row */
|
||||||
|
|
||||||
|
/* construct first row (120 x + 210 y <= 15000) */
|
||||||
|
j = 0;
|
||||||
|
|
||||||
|
colno[j] = 1; /* first column */
|
||||||
|
row[j++] = 120;
|
||||||
|
|
||||||
|
colno[j] = 2; /* second column */
|
||||||
|
row[j++] = 210;
|
||||||
|
|
||||||
|
/* add the row to lpsolve */
|
||||||
|
if(!add_constraintex(lp, j, row, colno, LE, 15000))
|
||||||
|
ret = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ret == 0) {
|
||||||
|
/* construct second row (110 x + 30 y <= 4000) */
|
||||||
|
j = 0;
|
||||||
|
|
||||||
|
colno[j] = 1; /* first column */
|
||||||
|
row[j++] = 110;
|
||||||
|
|
||||||
|
colno[j] = 2; /* second column */
|
||||||
|
row[j++] = 30;
|
||||||
|
|
||||||
|
/* add the row to lpsolve */
|
||||||
|
if(!add_constraintex(lp, j, row, colno, LE, 4000))
|
||||||
|
ret = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ret == 0) {
|
||||||
|
/* construct third row (x + y <= 75) */
|
||||||
|
j = 0;
|
||||||
|
|
||||||
|
colno[j] = 1; /* first column */
|
||||||
|
row[j++] = 1;
|
||||||
|
|
||||||
|
colno[j] = 2; /* second column */
|
||||||
|
row[j++] = 1;
|
||||||
|
|
||||||
|
/* add the row to lpsolve */
|
||||||
|
if(!add_constraintex(lp, j, row, colno, LE, 75))
|
||||||
|
ret = 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ret == 0) {
|
||||||
|
set_add_rowmode(lp, FALSE); /* rowmode should be turned off again when done building the model */
|
||||||
|
|
||||||
|
/* set the objective function (143 x + 60 y) */
|
||||||
|
j = 0;
|
||||||
|
|
||||||
|
colno[j] = 1; /* first column */
|
||||||
|
row[j++] = 143;
|
||||||
|
|
||||||
|
colno[j] = 2; /* second column */
|
||||||
|
row[j++] = 60;
|
||||||
|
|
||||||
|
/* set the objective in lpsolve */
|
||||||
|
if(!set_obj_fnex(lp, j, row, colno))
|
||||||
|
ret = 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ret == 0) {
|
||||||
|
/* set the object direction to maximize */
|
||||||
|
set_maxim(lp);
|
||||||
|
|
||||||
|
/* just out of curioucity, now show the model in lp format on screen */
|
||||||
|
/* this only works if this is a console application. If not, use write_lp and a filename */
|
||||||
|
write_LP(lp, stdout);
|
||||||
|
/* write_lp(lp, "model.lp"); */
|
||||||
|
|
||||||
|
/* I only want to see important messages on screen while solving */
|
||||||
|
set_verbose(lp, IMPORTANT);
|
||||||
|
|
||||||
|
/* Now let lpsolve calculate a solution */
|
||||||
|
ret = solve(lp);
|
||||||
|
if(ret == OPTIMAL)
|
||||||
|
ret = 0;
|
||||||
|
else
|
||||||
|
ret = 5;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ret == 0) {
|
||||||
|
/* a solution is calculated, now lets get some results */
|
||||||
|
|
||||||
|
/* objective value */
|
||||||
|
printf("Objective value: %f\n", get_objective(lp));
|
||||||
|
|
||||||
|
/* variable values */
|
||||||
|
get_variables(lp, row);
|
||||||
|
for(j = 0; j < Ncol; j++)
|
||||||
|
printf("%s: %f\n", get_col_name(lp, j + 1), row[j]);
|
||||||
|
|
||||||
|
/* we are done now */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* free allocated memory */
|
||||||
|
if(row != NULL)
|
||||||
|
free(row);
|
||||||
|
if(colno != NULL)
|
||||||
|
free(colno);
|
||||||
|
|
||||||
|
if(lp != NULL) {
|
||||||
|
/* clean up such that all used memory by lpsolve is freed */
|
||||||
|
delete_lp(lp);
|
||||||
|
}
|
||||||
|
|
||||||
|
return(ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
demo();
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user