Visual c++ 为什么没有';NodeCallback中没有NodeID

Visual c++ 为什么没有';NodeCallback中没有NodeID,visual-c++,cplex,Visual C++,Cplex,我从BranchCallback获得了NodeID(getNodeID)和父级,并从NodeCallback获得了变量branch。当我绘制树搜索算法时,一些节点在这些节点之前没有任何变量分支,当我看到VS C++的控制台没有这些NoIDID的任何记录。但是我确信BranchCallback中有很多信息,比如这些节点的目标值。为什么呢?请注意(正如我在另一篇文章中解释的那样),控制台日志中显示的NodeID与回调中获得的NodeID不同。所以这两件事是不相关的 那么,对于你要问的其他问题,不清楚

我从BranchCallback获得了NodeID(getNodeID)和父级,并从NodeCallback获得了变量branch。当我绘制树搜索算法时,一些节点在这些节点之前没有任何变量分支,当我看到VS C++的控制台没有这些NoIDID的任何记录。但是我确信BranchCallback中有很多信息,比如这些节点的目标值。为什么呢?

请注意(正如我在另一篇文章中解释的那样),控制台日志中显示的NodeID与回调中获得的NodeID不同。所以这两件事是不相关的

那么,对于你要问的其他问题,不清楚你是如何获得任何数据的。特别是,如果您在分支回调中收集节点,然后直到稍后才在节点回调中使用分支变量,那么这可能不适用于被修剪的节点。为什么不从分支回调中获取分支变量呢? 下面是一个简单的示例:

#include <map>
#include <limits>
#include <iostream>
#include <ilcplex/ilocplex.h>
#include <ilconcert/ilothread.h>

using std::cout;
using std::endl;

/** The info we collect for a node. */
struct Info {
   IloCplex::MIPCallbackI::NodeId id;        /**< The node's id. */
   IloCplex::MIPCallbackI::NodeId parent;    /**< ID of the parent (root is 0). */
   IloNumVar                      branchVar; /**< The variable on which CPLEX branched
                                              * to create this node. */
   IloNum                         branchVal; /**< The value CPLEX used for branching. */
   IloCplex::BranchDirection      branchDir; /**< The direction into which CPLEX branched. */
};

// Overload operator< so that we can use NodeIds as keys in maps.
bool operator<(IloCplex::MIPCallbackI::NodeId const &n1,
               IloCplex::MIPCallbackI::NodeId const &n2)
{
   return n1._id < n2._id;
}

// Map node ids to Info objects so that you can easily get from the info
// for a child to the info of its parent.
IloFastMutex lck;
typedef std::map<IloCplex::MIPCallbackI::NodeId,Info> MapType;
MapType nodeMap;

// A simple branch callback that tracks CPLEX branching decisions.
ILOBRANCHCALLBACK0(BranchCallback) {
   IloInt const n = getNbranches();
   IloCplex::MIPCallbackI::NodeId me = getNodeId();
   IloNumVarArray x(getEnv());
   IloNumArray bounds(getEnv());
   IloCplex::BranchDirectionArray dirs(getEnv());
   for (IloInt b = 0; b < n; ++b) {
      // Get what CPLEX plans to do and perform the exact same branch.
      // Then record all the information abouth the newly created branch.
      getBranch(x, bounds, dirs, b);
      Info info;
      info.id = makeBranch(b);
      info.parent = me;
      if ( x.getSize() == 1 ) {
         info.branchVar = x[0];
         info.branchVal = bounds[0];
         info.branchDir = dirs[0];
      }
      else {
         // CPLEX branches on more than one variable. We don't record that.
         info.branchVar = 0;
         info.branchVal = std::numeric_limits<double>::quiet_NaN();
         info.branchDir = IloCplex::BranchGlobal;
      }
      lck.lock();
      nodeMap.insert(MapType::value_type(info.id, info));
      lck.unlock();
   }
   dirs.end();
   bounds.end();
   x.end();
}

int
main(int argc, char **argv) {
   for (int a = 1; a < argc; ++a) {
      IloEnv env;
      IloModel model(env);
      IloCplex cplex(model);
      cplex.importModel(model, argv[a]);
      cplex.use(BranchCallback(env));
      nodeMap.clear();
      cplex.setParam(IloCplex::Threads, cplex.getNumCores());
      //cplex.setParam(IloCplex::Threads, 1);
      //cplex.setParam(IloCplex::NodeLim, 10);
      cplex.solve();

      // Print information about all the nodes.
      for (MapType::const_iterator it = nodeMap.begin(); it != nodeMap.end(); ++it) {
         Info const &i = it->second;
         cout << "Node " << i.id << " created from " << i.parent
              << " by branching "
              << (i.branchDir == IloCplex::BranchUp ? "up" : "down")
              << " on " << (i.branchVar.getImpl() ? i.branchVar.getName() : "more than one variable")
              << " with value " << i.branchVal
              << endl;
      }
      env.end();
   }
   return 0;
}
转到
Info
类并使用如下节点回调:

// A simple node callback that tracks the order in which nodes are selected.
ILONODECALLBACK0(NodeCallback) {
   // The order that CPLEX plans to execute next is at index 0.
   IloCplex::MIPCallbackI::NodeId next = getNodeId(0);
   lck.lock();
   static IloInt order = 0;
   nodeMap[next].order = order++;
   lck.unlock();
}
(您可以使用时间戳或其他东西来代替简单的计数器)。

请注意(正如我在另一篇文章中解释的那样),控制台日志中显示的NodeID与回调中获得的NodeID不同。所以这两件事是不相关的

那么,对于你要问的其他问题,不清楚你是如何获得任何数据的。特别是,如果您在分支回调中收集节点,然后直到稍后才在节点回调中使用分支变量,那么这可能不适用于被修剪的节点。为什么不从分支回调中获取分支变量呢? 下面是一个简单的示例:

#include <map>
#include <limits>
#include <iostream>
#include <ilcplex/ilocplex.h>
#include <ilconcert/ilothread.h>

using std::cout;
using std::endl;

/** The info we collect for a node. */
struct Info {
   IloCplex::MIPCallbackI::NodeId id;        /**< The node's id. */
   IloCplex::MIPCallbackI::NodeId parent;    /**< ID of the parent (root is 0). */
   IloNumVar                      branchVar; /**< The variable on which CPLEX branched
                                              * to create this node. */
   IloNum                         branchVal; /**< The value CPLEX used for branching. */
   IloCplex::BranchDirection      branchDir; /**< The direction into which CPLEX branched. */
};

// Overload operator< so that we can use NodeIds as keys in maps.
bool operator<(IloCplex::MIPCallbackI::NodeId const &n1,
               IloCplex::MIPCallbackI::NodeId const &n2)
{
   return n1._id < n2._id;
}

// Map node ids to Info objects so that you can easily get from the info
// for a child to the info of its parent.
IloFastMutex lck;
typedef std::map<IloCplex::MIPCallbackI::NodeId,Info> MapType;
MapType nodeMap;

// A simple branch callback that tracks CPLEX branching decisions.
ILOBRANCHCALLBACK0(BranchCallback) {
   IloInt const n = getNbranches();
   IloCplex::MIPCallbackI::NodeId me = getNodeId();
   IloNumVarArray x(getEnv());
   IloNumArray bounds(getEnv());
   IloCplex::BranchDirectionArray dirs(getEnv());
   for (IloInt b = 0; b < n; ++b) {
      // Get what CPLEX plans to do and perform the exact same branch.
      // Then record all the information abouth the newly created branch.
      getBranch(x, bounds, dirs, b);
      Info info;
      info.id = makeBranch(b);
      info.parent = me;
      if ( x.getSize() == 1 ) {
         info.branchVar = x[0];
         info.branchVal = bounds[0];
         info.branchDir = dirs[0];
      }
      else {
         // CPLEX branches on more than one variable. We don't record that.
         info.branchVar = 0;
         info.branchVal = std::numeric_limits<double>::quiet_NaN();
         info.branchDir = IloCplex::BranchGlobal;
      }
      lck.lock();
      nodeMap.insert(MapType::value_type(info.id, info));
      lck.unlock();
   }
   dirs.end();
   bounds.end();
   x.end();
}

int
main(int argc, char **argv) {
   for (int a = 1; a < argc; ++a) {
      IloEnv env;
      IloModel model(env);
      IloCplex cplex(model);
      cplex.importModel(model, argv[a]);
      cplex.use(BranchCallback(env));
      nodeMap.clear();
      cplex.setParam(IloCplex::Threads, cplex.getNumCores());
      //cplex.setParam(IloCplex::Threads, 1);
      //cplex.setParam(IloCplex::NodeLim, 10);
      cplex.solve();

      // Print information about all the nodes.
      for (MapType::const_iterator it = nodeMap.begin(); it != nodeMap.end(); ++it) {
         Info const &i = it->second;
         cout << "Node " << i.id << " created from " << i.parent
              << " by branching "
              << (i.branchDir == IloCplex::BranchUp ? "up" : "down")
              << " on " << (i.branchVar.getImpl() ? i.branchVar.getName() : "more than one variable")
              << " with value " << i.branchVal
              << endl;
      }
      env.end();
   }
   return 0;
}
转到
Info
类并使用如下节点回调:

// A simple node callback that tracks the order in which nodes are selected.
ILONODECALLBACK0(NodeCallback) {
   // The order that CPLEX plans to execute next is at index 0.
   IloCplex::MIPCallbackI::NodeId next = getNodeId(0);
   lck.lock();
   static IloInt order = 0;
   nodeMap[next].order = order++;
   lck.unlock();
}

(您可以使用时间戳或其他东西,而不是简单的计数器)。

不清楚您在问什么,以及如何获得所拥有的信息。你能展示你代码的所有相关部分吗?你是如何准确地获得你所拥有的所有信息的,以及你是如何将不同的信息联系起来的。目前还不清楚你在问什么以及你是如何获得你所拥有的信息的。你能展示你代码的所有相关部分吗?您如何准确地获取所有信息,以及如何将不同的信息联系起来。