在 C++ 中将对象从一个向量移动到另一个向量(LEMON 库)

Moving an object from one vector to another in C++ (LEMON library)

我正在尝试使用 LEMON 库,但我 运行 遇到了我正在尝试实施的算法的问题。这个算法的想法是有一个节点向量的向量,我想在一定的限制下将节点移动到不同的向量(颜色 类)。这是实现我的算法的代码:

bool moveColor() {
  // pick the smallest color class
  sort(colors.begin(), colors.end(), vectorSort);
  vector< vector< ListGraph::Node > >::iterator smallestColor = colors.begin();

  // shuffle this class
  random_shuffle(smallestColor->begin(), smallestColor->end());

  // try to move any of the nodes to any bigger class
  bool foundNode = false;
  vector< ListGraph::Node >::iterator movingNode;
  vector< vector< ListGraph::Node > >::iterator destinationClass;
  for (movingNode = smallestColor->begin(); movingNode != smallestColor->end() && !foundNode; ++movingNode) {
    for (destinationClass = colors.begin()+1; destinationClass != colors.end() && !foundNode; ++destinationClass) {
      ListGraph::NodeMap<bool> filter(g, false);
      vector< ListGraph::Node >::iterator classNode;
      for (classNode = destinationClass->begin(); classNode != destinationClass->end(); ++classNode) {
        filter[*classNode] = true;
      }
      filter[*movingNode] = true;
      FilterNodes<ListGraph> subgraph(g, filter);
      if (acyclic(subgraph)) {
        foundNode = true;
      }
    }
  }

  // if a movable node was found, move it. otherwise return false
  if (foundNode) {
    destinationClass->push_back(*movingNode);
    smallestColor->erase(movingNode);
    if (smallestColor->empty()) {
      colors.erase(smallestColor);
    }
    return true;
  }
  return false;
}

这个函数在main中循环调用,直到无法移动节点。我在代码中遇到的主要问题是实际上将节点从一个向量移动到另一个向量的部分:

if (foundNode) {
  destinationClass->push_back(*movingNode);
  smallestColor->erase(movingNode);
  if (smallestColor->empty()) {
    colors.erase(smallestColor);
  }
  return true;
}

这部分似乎不起作用,因为我认为在调用擦除函数时正在解构节点。这是调用此函数之前和之后的节点 ID 示例:

NEW ROUND
1 
3 
0 
5 2 
7 6 4 
NEW ROUND
3 
0 32701 
5 2 
7 6 4 

如您所见,移动的节点的 ID 不正确(32701 而不是 1)。感谢任何帮助。

问题其实在这里:

if (acyclic(subgraph)) {
    foundNode = true;
}

当你定位节点时,你不会break跳出for循环,这使得movingNode迭代器前进到向量中的下一个位置(smallestColor->end()在这种情况)在检查 !foundNode 条件之前。在这种情况下,您必须 break 两次,因为您要从嵌套循环中中断。

可选地,您可以将匹配条件的迭代器存储在单独的变量中以在循环外进行操作(不同于在 for 循环中迭代的迭代器)。

关于您突出显示为潜在问题来源的代码段: destinationClass->push_back(*movingNode);destinationClassNode 的副本放入 movingNode 迭代器指向的副本。也就是说,Node 的复制构造函数被调用。由于 Node 没有用户定义的复制构造函数,编译器会自动生成一个,即所有成员的复制值,因此应该复制 id 值(当然如果正确的迭代器用于 push_back).当然,您要重新定位的节点的原始副本已被 erase 破坏,但这不会影响新副本。