source: trunk/Cbc/examples/CbcCompareUser.cpp

Last change on this file was 1898, checked in by stefan, 6 years ago

fixup examples

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.3 KB
Line 
1// $Id: CbcCompareUser.cpp 1898 2013-04-09 18:06:04Z tkr $
2// Copyright (C) 2004, International Business Machines
3// Corporation and others.  All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6#include <cassert>
7#include <cmath>
8#include <cfloat>
9//#define CBC_DEBUG
10
11#include "CoinPragma.hpp"
12#include "CbcMessage.hpp"
13#include "CbcModel.hpp"
14#include "CbcTree.hpp"
15#include "CbcCompareUser.hpp"
16#include "CoinError.hpp"
17#include "CoinHelperFunctions.hpp"
18
19/** Default Constructor
20
21*/
22CbcCompareUser::CbcCompareUser ()
23  : CbcCompareBase(),
24    weight_(-1.0),
25    saveWeight_(0.0),
26    numberSolutions_(0),
27    count_(0),
28    treeSize_(0)
29{
30  test_=this;
31}
32
33// Constructor with weight
34CbcCompareUser::CbcCompareUser (double weight) 
35  : CbcCompareBase(),
36    weight_(weight) ,
37    saveWeight_(0.0),
38    numberSolutions_(0),
39    count_(0),
40    treeSize_(0)
41{
42  test_=this;
43}
44
45
46// Copy constructor
47CbcCompareUser::CbcCompareUser ( const CbcCompareUser & rhs)
48  :CbcCompareBase(rhs)
49
50{
51  weight_=rhs.weight_;
52  saveWeight_ = rhs.saveWeight_;
53  numberSolutions_=rhs.numberSolutions_;
54  count_ = rhs.count_;
55  treeSize_ = rhs.treeSize_;
56}
57
58// Clone
59CbcCompareBase *
60CbcCompareUser::clone() const
61{
62  return new CbcCompareUser(*this);
63}
64
65// Assignment operator
66CbcCompareUser & 
67CbcCompareUser::operator=( const CbcCompareUser& rhs)
68{
69  if (this!=&rhs) {
70    CbcCompareBase::operator=(rhs);
71    weight_=rhs.weight_;
72    saveWeight_ = rhs.saveWeight_;
73    numberSolutions_=rhs.numberSolutions_;
74    count_ = rhs.count_;
75    treeSize_ = rhs.treeSize_;
76  }
77  return *this;
78}
79
80// Destructor
81CbcCompareUser::~CbcCompareUser ()
82{
83}
84// For moment go to default
85#if 0
86// Returns true if y better than x
87bool
88CbcCompareUser::test (CbcNode * x, CbcNode * y)
89{
90  if (x) {
91    if (y) {
92      if (weight_==-1.0) {
93        // before solution
94        /* printf("x %d %d %g, y %d %d %g\n",
95           x->numberUnsatisfied(),x->depth(),x->objectiveValue(),
96           y->numberUnsatisfied(),y->depth(),y->objectiveValue()); */
97        if (x->numberUnsatisfied() > y->numberUnsatisfied())
98          return true;
99        else if (x->numberUnsatisfied() < y->numberUnsatisfied())
100          return false;
101        else
102          return x->depth() < y->depth();
103      } else {
104        // after solution
105        double weight = CoinMax(weight_,0.0);
106        return x->objectiveValue()+ weight*x->numberUnsatisfied() >
107          y->objectiveValue() + weight*y->numberUnsatisfied();
108        //return x->guessedObjectiveValue()>y->guessedObjectiveValue();
109      }
110    } else {
111      return false;
112    }
113  } else {
114    return true;
115  }
116}
117// This allows method to change behavior as it is called
118// after each solution
119void
120CbcCompareUser::newSolution(CbcModel * model,
121                               double objectiveAtContinuous,
122                               int numberInfeasibilitiesAtContinuous)
123{
124  // set to get close to this solution
125  double costPerInteger =
126    (model->getObjValue()-objectiveAtContinuous)/
127    ((double) numberInfeasibilitiesAtContinuous);
128  weight_ = 0.95*costPerInteger;
129  saveWeight_=weight_;
130  if (model->getSolutionCount()==model->getNumberHeuristicSolutions())
131    return; // solution was got by rounding
132  numberSolutions_++;
133  if (numberSolutions_>5)
134    weight_ =0.0; // this searches on objective
135  return (true) ;
136}
137// This allows method to change behavior
138bool
139CbcCompareUser::every1000Nodes(CbcModel * model, int numberNodes)
140{
141  if (numberNodes>10000)
142    weight_ =0.0; // this searches on objective
143  else if (numberNodes==1000&&weight_==-2.0)
144    weight_=-1.0; // Go to depth first
145  // get size of tree
146  treeSize_ = model->tree()->size();
147  if (treeSize_>10000) {
148    // set weight to reduce size most of time
149    if (treeSize_>20000)
150      weight_=-1.0;
151    else if ((numberNodes%4000)!=0)
152      weight_=-1.0;
153    else
154      weight_=saveWeight_;
155  }
156  return numberNodes==11000; // resort if first time
157}
158// Returns true if wants code to do scan with alternate criterion
159bool
160CbcCompareUser::fullScan() const
161{
162  count_++;
163  if (weight_)
164    return (count_%10)==0;
165  else
166    return false;
167}
168// This is alternate test function
169bool
170CbcCompareUser::alternateTest (CbcNode * x, CbcNode * y)
171{
172  if (x) {
173    if (y) {
174      return x->objectiveValue() >
175        y->objectiveValue() ;
176    } else {
177      return false;
178    }
179  } else {
180    return true;
181  }
182}
183#else
184
185// Returns true if y better than x
186bool
187CbcCompareUser::test (CbcNode * x, CbcNode * y)
188{
189  if (weight_==-1.0&&(y->depth()>7||x->depth()>7)) {
190    // before solution
191    /* printf("x %d %d %g, y %d %d %g\n",
192       x->numberUnsatisfied(),x->depth(),x->objectiveValue(),
193       y->numberUnsatisfied(),y->depth(),y->objectiveValue()); */
194    if (x->numberUnsatisfied() > y->numberUnsatisfied()) {
195      return true;
196    } else if (x->numberUnsatisfied() < y->numberUnsatisfied()) {
197      return false;
198    } else {
199      int testX = x->depth();
200      int testY = y->depth();
201      if (testX!=testY)
202        return testX < testY;
203      else
204        return equalityTest(x,y); // so ties will be broken in consistent manner
205    }
206  } else {
207    // after solution
208    double weight = CoinMax(weight_,0.0);
209    double testX =  x->objectiveValue()+ weight*x->numberUnsatisfied();
210    double testY = y->objectiveValue() + weight*y->numberUnsatisfied();
211    if (testX!=testY)
212      return testX > testY;
213    else
214      return equalityTest(x,y); // so ties will be broken in consistent manner
215  }
216}
217// This allows method to change behavior as it is called
218// after each solution
219bool
220CbcCompareUser::newSolution(CbcModel * model,
221                               double objectiveAtContinuous,
222                               int numberInfeasibilitiesAtContinuous)
223{
224  if (model->getSolutionCount()==model->getNumberHeuristicSolutions()&&
225      model->getSolutionCount()<5&&model->getNodeCount()<500)
226    return (false) ; // solution was got by rounding
227  // set to get close to this solution
228  double costPerInteger =
229    (model->getObjValue()-objectiveAtContinuous)/
230    ((double) numberInfeasibilitiesAtContinuous);
231  weight_ = 0.95*costPerInteger;
232  saveWeight_ = 0.95*weight_;
233  numberSolutions_++;
234  if (numberSolutions_>5)
235    weight_ =0.0; // this searches on objective
236  return (true) ;
237}
238// This allows method to change behavior
239bool
240CbcCompareUser::every1000Nodes(CbcModel * model, int numberNodes)
241{
242  double saveWeight=weight_;
243  int numberNodes1000 = numberNodes/1000;
244  if (numberNodes>10000) {
245    weight_ =0.0; // this searches on objective
246    // but try a bit of other stuff
247    if ((numberNodes1000%4)==1)
248      weight_=saveWeight_;
249  } else if (numberNodes==1000&&weight_==-2.0) {
250    weight_=-1.0; // Go to depth first
251  }
252  // get size of tree
253  treeSize_ = model->tree()->size();
254  if (treeSize_>10000) {
255    int n1 = model->solver()->getNumRows()+model->solver()->getNumCols();
256    int n2 = model->numberObjects();
257    double size = n1*0.1 + n2*2.0;
258    // set weight to reduce size most of time
259    if (treeSize_*size>5.0e7)
260      weight_=-1.0;
261    else if ((numberNodes1000%4)==0&&treeSize_*size>1.0e6)
262      weight_=-1.0;
263    else if ((numberNodes1000%4)==1)
264      weight_=0.0;
265    else
266      weight_=saveWeight_;
267  }
268  return (weight_!=saveWeight);
269}
270// Returns true if wants code to do scan with alternate criterion
271bool
272CbcCompareUser::fullScan() const
273{
274  return false;
275}
276// This is alternate test function
277bool
278CbcCompareUser::alternateTest (CbcNode * x, CbcNode * y)
279{
280  // not used
281  abort();
282  return false;
283}
284#endif
Note: See TracBrowser for help on using the repository browser.