CbcCompareBase.hpp 3.79 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155
/* $Id$ */
// Copyright (C) 2002, International Business Machines
// Corporation and others.  All Rights Reserved.
// This code is licensed under the terms of the Eclipse Public License (EPL).

#ifndef CbcCompareBase_H
#define CbcCompareBase_H

//#############################################################################
/*  These are alternative strategies for node traversal.
    They can take data etc for fine tuning

    At present the node list is stored as a heap and the "test"
    comparison function returns true if node y is better than node x.

    This is rather inflexible so if the comparison functions wants
    it can signal to use alternative criterion on a complete pass
    throgh tree.

*/
#include "CbcNode.hpp"
#include "CbcConfig.h"

class CbcModel;
class CbcTree;
class CbcCompareBase {
public:
  // Default Constructor
  CbcCompareBase()
  {
    test_ = NULL;
    threaded_ = false;
  }

  /*! \brief Reconsider behaviour after discovering a new solution.
    
      This allows any method to change its behaviour. It is called
      after each solution.

      The method should return true if changes are made which will
      alter the evaluation criteria applied to a node. (So that in
      cases where the search tree is sorted, it can be properly
      rebuilt.)
    */
  virtual bool newSolution(CbcModel *) { return (false); }

  /*! \brief Reconsider behaviour after discovering a new solution.
    
      This allows any method to change its behaviour. It is called
      after each solution.

      The method should return true if changes are made which will
      alter the evaluation criteria applied to a node. (So that in
      cases where the search tree is sorted, it can be properly
      rebuilt.)
    */
  virtual bool newSolution(CbcModel *,
    double,
    int) { return (false); }

  // This allows any method to change behavior as it is called
  // after every 1000 nodes.
  // Return true if want tree re-sorted
  virtual bool every1000Nodes(CbcModel *, int)
  {
    return false;
  }

  /** Returns true if wants code to do scan with alternate criterion
        NOTE - this is temporarily disabled
    */
  virtual bool fullScan() const
  {
    return false;
  }

  virtual ~CbcCompareBase() {}
  /// Create C++ lines to get to current state
  virtual void generateCpp(FILE *) {}

  // Copy constructor
  CbcCompareBase(const CbcCompareBase &rhs)
  {
    test_ = rhs.test_;
    threaded_ = rhs.threaded_;
  }

  // Assignment operator
  CbcCompareBase &operator=(const CbcCompareBase &rhs)
  {
    if (this != &rhs) {
      test_ = rhs.test_;
      threaded_ = rhs.threaded_;
    }
    return *this;
  }

  /// Clone
  virtual CbcCompareBase *clone() const
  {
    abort();
    return NULL;
  }

  /// This is test function
  virtual bool test(CbcNode *, CbcNode *)
  {
    return true;
  }

  /// This is alternate test function
  virtual bool alternateTest(CbcNode *x, CbcNode *y)
  {
    return test(x, y);
  }

  bool operator()(CbcNode *x, CbcNode *y)
  {
    return test(x, y);
  }
  /// Further test if everything else equal
  inline bool equalityTest(CbcNode *x, CbcNode *y) const
  {
    assert(x);
    assert(y);
    if (!threaded_) {
      CbcNodeInfo *infoX = x->nodeInfo();
      assert(infoX);
      int nodeNumberX = infoX->nodeNumber();
      CbcNodeInfo *infoY = y->nodeInfo();
      assert(infoY);
      int nodeNumberY = infoY->nodeNumber();
      assert(nodeNumberX != nodeNumberY);
      return (nodeNumberX > nodeNumberY);
    } else {
      assert(x->nodeNumber() != y->nodeNumber());
      return (x->nodeNumber() > y->nodeNumber());
    }
  }
  /// Say threaded
  inline void sayThreaded()
  {
    threaded_ = true;
  }

protected:
  CbcCompareBase *test_;
  // If not threaded we can use better way to break ties
  bool threaded_;
};

#endif

/* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
*/