00001
00002
00003 #if defined(_MSC_VER)
00004
00005 # pragma warning(disable:4786)
00006 #endif
00007 #include <cassert>
00008 #include <cmath>
00009 #include <cfloat>
00010
00011 #include "OsiSolverInterface.hpp"
00012 #include "SbbModel.hpp"
00013 #include "SbbMessage.hpp"
00014 #include "SbbBranchUser.hpp"
00015 #include "CoinSort.hpp"
00016
00017
00018 SbbBranchUserDecision::SbbBranchUserDecision()
00019 :SbbBranchDecision()
00020 {
00021 }
00022
00023
00024 SbbBranchUserDecision::SbbBranchUserDecision (
00025 const SbbBranchUserDecision & rhs)
00026 :SbbBranchDecision(rhs)
00027 {
00028 }
00029
00030 SbbBranchUserDecision::~SbbBranchUserDecision()
00031 {
00032 }
00033
00034
00035 SbbBranchDecision *
00036 SbbBranchUserDecision::clone() const
00037 {
00038 return new SbbBranchUserDecision(*this);
00039 }
00040
00041
00042 void
00043 SbbBranchUserDecision::initialize(SbbModel * model)
00044 {
00045 }
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055 int
00056 SbbBranchUserDecision::betterBranch(SbbBranchingObject * thisOne,
00057 SbbBranchingObject * bestSoFar,
00058 double changeUp, int numberInfeasibilitiesUp,
00059 double changeDown, int numberInfeasibilitiesDown)
00060 {
00061 printf("Now obsolete SbbBranchUserDecision::betterBranch\n");
00062 abort();
00063 return 0;
00064 }
00065
00066
00067
00068
00069
00070
00071
00072 int
00073 SbbBranchUserDecision::bestBranch (SbbBranchingObject ** objects, int numberObjects,
00074 int numberUnsatisfied,
00075 double * changeUp, int * numberInfeasibilitiesUp,
00076 double * changeDown, int * numberInfeasibilitiesDown,
00077 double objectiveValue)
00078 {
00079
00080 int bestWay=0;
00081 int whichObject = -1;
00082 if (numberObjects) {
00083 SbbModel * model = objects[0]->model();
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097 #if 0
00098 int beforeSolution;
00099 int numberSolutions = model->getSolutionCount();
00100 if (numberSolutions) {
00101 int numberHeuristic = model->getNumberHeuristicSolutions();
00102 if (numberHeuristic<numberSolutions)
00103 beforeSolution = -1;
00104 else
00105 beforeSolution = numberHeuristic;
00106 } else {
00107 beforeSolution=0;
00108 }
00109 int bestNumber=INT_MAX;
00110 double bestCriterion=-1.0;
00111 if (!beforeSolution) {
00112
00113
00114 for (int i = 0 ; i < numberObjects ; i++) {
00115 int thisNumber = min(numberInfeasibilitiesUp[i],numberInfeasibilitiesDown[i]);
00116 if (thisNumber<=bestNumber) {
00117 int betterWay=0;
00118 if (numberInfeasibilitiesUp[i]<numberInfeasibilitiesDown[i]) {
00119 if (numberInfeasibilitiesUp[i]<bestNumber) {
00120 betterWay = 1;
00121 } else {
00122 if (changeUp[i]<bestCriterion)
00123 betterWay=1;
00124 }
00125 } else if (numberInfeasibilitiesUp[i]>numberInfeasibilitiesDown[i]) {
00126 if (numberInfeasibilitiesDown[i]<bestNumber) {
00127 betterWay = -1;
00128 } else {
00129 if (changeDown[i]<bestCriterion)
00130 betterWay=-1;
00131 }
00132 } else {
00133
00134 bool better=false;
00135 if (numberInfeasibilitiesUp[i]<bestNumber) {
00136 better=true;
00137 } else if (numberInfeasibilitiesUp[i]==bestNumber) {
00138 if (min(changeUp[i],changeDown[i])<bestCriterion)
00139 better=true;;
00140 }
00141 if (better) {
00142
00143 if (changeUp[i]<=changeDown[i])
00144 betterWay=1;
00145 else
00146 betterWay=-1;
00147 }
00148 }
00149 if (betterWay) {
00150 bestCriterion = min(changeUp[i],changeDown[i]);
00151 bestNumber = thisNumber;
00152 whichObject = i;
00153 bestWay = betterWay;
00154 }
00155 }
00156 }
00157 } else if (beforeSolution>0) {
00158
00159
00160 for (int i = 0 ; i < numberObjects ; i++) {
00161 int betterWay=0;
00162 if (changeUp[i]<=changeDown[i]) {
00163 if (changeUp[i]>bestCriterion)
00164 betterWay=1;
00165 } else {
00166 if (changeDown[i]>bestCriterion)
00167 betterWay=-1;
00168 }
00169 if (betterWay) {
00170 bestCriterion = min(changeUp[i],changeDown[i]);
00171 whichObject = i;
00172 bestWay = betterWay;
00173 }
00174 }
00175 } else {
00176
00177 for (int i = 0 ; i < numberObjects ; i++) {
00178 int betterWay=0;
00179 if (changeUp[i]<=changeDown[i]) {
00180 if (changeUp[i]>bestCriterion)
00181 betterWay=1;
00182 } else {
00183 if (changeDown[i]>bestCriterion)
00184 betterWay=-1;
00185 }
00186 if (betterWay) {
00187 bestCriterion = min(changeUp[i],changeDown[i]);
00188 whichObject = i;
00189 bestWay = betterWay;
00190 }
00191 }
00192 }
00193 #else
00194 int numberSolutions = model->getSolutionCount();
00195 double cutoff = model->getCutoff();
00196 int method=0;
00197 int i;
00198 if (numberSolutions) {
00199 int numberHeuristic = model->getNumberHeuristicSolutions();
00200 if (numberHeuristic<numberSolutions) {
00201 method = 1;
00202 } else {
00203 method = 2;
00204
00205 for ( i = 0 ; i < numberObjects ; i++) {
00206 int numberNext = numberInfeasibilitiesUp[i];
00207
00208 if (numberNext<numberUnsatisfied) {
00209 int numberUp = numberUnsatisfied - numberInfeasibilitiesUp[i];
00210 double perUnsatisfied = changeUp[i]/(double) numberUp;
00211 double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
00212 if (estimatedObjective<cutoff)
00213 method=3;
00214 }
00215 numberNext = numberInfeasibilitiesDown[i];
00216 if (numberNext<numberUnsatisfied) {
00217 int numberDown = numberUnsatisfied - numberInfeasibilitiesDown[i];
00218 double perUnsatisfied = changeDown[i]/(double) numberDown;
00219 double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
00220 if (estimatedObjective<cutoff)
00221 method=3;
00222 }
00223 }
00224 }
00225 method=2;
00226 } else {
00227 method = 0;
00228 }
00229
00230
00231
00232
00233
00234
00235 int bestNumber=INT_MAX;
00236 double bestCriterion=-1.0;
00237 double alternativeCriterion = -1.0;
00238 double bestEstimate = 1.0e100;
00239 switch (method) {
00240 case 0:
00241
00242 for ( i = 0 ; i < numberObjects ; i++) {
00243 int thisNumber = min(numberInfeasibilitiesUp[i],numberInfeasibilitiesDown[i]);
00244 if (thisNumber<=bestNumber) {
00245 int betterWay=0;
00246 if (numberInfeasibilitiesUp[i]<numberInfeasibilitiesDown[i]) {
00247 if (numberInfeasibilitiesUp[i]<bestNumber) {
00248 betterWay = 1;
00249 } else {
00250 if (changeUp[i]<bestCriterion)
00251 betterWay=1;
00252 }
00253 } else if (numberInfeasibilitiesUp[i]>numberInfeasibilitiesDown[i]) {
00254 if (numberInfeasibilitiesDown[i]<bestNumber) {
00255 betterWay = -1;
00256 } else {
00257 if (changeDown[i]<bestCriterion)
00258 betterWay=-1;
00259 }
00260 } else {
00261
00262 bool better=false;
00263 if (numberInfeasibilitiesUp[i]<bestNumber) {
00264 better=true;
00265 } else if (numberInfeasibilitiesUp[i]==bestNumber) {
00266 if (min(changeUp[i],changeDown[i])<bestCriterion)
00267 better=true;;
00268 }
00269 if (better) {
00270
00271 if (changeUp[i]<=changeDown[i])
00272 betterWay=1;
00273 else
00274 betterWay=-1;
00275 }
00276 }
00277 if (betterWay) {
00278 bestCriterion = min(changeUp[i],changeDown[i]);
00279 bestNumber = thisNumber;
00280 whichObject = i;
00281 bestWay = betterWay;
00282 }
00283 }
00284 }
00285 break;
00286 case 1:
00287 for ( i = 0 ; i < numberObjects ; i++) {
00288 int betterWay=0;
00289 if (changeUp[i]<=changeDown[i]) {
00290 if (changeUp[i]>bestCriterion)
00291 betterWay=1;
00292 } else {
00293 if (changeDown[i]>bestCriterion)
00294 betterWay=-1;
00295 }
00296 if (betterWay) {
00297 bestCriterion = min(changeUp[i],changeDown[i]);
00298 whichObject = i;
00299 bestWay = betterWay;
00300 }
00301 }
00302 break;
00303 case 2:
00304 for ( i = 0 ; i < numberObjects ; i++) {
00305 double change = min(changeUp[i],changeDown[i]);
00306 double sum = changeUp[i] + changeDown[i];
00307 bool take=false;
00308 if (change>1.1*bestCriterion)
00309 take=true;
00310 else if (change>0.9*bestCriterion&&sum+change>bestCriterion+alternativeCriterion)
00311 take=true;
00312 if (take) {
00313 if (changeUp[i]<=changeDown[i]) {
00314 if (changeUp[i]>bestCriterion)
00315 bestWay=1;
00316 } else {
00317 if (changeDown[i]>bestCriterion)
00318 bestWay=-1;
00319 }
00320 bestCriterion = change;
00321 alternativeCriterion = sum;
00322 whichObject = i;
00323 }
00324 }
00325 break;
00326 case 3:
00327 for ( i = 0 ; i < numberObjects ; i++) {
00328 int numberNext = numberInfeasibilitiesUp[i];
00329
00330 if (numberNext<numberUnsatisfied) {
00331 int numberUp = numberUnsatisfied - numberInfeasibilitiesUp[i];
00332 double perUnsatisfied = changeUp[i]/(double) numberUp;
00333 double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
00334 if (estimatedObjective<bestEstimate) {
00335 bestEstimate = estimatedObjective;
00336 bestWay=1;
00337 whichObject=i;
00338 }
00339 }
00340 numberNext = numberInfeasibilitiesDown[i];
00341 if (numberNext<numberUnsatisfied) {
00342 int numberDown = numberUnsatisfied - numberInfeasibilitiesDown[i];
00343 double perUnsatisfied = changeDown[i]/(double) numberDown;
00344 double estimatedObjective = objectiveValue + numberUnsatisfied * perUnsatisfied;
00345 if (estimatedObjective<bestEstimate) {
00346 bestEstimate = estimatedObjective;
00347 bestWay=-1;
00348 whichObject=i;
00349 }
00350 }
00351 }
00352 break;
00353 }
00354 #endif
00355
00356 objects[whichObject]->way(bestWay);
00357 }
00358 return whichObject;
00359 }