source: trunk/Cbc/src/CbcLinked.hpp @ 2422

Last change on this file since 2422 was 2422, checked in by forrest, 7 months ago

stuff that should be protected not private

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 41.0 KB
Line 
1/* $Id: CbcLinked.hpp 2422 2018-11-16 18:04:34Z forrest $ */
2// Copyright (C) 2006, International Business Machines
3// Corporation and others.  All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6#ifndef CglLinked_H
7#define CglLinked_H
8/* THIS CONTAINS STUFF THAT SHOULD BE IN
9   OsiSolverLink
10   OsiBranchLink
11   CglTemporary
12*/
13#include "CoinModel.hpp"
14#include "OsiClpSolverInterface.hpp"
15#include "OsiChooseVariable.hpp"
16#include "CbcFathom.hpp"
17class CbcModel;
18class CoinPackedMatrix;
19class OsiLinkedBound;
20class OsiObject;
21class CglStored;
22class CglTemporary;
23/**
24
25This is to allow the user to replace initialSolve and resolve
26This version changes coefficients
27*/
28
29class OsiSolverLink : public CbcOsiSolver {
30
31public:
32    //---------------------------------------------------------------------------
33    /**@name Solve methods */
34    //@{
35    /// Solve initial LP relaxation
36    virtual void initialSolve();
37
38    /// Resolve an LP relaxation after problem modification
39    virtual void resolve();
40
41    /**
42       Problem specific
43       Returns -1 if node fathomed and no solution
44                0 if did nothing
45            1 if node fathomed and solution
46       allFixed is true if all LinkedBound variables are fixed
47    */
48    virtual int fathom(bool allFixed) ;
49    /** Solves nonlinear problem from CoinModel using SLP - may be used as crash
50        for other algorithms when number of iterations small.
51        Also exits if all problematical variables are changing
52        less than deltaTolerance
53        Returns solution array
54    */
55    double * nonlinearSLP(int numberPasses, double deltaTolerance);
56    /** Solve linearized quadratic objective branch and bound.
57        Return cutoff and OA cut
58    */
59    double linearizedBAB(CglStored * cut) ;
60    /** Solves nonlinear problem from CoinModel using SLP - and then tries to get
61        heuristic solution
62        Returns solution array
63        mode -
64        0 just get continuous
65        1 round and try normal bab
66        2 use defaultBound_ to bound integer variables near current solution
67    */
68    double * heuristicSolution(int numberPasses, double deltaTolerance, int mode);
69
70    /// Do OA cuts
71    int doAOCuts(CglTemporary * cutGen, const double * solution, const double * solution2);
72    //@}
73
74
75    /**@name Constructors and destructors */
76    //@{
77    /// Default Constructor
78    OsiSolverLink ();
79
80    /** This creates from a coinModel object
81
82        if errors.then number of sets is -1
83
84        This creates linked ordered sets information.  It assumes -
85
86        for product terms syntax is yy*f(zz)
87        also just f(zz) is allowed
88        and even a constant
89
90        modelObject not const as may be changed as part of process.
91    */
92    OsiSolverLink(  CoinModel & modelObject);
93    // Other way with existing object
94    void load(  CoinModel & modelObject, bool tightenBounds = false, int logLevel = 1);
95    /// Clone
96    virtual OsiSolverInterface * clone(bool copyData = true) const;
97
98    /// Copy constructor
99    OsiSolverLink (const OsiSolverLink &);
100
101    /// Assignment operator
102    OsiSolverLink & operator=(const OsiSolverLink& rhs);
103
104    /// Destructor
105    virtual ~OsiSolverLink ();
106
107    //@}
108
109
110    /**@name Sets and Gets */
111    //@{
112    /// Add a bound modifier
113    void addBoundModifier(bool upperBoundAffected, bool useUpperBound, int whichVariable, int whichVariableAffected,
114                          double multiplier = 1.0);
115    /// Update coefficients - returns number updated if in updating mode
116    int updateCoefficients(ClpSimplex * solver, CoinPackedMatrix * matrix);
117    /// Analyze constraints to see which are convex (quadratic)
118    void analyzeObjects();
119    /// Add reformulated bilinear constraints
120    void addTighterConstraints();
121    /// Objective value of best solution found internally
122    inline double bestObjectiveValue() const {
123        return bestObjectiveValue_;
124    }
125    /// Set objective value of best solution found internally
126    inline void setBestObjectiveValue(double value) {
127        bestObjectiveValue_ = value;
128    }
129    /// Best solution found internally
130    inline const double * bestSolution() const {
131        return bestSolution_;
132    }
133    /// Set best solution found internally
134    void setBestSolution(const double * solution, int numberColumns);
135    /// Set special options
136    inline void setSpecialOptions2(int value) {
137        specialOptions2_ = value;
138    }
139    /// Say convex (should work it out) - if convex false then strictly concave
140    void sayConvex(bool convex);
141    /// Get special options
142    inline int specialOptions2() const {
143        return specialOptions2_;
144    }
145    /** Clean copy of matrix
146        So we can add rows
147    */
148    CoinPackedMatrix * cleanMatrix() const {
149        return matrix_;
150    }
151    /** Row copy of matrix
152        Just genuine columns and rows
153        Linear part
154    */
155    CoinPackedMatrix * originalRowCopy() const {
156        return originalRowCopy_;
157    }
158    /// Copy of quadratic model if one
159    ClpSimplex * quadraticModel() const {
160        return quadraticModel_;
161    }
162    /// Gets correct form for a quadratic row - user to delete
163    CoinPackedMatrix * quadraticRow(int rowNumber, double * linear) const;
164    /// Default meshSize
165    inline double defaultMeshSize() const {
166        return defaultMeshSize_;
167    }
168    inline void setDefaultMeshSize(double value) {
169        defaultMeshSize_ = value;
170    }
171    /// Default maximumbound
172    inline double defaultBound() const {
173        return defaultBound_;
174    }
175    inline void setDefaultBound(double value) {
176        defaultBound_ = value;
177    }
178    /// Set integer priority
179    inline void setIntegerPriority(int value) {
180        integerPriority_ = value;
181    }
182    /// Get integer priority
183    inline int integerPriority() const {
184        return integerPriority_;
185    }
186    /// Objective transfer variable if one
187    inline int objectiveVariable() const {
188        return objectiveVariable_;
189    }
190    /// Set biLinear priority
191    inline void setBiLinearPriority(int value) {
192        biLinearPriority_ = value;
193    }
194    /// Get biLinear priority
195    inline int biLinearPriority() const {
196        return biLinearPriority_;
197    }
198    /// Return CoinModel
199    inline const CoinModel * coinModel() const {
200        return &coinModel_;
201    }
202    /// Set all biLinear priorities on x-x variables
203    void setBiLinearPriorities(int value, double meshSize = 1.0);
204    /** Set options and priority on all or some biLinear variables
205        1 - on I-I
206        2 - on I-x
207        4 - on x-x
208        or combinations.
209        -1 means leave (for priority value and strategy value)
210    */
211    void setBranchingStrategyOnVariables(int strategyValue, int priorityValue = -1,
212                                         int mode = 7);
213    /// Set all mesh sizes on x-x variables
214    void setMeshSizes(double value);
215    /** Two tier integer problem where when set of variables with priority
216        less than this are fixed the problem becomes an easier integer problem
217    */
218    void setFixedPriority(int priorityValue);
219    //@}
220
221    //---------------------------------------------------------------------------
222
223protected:
224
225
226    /**@name functions */
227    //@{
228    /// Do real work of initialize
229    //void initialize(ClpSimplex * & solver, OsiObject ** & object) const;
230    /// Do real work of delete
231    void gutsOfDestructor(bool justNullify = false);
232    /// Do real work of copy
233    void gutsOfCopy(const OsiSolverLink & rhs) ;
234    //@}
235
236    /**@name Private member data */
237    //@{
238    /** Clean copy of matrix
239        Marked coefficients will be multiplied by L or U
240    */
241    CoinPackedMatrix * matrix_;
242    /** Row copy of matrix
243        Just genuine columns and rows
244    */
245    CoinPackedMatrix * originalRowCopy_;
246    /// Copy of quadratic model if one
247    ClpSimplex * quadraticModel_;
248    /// Number of rows with nonLinearities
249    int numberNonLinearRows_;
250    /// Starts of lists
251    int * startNonLinear_;
252    /// Row number for a list
253    int * rowNonLinear_;
254    /** Indicator whether is convex, concave or neither
255        -1 concave, 0 neither, +1 convex
256    */
257    int * convex_;
258    /// Indices in a list/row
259    int * whichNonLinear_;
260    /// Model in CoinModel format
261    CoinModel coinModel_;
262    /// Number of variables in tightening phase
263    int numberVariables_;
264    /// Information
265    OsiLinkedBound * info_;
266    /**
267       0 bit (1) - call fathom (may do mini B&B)
268       1 bit (2) - quadratic only in objective (add OA cuts)
269       2 bit (4) - convex
270       3 bit (8) - try adding OA cuts
271       4 bit (16) - add linearized constraints
272    */
273    int specialOptions2_;
274    /// Objective transfer row if one
275    int objectiveRow_;
276    /// Objective transfer variable if one
277    int objectiveVariable_;
278    /// Objective value of best solution found internally
279    double bestObjectiveValue_;
280    /// Default mesh
281    double defaultMeshSize_;
282    /// Default maximum bound
283    double defaultBound_;
284    /// Best solution found internally
285    double * bestSolution_;
286    /// Priority for integers
287    int integerPriority_;
288    /// Priority for bilinear
289    int biLinearPriority_;
290    /// Number of variables which when fixed help
291    int numberFix_;
292    /// list of fixed variables
293    int * fixVariables_;
294    //@}
295};
296/**
297   List of bounds which depend on other bounds
298*/
299
300class OsiLinkedBound {
301
302public:
303    //---------------------------------------------------------------------------
304    /**@name Action methods */
305    //@{
306    /// Update other bounds
307    void updateBounds(ClpSimplex * solver);
308    //@}
309
310
311    /**@name Constructors and destructors */
312    //@{
313    /// Default Constructor
314    OsiLinkedBound ();
315    /// Useful Constructor
316    OsiLinkedBound(OsiSolverInterface * model, int variable,
317                   int numberAffected, const int * positionL,
318                   const int * positionU, const double * multiplier);
319
320    /// Copy constructor
321    OsiLinkedBound (const OsiLinkedBound &);
322
323    /// Assignment operator
324    OsiLinkedBound & operator=(const OsiLinkedBound& rhs);
325
326    /// Destructor
327    ~OsiLinkedBound ();
328
329    //@}
330
331    /**@name Sets and Gets */
332    //@{
333    /// Get variable
334    inline int variable() const {
335        return variable_;
336    }
337    /// Add a bound modifier
338    void addBoundModifier(bool upperBoundAffected, bool useUpperBound, int whichVariable,
339                          double multiplier = 1.0);
340    //@}
341
342protected:
343    typedef struct {
344        double multiplier; // to use in computation
345        int affected; // variable or element affected
346        /*
347          0 - LB of variable affected
348          1 - UB of variable affected
349          2 - element in position (affected) affected
350        */
351        unsigned char affect;
352        unsigned char ubUsed; // nonzero if UB of this variable is used
353        /*
354           0 - use x*multiplier
355           1 - use multiplier/x
356           2 - if UB use min of current upper and x*multiplier, if LB use max of current lower and x*multiplier
357        */
358        unsigned char type; // type of computation
359    } boundElementAction;
360
361    /**@name Private member data */
362    //@{
363    /// Pointer back to model
364    OsiSolverInterface * model_;
365    /// Variable
366    int variable_;
367    /// Number of variables/elements affected
368    int numberAffected_;
369    /// Maximum number of variables/elements affected
370    int maximumAffected_;
371    /// Actions
372    boundElementAction * affected_;
373    //@}
374};
375#include "CbcHeuristic.hpp"
376/** heuristic - just picks up any good solution
377 */
378
379class CbcHeuristicDynamic3 : public CbcHeuristic {
380public:
381
382    // Default Constructor
383    CbcHeuristicDynamic3 ();
384
385    /* Constructor with model
386     */
387    CbcHeuristicDynamic3 (CbcModel & model);
388
389    // Copy constructor
390    CbcHeuristicDynamic3 ( const CbcHeuristicDynamic3 &);
391
392    // Destructor
393    ~CbcHeuristicDynamic3 ();
394
395    /// Clone
396    virtual CbcHeuristic * clone() const;
397
398    /// update model
399    virtual void setModel(CbcModel * model);
400
401    using CbcHeuristic::solution ;
402    /** returns 0 if no solution, 1 if valid solution.
403        Sets solution values if good, sets objective value (only if good)
404        We leave all variables which are at one at this node of the
405        tree to that value and will
406        initially set all others to zero.  We then sort all variables in order of their cost
407        divided by the number of entries in rows which are not yet covered.  We randomize that
408        value a bit so that ties will be broken in different ways on different runs of the heuristic.
409        We then choose the best one and set it to one and repeat the exercise.
410
411    */
412    virtual int solution(double & objectiveValue,
413                         double * newSolution);
414    /// Resets stuff if model changes
415    virtual void resetModel(CbcModel * model);
416    /// Returns true if can deal with "odd" problems e.g. sos type 2
417    virtual bool canDealWithOdd() const {
418        return true;
419    }
420
421private:
422    /// Illegal Assignment operator
423    CbcHeuristicDynamic3 & operator=(const CbcHeuristicDynamic3& rhs);
424};
425
426#include "OsiBranchingObject.hpp"
427
428/** Define Special Linked Ordered Sets.
429
430*/
431class CoinWarmStartBasis;
432
433class OsiOldLink : public OsiSOS {
434
435public:
436
437    // Default Constructor
438    OsiOldLink ();
439
440    /** Useful constructor - A valid solution is if all variables are zero
441        apart from k*numberLink to (k+1)*numberLink-1 where k is 0 through
442        numberInSet-1.  The length of weights array is numberInSet.
443        For this constructor the variables in matrix are the numberInSet*numberLink
444        starting at first. If weights null then 0,1,2..
445    */
446    OsiOldLink (const OsiSolverInterface * solver, int numberMembers,
447                int numberLinks, int first,
448                const double * weights, int setNumber);
449    /** Useful constructor - A valid solution is if all variables are zero
450        apart from k*numberLink to (k+1)*numberLink-1 where k is 0 through
451        numberInSet-1.  The length of weights array is numberInSet.
452        For this constructor the variables are given by list - grouped.
453        If weights null then 0,1,2..
454    */
455    OsiOldLink (const OsiSolverInterface * solver, int numberMembers,
456                int numberLinks, int typeSOS, const int * which,
457                const double * weights, int setNumber);
458
459    // Copy constructor
460    OsiOldLink ( const OsiOldLink &);
461
462    /// Clone
463    virtual OsiObject * clone() const;
464
465    // Assignment operator
466    OsiOldLink & operator=( const OsiOldLink& rhs);
467
468    // Destructor
469    virtual ~OsiOldLink ();
470
471    using OsiObject::infeasibility ;
472    /// Infeasibility - large is 0.5
473    virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const;
474
475    using OsiObject::feasibleRegion ;
476    /** Set bounds to fix the variable at the current (integer) value.
477
478      Given an integer value, set the lower and upper bounds to fix the
479      variable. Returns amount it had to move variable.
480    */
481    virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const;
482
483    /** Creates a branching object
484
485      The preferred direction is set by \p way, 0 for down, 1 for up.
486    */
487    virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const;
488
489    /// Redoes data when sequence numbers change
490    virtual void resetSequenceEtc(int numberColumns, const int * originalColumns);
491
492    /// Number of links for each member
493    inline int numberLinks() const {
494        return numberLinks_;
495    }
496
497    /** \brief Return true if object can take part in normal heuristics
498    */
499    virtual bool canDoHeuristics() const {
500        return false;
501    }
502    /** \brief Return true if branch should only bound variables
503    */
504    virtual bool boundBranch() const {
505        return false;
506    }
507
508protected:
509    /// data
510
511    /// Number of links
512    int numberLinks_;
513};
514/** Branching object for Linked ordered sets
515
516 */
517class OsiOldLinkBranchingObject : public OsiSOSBranchingObject {
518
519public:
520
521    // Default Constructor
522    OsiOldLinkBranchingObject ();
523
524    // Useful constructor
525    OsiOldLinkBranchingObject (OsiSolverInterface * solver,  const OsiOldLink * originalObject,
526                               int way,
527                               double separator);
528
529    // Copy constructor
530    OsiOldLinkBranchingObject ( const OsiOldLinkBranchingObject &);
531
532    // Assignment operator
533    OsiOldLinkBranchingObject & operator=( const OsiOldLinkBranchingObject& rhs);
534
535    /// Clone
536    virtual OsiBranchingObject * clone() const;
537
538    // Destructor
539    virtual ~OsiOldLinkBranchingObject ();
540
541    using OsiBranchingObject::branch ;
542    /// Does next branch and updates state
543    virtual double branch(OsiSolverInterface * solver);
544
545    using OsiBranchingObject::print ;
546    /** \brief Print something about branch - only if log level high
547    */
548    virtual void print(const OsiSolverInterface * solver = NULL);
549private:
550    /// data
551};
552/** Define data for one link
553
554*/
555
556
557class OsiOneLink {
558
559public:
560
561    // Default Constructor
562    OsiOneLink ();
563
564    /** Useful constructor -
565
566    */
567    OsiOneLink (const OsiSolverInterface * solver, int xRow, int xColumn, int xyRow,
568                const char * functionString);
569
570    // Copy constructor
571    OsiOneLink ( const OsiOneLink &);
572
573    // Assignment operator
574    OsiOneLink & operator=( const OsiOneLink& rhs);
575
576    // Destructor
577    virtual ~OsiOneLink ();
578
579    /// data
580
581    /// Row which defines x (if -1 then no x)
582    int xRow_;
583    /// Column which defines x
584    int xColumn_;
585    /// Output row
586    int xyRow;
587    /// Function
588    std::string function_;
589};
590/** Define Special Linked Ordered Sets. New style
591
592    members and weights may be stored in SOS object
593
594    This is for y and x*f(y) and z*g(y) etc
595
596*/
597
598
599class OsiLink : public OsiSOS {
600
601public:
602
603    // Default Constructor
604    OsiLink ();
605
606    /** Useful constructor -
607
608    */
609    OsiLink (const OsiSolverInterface * solver, int yRow,
610             int yColumn, double meshSize);
611
612    // Copy constructor
613    OsiLink ( const OsiLink &);
614
615    /// Clone
616    virtual OsiObject * clone() const;
617
618    // Assignment operator
619    OsiLink & operator=( const OsiLink& rhs);
620
621    // Destructor
622    virtual ~OsiLink ();
623
624    using OsiObject::infeasibility ;
625    /// Infeasibility - large is 0.5
626    virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const;
627
628    using OsiObject::feasibleRegion ;
629    /** Set bounds to fix the variable at the current (integer) value.
630
631      Given an integer value, set the lower and upper bounds to fix the
632      variable. Returns amount it had to move variable.
633    */
634    virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const;
635
636    /** Creates a branching object
637
638      The preferred direction is set by \p way, 0 for down, 1 for up.
639    */
640    virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const;
641
642    /// Redoes data when sequence numbers change
643    virtual void resetSequenceEtc(int numberColumns, const int * originalColumns);
644
645    /// Number of links for each member
646    inline int numberLinks() const {
647        return numberLinks_;
648    }
649
650    /** \brief Return true if object can take part in normal heuristics
651    */
652    virtual bool canDoHeuristics() const {
653        return false;
654    }
655    /** \brief Return true if branch should only bound variables
656    */
657    virtual bool boundBranch() const {
658        return false;
659    }
660
661protected:
662    /// data
663    /// Current increment for y points
664    double meshSize_;
665    /// Links
666    OsiOneLink * data_;
667    /// Number of links
668    int numberLinks_;
669    /// Row which defines y
670    int yRow_;
671    /// Column which defines y
672    int yColumn_;
673};
674/** Branching object for Linked ordered sets
675
676 */
677class OsiLinkBranchingObject : public OsiTwoWayBranchingObject {
678
679public:
680
681    // Default Constructor
682    OsiLinkBranchingObject ();
683
684    // Useful constructor
685    OsiLinkBranchingObject (OsiSolverInterface * solver,  const OsiLink * originalObject,
686                            int way,
687                            double separator);
688
689    // Copy constructor
690    OsiLinkBranchingObject ( const OsiLinkBranchingObject &);
691
692    // Assignment operator
693    OsiLinkBranchingObject & operator=( const OsiLinkBranchingObject& rhs);
694
695    /// Clone
696    virtual OsiBranchingObject * clone() const;
697
698    // Destructor
699    virtual ~OsiLinkBranchingObject ();
700
701    using OsiBranchingObject::branch ;
702    /// Does next branch and updates state
703    virtual double branch(OsiSolverInterface * solver);
704
705    using OsiBranchingObject::print ;
706    /** \brief Print something about branch - only if log level high
707    */
708    virtual void print(const OsiSolverInterface * solver = NULL);
709private:
710    /// data
711};
712/** Define BiLinear objects
713
714    This models x*y where one or both are integer
715
716*/
717
718
719class OsiBiLinear : public OsiObject2 {
720
721public:
722
723    // Default Constructor
724    OsiBiLinear ();
725
726    /** Useful constructor -
727        This Adds in rows and variables to construct valid Linked Ordered Set
728        Adds extra constraints to match other x/y
729        So note not const solver
730    */
731    OsiBiLinear (OsiSolverInterface * solver, int xColumn,
732                 int yColumn, int xyRow, double coefficient,
733                 double xMesh, double yMesh,
734                 int numberExistingObjects = 0, const OsiObject ** objects = NULL );
735
736    /** Useful constructor -
737        This Adds in rows and variables to construct valid Linked Ordered Set
738        Adds extra constraints to match other x/y
739        So note not const model
740    */
741    OsiBiLinear (CoinModel * coinModel, int xColumn,
742                 int yColumn, int xyRow, double coefficient,
743                 double xMesh, double yMesh,
744                 int numberExistingObjects = 0, const OsiObject ** objects = NULL );
745
746    // Copy constructor
747    OsiBiLinear ( const OsiBiLinear &);
748
749    /// Clone
750    virtual OsiObject * clone() const;
751
752    // Assignment operator
753    OsiBiLinear & operator=( const OsiBiLinear& rhs);
754
755    // Destructor
756    virtual ~OsiBiLinear ();
757
758    using OsiObject::infeasibility ;
759    /// Infeasibility - large is 0.5
760    virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const;
761
762    using OsiObject::feasibleRegion ;
763    /** Set bounds to fix the variable at the current (integer) value.
764
765      Given an integer value, set the lower and upper bounds to fix the
766      variable. Returns amount it had to move variable.
767    */
768    virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const;
769
770    /** Creates a branching object
771
772      The preferred direction is set by \p way, 0 for down, 1 for up.
773    */
774    virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const;
775
776    /// Redoes data when sequence numbers change
777    virtual void resetSequenceEtc(int numberColumns, const int * originalColumns);
778
779    // This does NOT set mutable stuff
780    virtual double checkInfeasibility(const OsiBranchingInformation * info) const;
781
782    /** \brief Return true if object can take part in normal heuristics
783    */
784    virtual bool canDoHeuristics() const {
785        return false;
786    }
787    /** \brief Return true if branch should only bound variables
788    */
789    virtual bool boundBranch() const {
790        return (branchingStrategy_&4) != 0;
791    }
792    /// X column
793    inline int xColumn() const {
794        return xColumn_;
795    }
796    /// Y column
797    inline int yColumn() const {
798        return yColumn_;
799    }
800    /// X row
801    inline int xRow() const {
802        return xRow_;
803    }
804    /// Y row
805    inline int yRow() const {
806        return yRow_;
807    }
808    /// XY row
809    inline int xyRow() const {
810        return xyRow_;
811    }
812    /// Coefficient
813    inline double coefficient() const {
814        return coefficient_;
815    }
816    /// Set coefficient
817    inline void setCoefficient(double value) {
818        coefficient_ = value;
819    }
820    /// First lambda (of 4)
821    inline int firstLambda() const {
822        return firstLambda_;
823    }
824    /// X satisfied if less than this away from mesh
825    inline double xSatisfied() const {
826        return xSatisfied_;
827    }
828    inline void setXSatisfied(double value) {
829        xSatisfied_ = value;
830    }
831    /// Y satisfied if less than this away from mesh
832    inline double ySatisfied() const {
833        return ySatisfied_;
834    }
835    inline void setYSatisfied(double value) {
836        ySatisfied_ = value;
837    }
838    /// X other satisfied if less than this away from mesh
839    inline double xOtherSatisfied() const {
840        return xOtherSatisfied_;
841    }
842    inline void setXOtherSatisfied(double value) {
843        xOtherSatisfied_ = value;
844    }
845    /// Y other satisfied if less than this away from mesh
846    inline double yOtherSatisfied() const {
847        return yOtherSatisfied_;
848    }
849    inline void setYOtherSatisfied(double value) {
850        yOtherSatisfied_ = value;
851    }
852    /// X meshSize
853    inline double xMeshSize() const {
854        return xMeshSize_;
855    }
856    inline void setXMeshSize(double value) {
857        xMeshSize_ = value;
858    }
859    /// Y meshSize
860    inline double yMeshSize() const {
861        return yMeshSize_;
862    }
863    inline void setYMeshSize(double value) {
864        yMeshSize_ = value;
865    }
866    /// XY satisfied if two version differ by less than this
867    inline double xySatisfied() const {
868        return xySatisfied_;
869    }
870    inline void setXYSatisfied(double value) {
871        xySatisfied_ = value;
872    }
873    /// Set sizes and other stuff
874    void setMeshSizes(const OsiSolverInterface * solver, double x, double y);
875    /** branching strategy etc
876        bottom 2 bits
877        0 branch on either, 1 branch on x, 2 branch on y
878        next bit
879        4 set to say don't update coefficients
880        next bit
881        8 set to say don't use in feasible region
882        next bit
883        16 set to say - Always satisfied !!
884    */
885    inline int branchingStrategy() const {
886        return branchingStrategy_;
887    }
888    inline void setBranchingStrategy(int value) {
889        branchingStrategy_ = value;
890    }
891    /** Simple quadratic bound marker.
892        0 no
893        1 L if coefficient pos, G if negative i.e. value is ub on xy
894        2 G if coefficient pos, L if negative i.e. value is lb on xy
895        3 E
896        If bound then real coefficient is 1.0 and coefficient_ is bound
897    */
898    inline int boundType() const {
899        return boundType_;
900    }
901    inline void setBoundType(int value) {
902        boundType_ = value;
903    }
904    /// Does work of branching
905    void newBounds(OsiSolverInterface * solver, int way, short xOrY, double separator) const;
906    /// Updates coefficients - returns number updated
907    int updateCoefficients(const double * lower, const double * upper, double * objective,
908                           CoinPackedMatrix * matrix, CoinWarmStartBasis * basis) const;
909    /// Returns true value of single xyRow coefficient
910    double xyCoefficient(const double * solution) const;
911    /// Get LU coefficients from matrix
912    void getCoefficients(const OsiSolverInterface * solver, double xB[2], double yB[2], double xybar[4]) const;
913    /// Compute lambdas (third entry in each .B is current value) (nonzero if bad)
914    double computeLambdas(const double xB[3], const double yB[3], const double xybar[4], double lambda[4]) const;
915    /// Adds in data for extra row with variable coefficients
916    void addExtraRow(int row, double multiplier);
917    /// Sets infeasibility and other when pseudo shadow prices
918    void getPseudoShadow(const OsiBranchingInformation * info);
919    /// Gets sum of movements to correct value
920    double getMovement(const OsiBranchingInformation * info);
921
922protected:
923    /// Compute lambdas if coefficients not changing
924    void computeLambdas(const OsiSolverInterface * solver, double lambda[4]) const;
925    /// data
926
927    /// Coefficient
928    double coefficient_;
929    /// x mesh
930    double xMeshSize_;
931    /// y mesh
932    double yMeshSize_;
933    /// x satisfied if less than this away from mesh
934    double xSatisfied_;
935    /// y satisfied if less than this away from mesh
936    double ySatisfied_;
937    /// X other satisfied if less than this away from mesh
938    double xOtherSatisfied_;
939    /// Y other satisfied if less than this away from mesh
940    double yOtherSatisfied_;
941    /// xy satisfied if less than this away from true
942    double xySatisfied_;
943    /// value of x or y to branch about
944    mutable double xyBranchValue_;
945    /// x column
946    int xColumn_;
947    /// y column
948    int yColumn_;
949    /// First lambda (of 4)
950    int firstLambda_;
951    /** branching strategy etc
952        bottom 2 bits
953        0 branch on either, 1 branch on x, 2 branch on y
954        next bit
955        4 set to say don't update coefficients
956        next bit
957        8 set to say don't use in feasible region
958        next bit
959        16 set to say - Always satisfied !!
960    */
961    int branchingStrategy_;
962    /** Simple quadratic bound marker.
963        0 no
964        1 L if coefficient pos, G if negative i.e. value is ub on xy
965        2 G if coefficient pos, L if negative i.e. value is lb on xy
966        3 E
967        If bound then real coefficient is 1.0 and coefficient_ is bound
968    */
969    int boundType_;
970    /// x row
971    int xRow_;
972    /// y row (-1 if x*x)
973    int yRow_;
974    /// Output row
975    int xyRow_;
976    /// Convexity row
977    int convexity_;
978    /// Number of extra rows (coefficients to be modified)
979    int numberExtraRows_;
980    /// Multiplier for coefficient on row
981    double * multiplier_;
982    /// Row number
983    int * extraRow_;
984    /// Which chosen -1 none, 0 x, 1 y
985    mutable short chosen_;
986};
987/** Branching object for BiLinear objects
988
989 */
990class OsiBiLinearBranchingObject : public OsiTwoWayBranchingObject {
991
992public:
993
994    // Default Constructor
995    OsiBiLinearBranchingObject ();
996
997    // Useful constructor
998    OsiBiLinearBranchingObject (OsiSolverInterface * solver,  const OsiBiLinear * originalObject,
999                                int way,
1000                                double separator, int chosen);
1001
1002    // Copy constructor
1003    OsiBiLinearBranchingObject ( const OsiBiLinearBranchingObject &);
1004
1005    // Assignment operator
1006    OsiBiLinearBranchingObject & operator=( const OsiBiLinearBranchingObject& rhs);
1007
1008    /// Clone
1009    virtual OsiBranchingObject * clone() const;
1010
1011    // Destructor
1012    virtual ~OsiBiLinearBranchingObject ();
1013
1014    using OsiBranchingObject::branch ;
1015    /// Does next branch and updates state
1016    virtual double branch(OsiSolverInterface * solver);
1017
1018    using OsiBranchingObject::print ;
1019    /** \brief Print something about branch - only if log level high
1020    */
1021    virtual void print(const OsiSolverInterface * solver = NULL);
1022    /** \brief Return true if branch should only bound variables
1023    */
1024    virtual bool boundBranch() const;
1025protected:
1026    /// data
1027    /// 1 means branch on x, 2 branch on y
1028    short chosen_;
1029};
1030/** Define Continuous BiLinear objects for an == bound
1031
1032    This models x*y = b where both are continuous
1033
1034*/
1035
1036
1037class OsiBiLinearEquality : public OsiBiLinear {
1038
1039public:
1040
1041    // Default Constructor
1042    OsiBiLinearEquality ();
1043
1044    /** Useful constructor -
1045        This Adds in rows and variables to construct Ordered Set
1046        for x*y = b
1047        So note not const solver
1048    */
1049    OsiBiLinearEquality (OsiSolverInterface * solver, int xColumn,
1050                         int yColumn, int xyRow, double rhs,
1051                         double xMesh);
1052
1053    // Copy constructor
1054    OsiBiLinearEquality ( const OsiBiLinearEquality &);
1055
1056    /// Clone
1057    virtual OsiObject * clone() const;
1058
1059    // Assignment operator
1060    OsiBiLinearEquality & operator=( const OsiBiLinearEquality& rhs);
1061
1062    // Destructor
1063    virtual ~OsiBiLinearEquality ();
1064
1065    /// Possible improvement
1066    virtual double improvement(const OsiSolverInterface * solver) const;
1067    /** change grid
1068        if type 0 then use solution and make finer
1069        if 1 then back to original
1070        returns mesh size
1071    */
1072    double newGrid(OsiSolverInterface * solver, int type) const;
1073    /// Number of points
1074    inline int numberPoints() const {
1075        return numberPoints_;
1076    }
1077    inline void setNumberPoints(int value) {
1078        numberPoints_ = value;
1079    }
1080
1081protected:
1082    /// Number of points
1083    int numberPoints_;
1084};
1085/// Define a single integer class - but one where you keep branching until fixed even if satisfied
1086
1087
1088class OsiSimpleFixedInteger : public OsiSimpleInteger {
1089
1090public:
1091
1092    /// Default Constructor
1093    OsiSimpleFixedInteger ();
1094
1095    /// Useful constructor - passed solver index
1096    OsiSimpleFixedInteger (const OsiSolverInterface * solver, int iColumn);
1097
1098    /// Useful constructor - passed solver index and original bounds
1099    OsiSimpleFixedInteger (int iColumn, double lower, double upper);
1100
1101    /// Useful constructor - passed simple integer
1102    OsiSimpleFixedInteger (const OsiSimpleInteger &);
1103
1104    /// Copy constructor
1105    OsiSimpleFixedInteger ( const OsiSimpleFixedInteger &);
1106
1107    /// Clone
1108    virtual OsiObject * clone() const;
1109
1110    /// Assignment operator
1111    OsiSimpleFixedInteger & operator=( const OsiSimpleFixedInteger& rhs);
1112
1113    /// Destructor
1114    virtual ~OsiSimpleFixedInteger ();
1115
1116    using OsiObject::infeasibility ;
1117    /// Infeasibility - large is 0.5
1118    virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const;
1119
1120    /** Creates a branching object
1121
1122      The preferred direction is set by \p way, 0 for down, 1 for up.
1123    */
1124    virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const;
1125protected:
1126    /// data
1127
1128};
1129/** Define a single variable class which is involved with OsiBiLinear objects.
1130    This is used so can make better decision on where to branch as it can look at
1131    all objects.
1132
1133    This version sees if it can re-use code from OsiSimpleInteger
1134    even if not an integer variable.  If not then need to duplicate code.
1135*/
1136
1137
1138class OsiUsesBiLinear : public OsiSimpleInteger {
1139
1140public:
1141
1142    /// Default Constructor
1143    OsiUsesBiLinear ();
1144
1145    /// Useful constructor - passed solver index
1146    OsiUsesBiLinear (const OsiSolverInterface * solver, int iColumn, int type);
1147
1148    /// Useful constructor - passed solver index and original bounds
1149    OsiUsesBiLinear (int iColumn, double lower, double upper, int type);
1150
1151    /// Useful constructor - passed simple integer
1152    OsiUsesBiLinear (const OsiSimpleInteger & rhs, int type);
1153
1154    /// Copy constructor
1155    OsiUsesBiLinear ( const OsiUsesBiLinear & rhs);
1156
1157    /// Clone
1158    virtual OsiObject * clone() const;
1159
1160    /// Assignment operator
1161    OsiUsesBiLinear & operator=( const OsiUsesBiLinear& rhs);
1162
1163    /// Destructor
1164    virtual ~OsiUsesBiLinear ();
1165
1166    using OsiObject::infeasibility ;
1167    /// Infeasibility - large is 0.5
1168    virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const;
1169
1170    /** Creates a branching object
1171
1172      The preferred direction is set by \p way, 0 for down, 1 for up.
1173    */
1174    virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const;
1175
1176    using OsiObject::feasibleRegion ;
1177    /** Set bounds to fix the variable at the current value.
1178
1179      Given an current value, set the lower and upper bounds to fix the
1180      variable. Returns amount it had to move variable.
1181    */
1182    virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const;
1183
1184    /// Add all bi-linear objects
1185    void addBiLinearObjects(OsiSolverLink * solver);
1186protected:
1187    /// data
1188    /// Number of bilinear objects (maybe could be more general)
1189    int numberBiLinear_;
1190    /// Type of variable - 0 continuous, 1 integer
1191    int type_;
1192    /// Objects
1193    OsiObject ** objects_;
1194};
1195/** This class chooses a variable to branch on
1196
1197    This is just as OsiChooseStrong but it fakes it so only
1198    first so many are looked at in this phase
1199
1200*/
1201
1202class OsiChooseStrongSubset  : public OsiChooseStrong {
1203
1204public:
1205
1206    /// Default Constructor
1207    OsiChooseStrongSubset ();
1208
1209    /// Constructor from solver (so we can set up arrays etc)
1210    OsiChooseStrongSubset (const OsiSolverInterface * solver);
1211
1212    /// Copy constructor
1213    OsiChooseStrongSubset (const OsiChooseStrongSubset &);
1214
1215    /// Assignment operator
1216    OsiChooseStrongSubset & operator= (const OsiChooseStrongSubset& rhs);
1217
1218    /// Clone
1219    virtual OsiChooseVariable * clone() const;
1220
1221    /// Destructor
1222    virtual ~OsiChooseStrongSubset ();
1223
1224    /** Sets up strong list and clears all if initialize is true.
1225        Returns number of infeasibilities.
1226        If returns -1 then has worked out node is infeasible!
1227    */
1228    virtual int setupList ( OsiBranchingInformation *info, bool initialize);
1229    /** Choose a variable
1230        Returns -
1231       -1 Node is infeasible
1232       0  Normal termination - we have a candidate
1233       1  All looks satisfied - no candidate
1234       2  We can change the bound on a variable - but we also have a strong branching candidate
1235       3  We can change the bound on a variable - but we have a non-strong branching candidate
1236       4  We can change the bound on a variable - no other candidates
1237       We can pick up branch from bestObjectIndex() and bestWhichWay()
1238       We can pick up a forced branch (can change bound) from firstForcedObjectIndex() and firstForcedWhichWay()
1239       If we have a solution then we can pick up from goodObjectiveValue() and goodSolution()
1240       If fixVariables is true then 2,3,4 are all really same as problem changed
1241    */
1242    virtual int chooseVariable( OsiSolverInterface * solver, OsiBranchingInformation *info, bool fixVariables);
1243
1244    /// Number of objects to use
1245    inline int numberObjectsToUse() const {
1246        return numberObjectsToUse_;
1247    }
1248    /// Set number of objects to use
1249    inline void setNumberObjectsToUse(int value) {
1250        numberObjectsToUse_ = value;
1251    }
1252
1253protected:
1254    // Data
1255    /// Number of objects to be used (and set in solver)
1256    int numberObjectsToUse_;
1257};
1258
1259#include <string>
1260
1261#include "CglStored.hpp"
1262
1263class CoinWarmStartBasis;
1264/** Stored Temporary Cut Generator Class - destroyed after first use */
1265class CglTemporary : public CglStored {
1266
1267public:
1268
1269
1270    /**@name Generate Cuts */
1271    //@{
1272    /** Generate Mixed Integer Stored cuts for the model of the
1273        solver interface, si.
1274
1275        Insert the generated cuts into OsiCut, cs.
1276
1277        This generator just looks at previously stored cuts
1278        and inserts any that are violated by enough
1279    */
1280    virtual void generateCuts( const OsiSolverInterface & si, OsiCuts & cs,
1281                               const CglTreeInfo info = CglTreeInfo());
1282    //@}
1283
1284    /**@name Constructors and destructors */
1285    //@{
1286    /// Default constructor
1287    CglTemporary ();
1288
1289    /// Copy constructor
1290    CglTemporary (const CglTemporary & rhs);
1291
1292    /// Clone
1293    virtual CglCutGenerator * clone() const;
1294
1295    /// Assignment operator
1296    CglTemporary &
1297    operator=(const CglTemporary& rhs);
1298
1299    /// Destructor
1300    virtual
1301    ~CglTemporary ();
1302    //@}
1303
1304private:
1305
1306// Private member methods
1307
1308    // Private member data
1309};
1310//#############################################################################
1311
1312/**
1313
1314This is to allow the user to replace initialSolve and resolve
1315*/
1316
1317class OsiSolverLinearizedQuadratic : public OsiClpSolverInterface {
1318
1319public:
1320    //---------------------------------------------------------------------------
1321    /**@name Solve methods */
1322    //@{
1323    /// Solve initial LP relaxation
1324    virtual void initialSolve();
1325    //@}
1326
1327
1328    /**@name Constructors and destructors */
1329    //@{
1330    /// Default Constructor
1331    OsiSolverLinearizedQuadratic ();
1332    /// Useful constructor (solution should be good)
1333    OsiSolverLinearizedQuadratic(  ClpSimplex * quadraticModel);
1334    /// Clone
1335    virtual OsiSolverInterface * clone(bool copyData = true) const;
1336
1337    /// Copy constructor
1338    OsiSolverLinearizedQuadratic (const OsiSolverLinearizedQuadratic &);
1339
1340    /// Assignment operator
1341    OsiSolverLinearizedQuadratic & operator=(const OsiSolverLinearizedQuadratic& rhs);
1342
1343    /// Destructor
1344    virtual ~OsiSolverLinearizedQuadratic ();
1345
1346    //@}
1347
1348
1349    /**@name Sets and Gets */
1350    //@{
1351    /// Objective value of best solution found internally
1352    inline double bestObjectiveValue() const {
1353        return bestObjectiveValue_;
1354    }
1355    /// Best solution found internally
1356    const double * bestSolution() const {
1357        return bestSolution_;
1358    }
1359    /// Set special options
1360    inline void setSpecialOptions3(int value) {
1361        specialOptions3_ = value;
1362    }
1363    /// Get special options
1364    inline int specialOptions3() const {
1365        return specialOptions3_;
1366    }
1367    /// Copy of quadratic model if one
1368    ClpSimplex * quadraticModel() const {
1369        return quadraticModel_;
1370    }
1371    //@}
1372
1373    //---------------------------------------------------------------------------
1374
1375protected:
1376
1377
1378    /**@name functions */
1379    //@{
1380
1381    /**@name Private member data */
1382    //@{
1383    /// Objective value of best solution found internally
1384    double bestObjectiveValue_;
1385    /// Copy of quadratic model if one
1386    ClpSimplex * quadraticModel_;
1387    /// Best solution found internally
1388    double * bestSolution_;
1389    /**
1390       0 bit (1) - don't do mini B&B
1391       1 bit (2) - quadratic only in objective
1392    */
1393    int specialOptions3_;
1394    //@}
1395};
1396class ClpSimplex;
1397/** Return an approximate solution to a CoinModel.
1398    Lots of bounds may be odd to force a solution.
1399    mode = 0 just tries to get a continuous solution
1400*/
1401ClpSimplex * approximateSolution(CoinModel & coinModel,
1402                                 int numberPasses, double deltaTolerance,
1403                                 int mode = 0);
1404#endif
1405
Note: See TracBrowser for help on using the repository browser.