1 // Copyright (C) 2006, International Business Machines
2 // Corporation and others.  All Rights Reserved.
3 // This code is licensed under the terms of the Eclipse Public License (EPL).
4 
5 #include <cassert>
6 #include <cstdlib>
7 #include <cmath>
8 #include <cfloat>
9 
10 #include "CoinPragma.hpp"
11 #include "CoinHelperFunctions.hpp"
12 #include "OsiSolverInterface.hpp"
13 #include "OsiAuxInfo.hpp"
14 
15 // Default Constructor
OsiAuxInfo(void * appData)16 OsiAuxInfo::OsiAuxInfo(void *appData)
17   : appData_(appData)
18 {
19 }
20 
21 // Destructor
~OsiAuxInfo()22 OsiAuxInfo::~OsiAuxInfo()
23 {
24 }
25 
26 // Clone
27 OsiAuxInfo *
clone() const28 OsiAuxInfo::clone() const
29 {
30   return new OsiAuxInfo(*this);
31 }
32 
33 // Copy constructor
OsiAuxInfo(const OsiAuxInfo & rhs)34 OsiAuxInfo::OsiAuxInfo(const OsiAuxInfo &rhs)
35   : appData_(rhs.appData_)
36 {
37 }
38 OsiAuxInfo &
operator =(const OsiAuxInfo & rhs)39 OsiAuxInfo::operator=(const OsiAuxInfo &rhs)
40 {
41   if (this != &rhs) {
42     appData_ = rhs.appData_;
43   }
44   return *this;
45 }
46 // Default Constructor
OsiBabSolver(int solverType)47 OsiBabSolver::OsiBabSolver(int solverType)
48   : OsiAuxInfo()
49   , bestObjectiveValue_(1.0e100)
50   , mipBound_(-1.0e100)
51   , solver_(NULL)
52   , bestSolution_(NULL)
53   , beforeLower_(NULL)
54   , beforeUpper_(NULL)
55   , extraInfo_(NULL)
56   , solverType_(solverType)
57   , sizeSolution_(0)
58   , extraCharacteristics_(0)
59 {
60 }
61 
62 // Destructor
~OsiBabSolver()63 OsiBabSolver::~OsiBabSolver()
64 {
65   delete[] bestSolution_;
66 }
67 
68 // Clone
69 OsiAuxInfo *
clone() const70 OsiBabSolver::clone() const
71 {
72   return new OsiBabSolver(*this);
73 }
74 
75 // Copy constructor
OsiBabSolver(const OsiBabSolver & rhs)76 OsiBabSolver::OsiBabSolver(const OsiBabSolver &rhs)
77   : OsiAuxInfo(rhs)
78   , bestObjectiveValue_(rhs.bestObjectiveValue_)
79   , mipBound_(rhs.mipBound_)
80   , solver_(rhs.solver_)
81   , bestSolution_(NULL)
82   , beforeLower_(rhs.beforeLower_)
83   , beforeUpper_(rhs.beforeUpper_)
84   , extraInfo_(rhs.extraInfo_)
85   , solverType_(rhs.solverType_)
86   , sizeSolution_(rhs.sizeSolution_)
87   , extraCharacteristics_(rhs.extraCharacteristics_)
88 {
89   if (rhs.bestSolution_) {
90     assert(solver_);
91     bestSolution_ = CoinCopyOfArray(rhs.bestSolution_, sizeSolution_);
92   }
93 }
94 OsiBabSolver &
operator =(const OsiBabSolver & rhs)95 OsiBabSolver::operator=(const OsiBabSolver &rhs)
96 {
97   if (this != &rhs) {
98     OsiAuxInfo::operator=(rhs);
99     delete[] bestSolution_;
100     solver_ = rhs.solver_;
101     solverType_ = rhs.solverType_;
102     bestObjectiveValue_ = rhs.bestObjectiveValue_;
103     bestSolution_ = NULL;
104     mipBound_ = rhs.mipBound_;
105     sizeSolution_ = rhs.sizeSolution_;
106     extraCharacteristics_ = rhs.extraCharacteristics_;
107     beforeLower_ = rhs.beforeLower_;
108     beforeUpper_ = rhs.beforeUpper_;
109     extraInfo_ = rhs.extraInfo_;
110     if (rhs.bestSolution_) {
111       assert(solver_);
112       bestSolution_ = CoinCopyOfArray(rhs.bestSolution_, sizeSolution_);
113     }
114   }
115   return *this;
116 }
117 // Returns 1 if solution, 0 if not
solution(double & solutionValue,double * betterSolution,int numberColumns)118 int OsiBabSolver::solution(double &solutionValue,
119   double *betterSolution,
120   int numberColumns)
121 {
122   if (!solver_)
123     return 0;
124   //printf("getSol %x solution_address %x - value %g\n",
125   //       this,bestSolution_,bestObjectiveValue_);
126   if (bestObjectiveValue_ < solutionValue && bestSolution_) {
127     // new solution
128     memcpy(betterSolution, bestSolution_, CoinMin(numberColumns, sizeSolution_) * sizeof(double));
129     if (sizeSolution_ < numberColumns)
130       CoinZeroN(betterSolution + sizeSolution_, numberColumns - sizeSolution_);
131     solutionValue = bestObjectiveValue_;
132     // free up
133     //delete [] bestSolution_;
134     //bestSolution_=NULL;
135     //bestObjectiveValue_=1.0e100;
136     return 1;
137   } else {
138     return 0;
139   }
140 }
141 
hasSolution(double & solutionValue,double * solution)142 bool OsiBabSolver::hasSolution(double &solutionValue, double *solution)
143 {
144   if (!bestSolution_)
145     return false;
146 
147   int numberColumns = solver_->getNumCols();
148   memcpy(solution, bestSolution_, numberColumns * sizeof(double));
149   solutionValue = bestObjectiveValue_;
150   return true;
151 }
152 
153 // set solution
setSolution(const double * solution,int numberColumns,double objectiveValue)154 void OsiBabSolver::setSolution(const double *solution, int numberColumns, double objectiveValue)
155 {
156   assert(solver_);
157   // just in case size has changed
158   delete[] bestSolution_;
159   sizeSolution_ = CoinMin(solver_->getNumCols(), numberColumns);
160   bestSolution_ = new double[sizeSolution_];
161   CoinZeroN(bestSolution_, sizeSolution_);
162   CoinMemcpyN(solution, CoinMin(sizeSolution_, numberColumns), bestSolution_);
163   bestObjectiveValue_ = objectiveValue * solver_->getObjSense();
164 }
165 // Get objective  (well mip bound)
166 double
mipBound() const167 OsiBabSolver::mipBound() const
168 {
169   assert(solver_);
170   if (solverType_ != 3)
171     return solver_->getObjSense() * solver_->getObjValue();
172   else
173     return mipBound_;
174 }
175 // Returns true if node feasible
mipFeasible() const176 bool OsiBabSolver::mipFeasible() const
177 {
178   assert(solver_);
179   if (solverType_ == 0 || solverType_ == 4)
180     return true;
181   else if (solverType_ != 3)
182     return solver_->isProvenOptimal();
183   else
184     return mipBound_ < 1.0e50;
185 }
186 
187 /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
188 */
189