[haiku-commits] r33609 - in haiku/trunk: headers/libs/linprog src/libs/linprog

  • From: axeld@xxxxxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 16 Oct 2009 14:13:08 +0200 (CEST)

Author: axeld
Date: 2009-10-16 14:13:07 +0200 (Fri, 16 Oct 2009)
New Revision: 33609
Changeset: http://dev.haiku-os.org/changeset/33609/haiku

Modified:
   haiku/trunk/headers/libs/linprog/Constraint.h
   haiku/trunk/headers/libs/linprog/LinearSpec.h
   haiku/trunk/headers/libs/linprog/Summand.h
   haiku/trunk/headers/libs/linprog/Variable.h
   haiku/trunk/src/libs/linprog/Constraint.cpp
   haiku/trunk/src/libs/linprog/LinearSpec.cpp
   haiku/trunk/src/libs/linprog/Summand.cpp
   haiku/trunk/src/libs/linprog/Variable.cpp
Log:
* Applied patch by Hong Yul Yang to update linprog.


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

Modified: haiku/trunk/headers/libs/linprog/LinearSpec.h
===================================================================
--- haiku/trunk/headers/libs/linprog/LinearSpec.h       2009-10-16 09:16:17 UTC 
(rev 33608)
+++ haiku/trunk/headers/libs/linprog/LinearSpec.h       2009-10-16 12:13:07 UTC 
(rev 33609)
@@ -18,6 +18,7 @@
 #include "lp_lib.h"
 
 #include <List.h>
+#include <String.h>
 #include <OS.h>
 #include <SupportDefs.h>
 #include <math.h>
@@ -37,7 +38,7 @@
        
 public:
                                                LinearSpec();
-                                               ~LinearSpec();
+       virtual                         ~LinearSpec();
 
        Variable*                       AddVariable();
 
@@ -100,6 +101,9 @@
        double                          ObjectiveValue() const;
        double                          SolvingTime() const;
 
+       BString*                        ToBString();
+       const char*                     ToString();
+
 protected:
        int32                           fCountColumns;
 

Modified: haiku/trunk/headers/libs/linprog/Summand.h
===================================================================
--- haiku/trunk/headers/libs/linprog/Summand.h  2009-10-16 09:16:17 UTC (rev 
33608)
+++ haiku/trunk/headers/libs/linprog/Summand.h  2009-10-16 12:13:07 UTC (rev 
33609)
@@ -29,6 +29,7 @@
 private:
        double                  fCoeff;
        Variable*               fVar;
+       bool    fUsedInPenaltyFunction;  //not set yet
 
 };
 

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

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

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

Modified: haiku/trunk/src/libs/linprog/Summand.cpp
===================================================================
--- haiku/trunk/src/libs/linprog/Summand.cpp    2009-10-16 09:16:17 UTC (rev 
33608)
+++ haiku/trunk/src/libs/linprog/Summand.cpp    2009-10-16 12:13:07 UTC (rev 
33609)
@@ -62,6 +62,7 @@
  */
 Summand::~Summand()
 {
+  fVar->fUsingSummands->RemoveItem(this);
 }
 
 
@@ -72,5 +73,8 @@
 {
        fCoeff = coeff;
        fVar = var;
+       fUsedInPenaltyFunction = false;
+       fVar->fUsingSummands->AddItem(this);
+       
 }
 

Modified: haiku/trunk/src/libs/linprog/Variable.cpp
===================================================================
--- haiku/trunk/src/libs/linprog/Variable.cpp   2009-10-16 09:16:17 UTC (rev 
33608)
+++ haiku/trunk/src/libs/linprog/Variable.cpp   2009-10-16 12:13:07 UTC (rev 
33609)
@@ -14,6 +14,16 @@
 #include <float.h>     // for DBL_MAX
 
 
+// Toggle debug output
+//#define DEBUG_VARIABLE
+
+#ifdef DEBUG_VARIABLE
+#      define STRACE(x) debug_printf x
+#else
+#      define STRACE(x) ;
+#endif
+
+
 /**
  * Gets index of the variable.
  * 
@@ -23,8 +33,10 @@
 Variable::Index()
 {
        int32 i = fLS->Variables()->IndexOf(this);
-       if (i == -1)
+       if (i == -1) {
                printf("Variable not part of fLS->Variables().");
+               return -1;
+       }
        return i + 1;
 }
 
@@ -42,18 +54,6 @@
 
 
 /**
- * Sets the current linear specification.
- * 
- * @param value        the current linear specification
- */
-void
-Variable::SetLS(LinearSpec* value)
-{
-       fLS = value;
-}
-
-
-/**
  * Gets the value.
  * 
  * @return the value
@@ -97,6 +97,9 @@
 void
 Variable::SetMin(double min)
 {
+       if (!fIsValid)
+               return;
+
        fMin = min;
        set_bounds(fLS->fLP, this->Index(), fMin, fMax);
 }
@@ -122,6 +125,9 @@
 void
 Variable::SetMax(double max)
 {
+       if (!fIsValid)
+               return;
+
        fMax = max;
        set_bounds(fLS->fLP, this->Index(), fMin, fMax);
 }
@@ -136,23 +142,66 @@
 void
 Variable::SetRange(double min, double max)
 {
+       if (!fIsValid)
+               return;
+
        fMin = min;
        fMax = max;
        set_bounds(fLS->fLP, this->Index(), fMin, fMax);
 }
 
 
+const char*
+Variable::Label()
+{
+       return fLabel;
+}
+
+
+void
+Variable::SetLabel(const char* label)
+{
+       fLabel = (char*) malloc(strlen(label) + 1);
+       strcpy(fLabel, label);
+}
+
+
 /**
  * Returns index of the variable as String.
  * E.g. "Var2"
  * 
  * @return the <code>String</code> index of the variable
  */
-//~ string Variable::ToString() {
-       //~ return "Var" + Index();
-//~ }
+BString*
+Variable::ToBString()
+{
+       BString* str = new BString();
+       if (fLabel) {
+               *str << fLabel;
+               if (!fIsValid)
+                       *str << "(invalid)";
+       } else {
+               *str << "Var";
+               if (!fIsValid)
+                       *str << "(invalid," << (int32)this << ")";
+               else
+                       *str << Index();
+       }
+       return str;
+}
 
 
+const char*
+Variable::ToString()
+{
+       BString* str = ToBString();
+       char* result = (char*) malloc(str->Length() + 1);
+       str->CopyInto(result, 0, str->Length());
+       delete str;
+       return result;
+}
+
+
 /**
  * Adds a constraint that sets this variable equal to the given one.
  * 
@@ -162,6 +211,9 @@
 Constraint*
 Variable::IsEqual(Variable* var)
 {
+       if (!fIsValid)
+               return NULL;
+
        return fLS->AddConstraint(1.0, this, -1.0, var, OperatorType(EQ), 0.0);
 }
 
@@ -175,6 +227,9 @@
 Constraint*
 Variable::IsSmallerOrEqual(Variable* var)
 {
+       if (!fIsValid)
+               return NULL;
+
        return fLS->AddConstraint(1.0, this, -1.0, var, OperatorType(LE), 0.0);
 }
 
@@ -186,28 +241,111 @@
  * @return the new constraint
  */
 Constraint*
-Variable::IsGreaterorEqual(Variable* var)
+Variable::IsGreaterOrEqual(Variable* var)
 {
+       if (!fIsValid)
+               return NULL;
+
        return fLS->AddConstraint(-1.0, var, 1.0, this, OperatorType(GE), 0.0);
 }
 
 
+Constraint*
+Variable::IsEqual(Variable* var, double penaltyNeg, double penaltyPos)
+{
+       if (!fIsValid)
+               return NULL;
+
+       return fLS->AddConstraint(1.0, this, -1.0, var, OperatorType(EQ), 0.0,
+               penaltyNeg, penaltyPos);
+}
+
+
+Constraint*
+Variable::IsSmallerOrEqual(Variable* var, double penaltyNeg, double penaltyPos)
+{
+       if (!fIsValid)
+               return NULL;
+
+       return fLS->AddConstraint(1.0, this, -1.0, var, OperatorType(LE), 0.0,
+               penaltyNeg, penaltyPos);
+}
+
+
+Constraint*
+Variable::IsGreaterOrEqual(Variable* var, double penaltyNeg, double penaltyPos)
+{
+       if (!fIsValid)
+               return NULL;
+
+       return fLS->AddConstraint(-1.0, var, 1.0, this, OperatorType(GE), 0.0,
+               penaltyNeg, penaltyPos);
+}
+
+
+bool
+Variable::IsValid()
+{
+       return fIsValid;
+}
+
+
+void
+Variable::Invalidate()
+{
+       STRACE(("Variable::Invalidate() on %s\n", ToString()));
+
+       if (!fIsValid)
+               return;
+
+       fIsValid = false;
+       del_column(fLS->fLP, Index());
+       fLS->Variables()->RemoveItem(this);
+
+       // invalidate all constraints that use this variable
+       BList* markedForInvalidation = new BList();
+       BList* constraints = fLS->Constraints();
+       for (int i = 0; i < constraints->CountItems(); i++) {
+               Constraint* constraint = static_cast<Constraint*>(
+                       constraints->ItemAt(i));
+
+               if (!constraint->IsValid())
+                       continue;

[... truncated: 58 lines follow ...]

Other related posts:

  • » [haiku-commits] r33609 - in haiku/trunk: headers/libs/linprog src/libs/linprog - axeld