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 |
16 | OsiAuxInfo::OsiAuxInfo(void * appData) |
17 | : appData_(appData) |
18 | { |
19 | } |
20 | |
21 | // Destructor |
22 | OsiAuxInfo::~OsiAuxInfo () |
23 | { |
24 | } |
25 | |
26 | // Clone |
27 | OsiAuxInfo * |
28 | OsiAuxInfo::clone() const |
29 | { |
30 | return new OsiAuxInfo(*this); |
31 | } |
32 | |
33 | // Copy constructor |
34 | OsiAuxInfo::OsiAuxInfo(const OsiAuxInfo & rhs) |
35 | : |
36 | appData_(rhs.appData_) |
37 | { |
38 | } |
39 | OsiAuxInfo & |
40 | OsiAuxInfo::operator=(const OsiAuxInfo &rhs) |
41 | { |
42 | if (this != &rhs) { |
43 | appData_ = rhs.appData_; |
44 | } |
45 | return *this; |
46 | } |
47 | // Default Constructor |
48 | OsiBabSolver::OsiBabSolver(int solverType) |
49 | :OsiAuxInfo(), |
50 | bestObjectiveValue_(1.0e100), |
51 | mipBound_(-1.0e100), |
52 | solver_(NULL), |
53 | bestSolution_(NULL), |
54 | beforeLower_(NULL), |
55 | beforeUpper_(NULL), |
56 | solverType_(solverType), |
57 | sizeSolution_(0), |
58 | extraCharacteristics_(0) |
59 | { |
60 | } |
61 | |
62 | // Destructor |
63 | OsiBabSolver::~OsiBabSolver () |
64 | { |
65 | delete [] bestSolution_; |
66 | } |
67 | |
68 | // Clone |
69 | OsiAuxInfo * |
70 | OsiBabSolver::clone() const |
71 | { |
72 | return new OsiBabSolver(*this); |
73 | } |
74 | |
75 | // Copy constructor |
76 | OsiBabSolver::OsiBabSolver(const OsiBabSolver & rhs) |
77 | : |
78 | OsiAuxInfo(rhs), |
79 | bestObjectiveValue_(rhs.bestObjectiveValue_), |
80 | mipBound_(rhs.mipBound_), |
81 | solver_(rhs.solver_), |
82 | bestSolution_(NULL), |
83 | beforeLower_(rhs.beforeLower_), |
84 | beforeUpper_(rhs.beforeUpper_), |
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 & |
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 | if (rhs.bestSolution_) { |
110 | assert (solver_); |
111 | bestSolution_ = CoinCopyOfArray(rhs.bestSolution_,sizeSolution_); |
112 | } |
113 | } |
114 | return *this; |
115 | } |
116 | // Returns 1 if solution, 0 if not |
117 | int |
118 | 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 | |
142 | bool |
143 | OsiBabSolver::hasSolution(double & solutionValue, double * solution) |
144 | { |
145 | if (! bestSolution_) |
146 | return false; |
147 | |
148 | int numberColumns = solver_->getNumCols(); |
149 | memcpy(solution,bestSolution_,numberColumns*sizeof(double)); |
150 | solutionValue = bestObjectiveValue_; |
151 | return true; |
152 | } |
153 | |
154 | // set solution |
155 | void |
156 | OsiBabSolver::setSolution(const double * solution, int numberColumns, double objectiveValue) |
157 | { |
158 | assert (solver_); |
159 | // just in case size has changed |
160 | delete [] bestSolution_; |
161 | sizeSolution_ = CoinMin(solver_->getNumCols(),numberColumns); |
162 | bestSolution_ = new double [sizeSolution_]; |
163 | CoinZeroN(bestSolution_,sizeSolution_); |
164 | CoinMemcpyN(solution,CoinMin(sizeSolution_,numberColumns),bestSolution_); |
165 | bestObjectiveValue_ = objectiveValue*solver_->getObjSense(); |
166 | } |
167 | // Get objective (well mip bound) |
168 | double |
169 | OsiBabSolver::mipBound() const |
170 | { |
171 | assert (solver_); |
172 | if (solverType_!=3) |
173 | return solver_->getObjSense()*solver_->getObjValue(); |
174 | else |
175 | return mipBound_; |
176 | } |
177 | // Returns true if node feasible |
178 | bool |
179 | OsiBabSolver::mipFeasible() const |
180 | { |
181 | assert (solver_); |
182 | if (solverType_==0) |
183 | return true; |
184 | else if (solverType_!=3) |
185 | return solver_->isProvenOptimal(); |
186 | else |
187 | return mipBound_<1.0e50; |
188 | } |
189 | |