source: branches/Couenne/Couenne/src/branch/CouenneThreeWayBranchObj.cpp @ 557

Last change on this file since 557 was 557, checked in by pbelotti, 12 years ago

use a more elaborate structure to check changed bounds. Check bounds of other variables after applying OBBT for one. Remove exit from exprSub::impliedBound. Return changed bounds in exprPow. Added explicit handling of whichWay in CouenneObject?. Added branching rule for expr{Inv,Log} and exprMul (infinite bounds).

File size: 3.8 KB
Line 
1/*
2 * Name:    CouenneThreeWayBranchObj.cpp
3 * Authors: Pietro Belotti, Carnegie Mellon University
4 * Purpose: Branching object for auxiliary variables
5 *
6 * (C) Pietro Belotti. This file is licensed under the Common Public License (CPL)
7 */
8
9#include <CoinHelperFunctions.hpp>
10#include <CouenneObject.hpp>
11#include <CouenneBranchingObject.hpp>
12#include <CouenneThreeWayBranchObj.hpp>
13
14
15/** \brief Constructor. Get a variable as an argument and set value_
16           through a call to operator () of that exprAux.
17*/
18
19CouenneThreeWayBranchObj::CouenneThreeWayBranchObj (int index, 
20                                                    CouNumber lcrop, 
21                                                    CouNumber rcrop,
22                                                    int way,
23                                                    bool isint): 
24  index_   (index),
25  lcrop_   (lcrop),
26  rcrop_   (rcrop),
27  integer_ (isint) {
28
29  numberBranches_ = 3;
30
31  // if none of these three, set to 0 and do code below
32  firstBranch_ = (way == THREE_LEFT)   ? 0 : 
33                 (way == THREE_CENTER) ? 1 : 
34                 (way == THREE_RIGHT)  ? 2 : 0; 
35 
36  if (way == THREE_RAND) { // pick first branch randomly
37    CouNumber rnd = 3. * CoinDrand48 ();
38    firstBranch_ = (rnd < 1.) ? 0 : (rnd < 2.) ? 1: 2;
39  }
40
41  // Depending on where x, l, and u are, divide bound interval into
42  // three and set lcrop_ and rcrop_ accordingly.
43
44  // if l and u are unbounded, crop around x using COUENNE_CROP
45  /*
46  if ((x-l > COUENNE_LARGE_INTERVAL) &&
47      (u-x > COUENNE_LARGE_INTERVAL)) {
48    lcrop_ = x - COUENNE_CROP;
49    rcrop_ = x + COUENNE_CROP;
50    first_ = 1;
51  }
52  else
53    if ((x-l > COUENNE_LARGE_INTERVAL) &&
54        (u-x < COUENNE_NEAR_BOUND)) {
55      lcrop_ = x - COUENNE_CROP;
56      rcrop_ = x - COUENNE_LCROP;
57      first_ = 2;
58    }
59    else
60      if ((x-l < COUENNE_NEAR_BOUND) &&
61          (u-x > COUENNE_LARGE_INTERVAL)) {
62        lcrop_ = x + COUENNE_CROP;
63        rcrop_ = x + COUENNE_LCROP;
64        first_ = 0;
65        }*/
66
67  if (0) {
68    printf ("=3= x%d branches on %g and %g (at %g) [%g,%g]\n", 
69            index_,
70            lcrop_,
71            rcrop_,
72            expression::Variable (index_),
73            expression::Lbound   (index_),
74            expression::Ubound   (index_));
75  }
76}
77
78
79/** \brief Execute the actions required to branch, as specified by the
80           current state of the branching object, and advance the
81           object's state.
82           Returns change in guessed objective on next branch
83*/
84
85double CouenneThreeWayBranchObj::branch (OsiSolverInterface * solver) {
86
87  //       -1 if "<= a"  node
88  // way =  0 if "[a,b]" node
89  //        1 if ">= b"  node
90
91  int way;
92
93  switch (branchIndex_) {
94    // if first offspring, let firstBranch_ decide who's first
95  case 0: way = firstBranch_;                break;
96  case 1: way = (firstBranch_ == 0) ? 1 : 0; break;
97  case 2: way = (firstBranch_ == 2) ? 1 : 2; break;
98  default: printf ("Warning, branchIndex_ has a strange value (%d)\n", branchIndex_);
99  }
100
101  // set lower or upper bound (round if this variable is integer)
102
103  switch (--way) { // from {0,1,2} to {-1,0,1}
104
105  case -1: solver -> setColUpper (index_, integer_ ? floor (lcrop_) : lcrop_); break; // left
106  case  0: solver -> setColLower (index_, integer_ ? ceil  (lcrop_) : lcrop_);
107           solver -> setColUpper (index_, integer_ ? floor (rcrop_) : rcrop_); break; // central
108  case  1: solver -> setColLower (index_, integer_ ? ceil  (rcrop_) : rcrop_); break; // right
109  default: printf ("Couenne: branching on nonsense way %d\n", way);
110  }
111
112  // TODO: apply bound tightening
113
114  if (0) {
115    switch (way) {
116    case -1: printf ("#3# Branch: x%d <= %g\n",               index_, lcrop_); break; // left
117    case  0: printf ("#3# Branch: %g <= x%d <= %g\n", lcrop_, index_, rcrop_); break; // center
118    case  1: printf ("#3# Branch: x%d >= %g\n",               index_, rcrop_); break; // right
119    default: printf ("Couenne: branching on nonsense way %d\n", way);
120    }
121  }
122
123  branchIndex_++;
124
125  return 0.; // estimated change in objective function
126}
Note: See TracBrowser for help on using the repository browser.