
/*
**  This file forms part of the GOBLIN C++ Class Library.
**
**  Written by Christian Fremuth-Paeger, November 2002.
**  
**  Copying, compiling, distribution and modification
**  of this source code is permitted only in accordance
**  with the GOBLIN general licence information.
*/             


#if !defined(_ILPWRAP_H_)

#define _ILPWRAP_H_

#include <absobj.h>


class goblinILPWrapper : public virtual goblinDataObject
{
public:

    goblinILPWrapper() throw();
    virtual ~goblinILPWrapper() throw();

    unsigned long   Allocated() throw();

    bool            IsMixedILP() {return true;};


    // *************************************************************** //
    //                             File IO                             //
    // *************************************************************** //

    enum TDisplayOpt {
        DISPLAY_PROBLEM = 0,
        DISPLAY_OBJECTIVE = 1,
        DISPLAY_RESTRICTIONS = 2,
        DISPLAY_BOUNDS = 4,
        DISPLAY_INTEGERS = 8,
        DISPLAY_FIXED = 16,
        DISPLAY_PRIMAL = 32,
        DISPLAY_DUAL = 64,
        DISPLAY_SLACKS = 128,
        DISPLAY_BASIS = 256,
        DISPLAY_TABLEAU = 512,
        DISPLAY_INVERSE = 1024
    };

    enum TLPFormat
        {MPS_FORMAT=0,LP_FORMAT=1,MPS_CPLEX=2,BAS_CPLEX=3,BAS_GOBLIN=4};
    
    void            Write(char*,TOption = 0) throw(ERFile,ERRejected);
    void            Write(char*,TLPFormat,TOption = 0) throw(ERFile,ERRejected);
    void            WriteLPNaive(char*,TDisplayOpt = DISPLAY_PROBLEM) throw(ERFile,ERRejected);
    void            WriteMPSFile(char*,TLPFormat = MPS_CPLEX) throw(ERFile,ERRejected);
    void            WriteMPSFile(ofstream&,TLPFormat = MPS_CPLEX) throw(ERFile,ERRejected);
    void            WriteBASFile(char*,TLPFormat = BAS_CPLEX) throw(ERFile,ERRejected);
    void            WriteBASFile(ofstream&,TLPFormat = BAS_CPLEX) throw(ERFile,ERRejected);
    char*           Display() throw(ERFile,ERRejected);

    void            Export2XFig(char*) throw(ERFile,ERRejected)
                        {throw ERRejected();};
    void            Export2Tk(char*) throw(ERFile,ERRejected)
                        {throw ERRejected();};
    void            Export2Ascii(char* fileName,TOption opt=0) throw(ERFile)
                        {WriteLPNaive(fileName,TDisplayOpt(opt));};

private:

    TVar            ReadRowLabel(char*) throw();
    TRestr          ReadColLabel(char*,bool) throw();

public:

    void            ReadMPSFile(char*) throw(ERParse,ERRejected);
    void            ReadMPSFile(ifstream&) throw(ERParse,ERRejected);
    void            ReadBASFile(char*) throw(ERParse,ERRejected);
    void            ReadBASFile(ifstream&) throw(ERParse,ERRejected);

    void            NoSuchVar(char*,TVar) throw(ERRange);
    void            NoSuchRestr(char*,TRestr) throw(ERRange);

    
    // *************************************************************** //
    //                      Retrieval Operations                       //
    // *************************************************************** //
    
    virtual TRestr  K() throw() = 0;
    virtual TVar    L() throw() = 0;
    
    virtual TFloat  Cost(TVar) throw(ERRange) = 0;
    virtual TFloat  Coeff(TRestr,TVar) throw(ERRange) = 0;
    virtual TFloat  URange(TVar) throw(ERRange) = 0;
    virtual TFloat  LRange(TVar) throw(ERRange) = 0;
    virtual TFloat  UBound(TRestr) throw(ERRange) = 0;
    virtual TFloat  LBound(TRestr) throw(ERRange) = 0;

    enum TVarType
        {VAR_FLOAT=0,VAR_INT=1,VAR_CANCELED=2};
    virtual TVarType    VarType(TVar) throw(ERRange) = 0;

    virtual char*   VarLabel(TVar,TOwnership = OWNED_BY_RECEIVER) throw(ERRange);
    virtual char*   RestrLabel(TRestr,TOwnership = OWNED_BY_RECEIVER) throw(ERRange);
    char*           UnifiedLabel(TRestr,TOwnership = OWNED_BY_RECEIVER) throw(ERRange);
    virtual TVar    VarIndex(char*) throw();
    virtual TRestr  RestrIndex(char*) throw();

    enum TDirection
        {MAXIMIZE=-1,MINIMIZE=1};
    virtual TDirection  Direction() throw() = 0;

    virtual bool    VarVisibility(TVar) throw(ERRange) {return true;};
    virtual bool    RestrVisibility(TRestr) throw(ERRange) {return true;};

    
    // *************************************************************** //
    //                      Instance Manipulation                      //
    // *************************************************************** //

    virtual TVar    AddVar(TFloat,TFloat,TFloat,TVarType = VAR_FLOAT)
                        throw(ERRejected) = 0;
    virtual TRestr  AddRestr(TFloat,TFloat) throw(ERRejected) = 0;

    virtual void    DeleteVar(TVar) throw(ERRange,ERRejected) = 0;
    virtual void    DeleteRestr(TRestr) throw(ERRange) = 0;

    virtual void    SetURange(TVar,TFloat) throw(ERRange) = 0;
    virtual void    SetLRange(TVar,TFloat) throw(ERRange) = 0;
    virtual void    SetUBound(TRestr,TFloat) throw(ERRange) = 0;
    virtual void    SetLBound(TRestr,TFloat) throw(ERRange) = 0;
    virtual void    SetCoeff(TRestr,TVar,TFloat) throw(ERRange) = 0;
    virtual void    SetCost(TVar,TFloat) throw(ERRange) = 0;
    virtual void    SetVarType(TVar,TVarType) throw(ERRange) = 0;

    virtual void    SetVarLabel(TVar,char*,TOwnership = OWNED_BY_SENDER)
                        throw(ERRange,ERRejected) = 0;
    virtual void    SetRestrLabel(TRestr,char*,TOwnership = OWNED_BY_SENDER)
                        throw(ERRange,ERRejected) = 0;

    virtual void    SetDirection(TDirection) throw() = 0;

    virtual void    SetVarVisibility(TVar,bool) throw(ERRange) {};
    virtual void    SetRestrVisibility(TRestr,bool) throw(ERRange) {};

    virtual void    Resize(TRestr,TVar,TIndex) throw(ERRange) = 0;
    virtual void    Strip() throw() = 0;

    
    // *************************************************************** //
    //                    Basis related information                    //
    // *************************************************************** //

    enum TRestrType     {BASIC_LB=0,BASIC_UB=1,NON_BASIC=2,RESTR_CANCELED=3};

    virtual TRestrType  RestrType(TRestr) throw(ERRange) = 0;
    virtual TRestr  Index(TVar) throw(ERRange) = 0;
    virtual TVar    RevIndex(TRestr) throw(ERRange) = 0;

    enum TLowerUpper    {LOWER=0,UPPER=1};

    virtual void    SetRestrType(TRestr,TLowerUpper) throw(ERRange,ERRejected) = 0;
    virtual void    SetIndex(TRestr,TVar,TLowerUpper) throw(ERRange,ERRejected) = 0;

protected:

    TVar        pivotColumn;
    TRestr      pivotRow;
    TLowerUpper pivotDir;
    
public:

    TVar        PivotColumn() throw() {return pivotColumn;};
    TRestr      PivotRow() throw() {return pivotRow;};
    TLowerUpper PivotDirection() throw() {return pivotDir;};

    virtual void    ResetBasis() throw() = 0;
    virtual bool    Initial() throw() = 0;

    virtual TFloat  X(TVar) throw(ERRange) = 0;
    virtual TFloat  Y(TRestr,TLowerUpper) throw(ERRange) = 0;

    virtual TFloat  Tableau(TVar,TRestr) throw() = 0;
    virtual TFloat  BaseInverse(TVar,TVar) throw(ERRange) = 0;

    virtual TFloat  ObjVal() throw();
    virtual TFloat  Slack(TRestr,TLowerUpper) throw(ERRange);
        // Slack(i,LB)=A_ix-L_i bzw. x_i-l_i;
        // Slack(i,UB)=U_i-A_ix bzw. u_i-x_i;

    virtual bool    PrimalFeasible(TFloat epsilon = 0.01) throw();
    virtual bool    DualFeasible(TFloat epsilon = 0.01) throw();

    
    // *************************************************************** //
    //                           Algorithms                            //
    // *************************************************************** //

    enum TSimplexMethod {SIMPLEX_AUTO=0,SIMPLEX_PRIMAL=1,SIMPLEX_DUAL=2};
    enum TStartBasis    {START_AUTO=0,START_LRANGE=1,START_CURRENT=2};
    enum TPricing       {VAR_PRICING=0,FIRST_FIT=1};
    enum TQTest         {EXACT=0,MAX_ABS=1};

    virtual TFloat  SolvePrimal() throw() = 0;      // Phase II
    virtual TFloat  SolveDual() throw() = 0;        // Phase II
    virtual bool    StartPrimal() throw() = 0;      // Phase I
    virtual bool    StartDual() throw() = 0;        // Phase I
    
    virtual void    Pivot(TRestr,TVar,TLowerUpper) throw(ERRange,ERRejected) = 0;
    virtual TVar    PricePrimal() throw(ERRejected) = 0;
    virtual TRestr  QTestPrimal(TVar) throw(ERRejected) = 0;
    virtual TRestr  PriceDual() throw(ERRejected) = 0;
    virtual TVar    QTestDual(TRestr) throw(ERRejected) = 0;
    
    virtual TFloat  SolveLP() throw();
    virtual TFloat  SolveMixedInteger() throw(ERRejected);

    virtual void    AddCuttingPlane() throw(ERRejected);

};


    // *************************************************************** //
    //              Entry function and package information             //
    // *************************************************************** //

class goblinILPModule : public virtual goblinDataObject
{
public:

    goblinILPModule() throw() {};
    
    virtual ~goblinILPModule() throw() {};

    virtual goblinILPWrapper*
        NewInstance(TRestr,TVar,TIndex,goblinILPWrapper::TDirection,
            goblinController&) throw(ERRange) = 0;

    virtual goblinILPWrapper*
        ReadInstance(char*,goblinController&) throw(ERRange) = 0;

    virtual goblinILPWrapper*
        Reinterprete(void*) throw(ERRange) = 0;

    virtual char*   Authors() throw() = 0;
    virtual int     MajorRelease() throw() = 0;
    virtual int     MinorRelease() throw() = 0;
    virtual char*   PatchLevel() throw() = 0;
    virtual char*   BuildDate() throw() = 0;
    virtual char*   License() throw() = 0;
    
    virtual unsigned long   Size() throw() {return sizeof(goblinILPModule);};

};


#endif
