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