I am trying to use the LEMON library and I am running into an issue with an algorithm that I am trying to implement. The idea of this algorithm is that there is a vector of vectors of nodes and I want to move the nodes around to different vectors (color classes) with certain restrictions. Here is the code that implements my algorithm:
我正在尝试使用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;
}
This function is called in main in a loop until a node was unable to be moved. The main issue I am having with the code is the section that actually moves a node from one vector to another:
main函数在循环中调用此函数,直到无法移动节点。我对代码的主要问题是实际将节点从一个向量移动到另一个向量的部分:
if (foundNode) {
destinationClass->push_back(*movingNode);
smallestColor->erase(movingNode);
if (smallestColor->empty()) {
colors.erase(smallestColor);
}
return true;
}
This part doesn't seem to work because I think the node is being deconstructed when the erase function is being called. Here is a sample of the node ids before and after this function was called:
这部分似乎不起作用,因为我认为在调用擦除函数时节点正在被解构。以下是调用此函数之前和之后的节点ID示例:
NEW ROUND
1
3
0
5 2
7 6 4
NEW ROUND
3
0 32701
5 2
7 6 4
As you can see, the id for the node that was moved is not correct (32701 instead of 1). Any help is appreciated.
如您所见,移动的节点的ID不正确(32701而不是1)。任何帮助表示赞赏。
1 个解决方案
#1
0
The issue is actually here:
问题实际上在这里:
if (acyclic(subgraph)) {
foundNode = true;
}
When you locate the node, you don't break
out of for
loop, which makes movingNode
iterator advance to next position in vector (smallestColor->end()
in this case) before checking for !foundNode
condition. In this case you have to break
twice, as you are breaking from nested loop.
找到节点时,不会中断for循环,这会使moveNode迭代器在检查!foundNode条件之前前进到向量中的下一个位置(本例中为smallestColor-> end())。在这种情况下,你必须打破两次,因为你打破了嵌套循环。
Optionally, you can store iterator that match criteria in separate variable to operate on outside the loop (different that one iterating over in for loop).
(可选)您可以存储与单独变量中的条件匹配的迭代器,以在循环外部进行操作(不同于迭代循环的循环)。
About the snippet you highlighted as potential source of issue: destinationClass->push_back(*movingNode);
is putting into destinationClass
a copy of Node
that movingNode
iterator points to. That mean, copy constructor of Node
is called. As Node
has no user-defined copy constructor, compiler auto-generates one, that copy value of all members, so id
value should be copied (of course if correct iterator is used for push_back
). Of course original copy of node you are relocating is destructed with erase
, but this does not affect new copy.
关于您突出显示为潜在问题来源的代码段:destinationClass-> push_back(* movingNode);正在向destinationClass输入movingNode迭代器指向的Node的副本。这意味着,调用Node的复制构造函数。由于Node没有用户定义的复制构造函数,编译器会自动生成一个复制所有成员的值,因此应复制id值(当然,如果正确的迭代器用于push_back)。当然,您要重新定位的节点的原始副本会被擦除破坏,但这不会影响新副本。
#1
0
The issue is actually here:
问题实际上在这里:
if (acyclic(subgraph)) {
foundNode = true;
}
When you locate the node, you don't break
out of for
loop, which makes movingNode
iterator advance to next position in vector (smallestColor->end()
in this case) before checking for !foundNode
condition. In this case you have to break
twice, as you are breaking from nested loop.
找到节点时,不会中断for循环,这会使moveNode迭代器在检查!foundNode条件之前前进到向量中的下一个位置(本例中为smallestColor-> end())。在这种情况下,你必须打破两次,因为你打破了嵌套循环。
Optionally, you can store iterator that match criteria in separate variable to operate on outside the loop (different that one iterating over in for loop).
(可选)您可以存储与单独变量中的条件匹配的迭代器,以在循环外部进行操作(不同于迭代循环的循环)。
About the snippet you highlighted as potential source of issue: destinationClass->push_back(*movingNode);
is putting into destinationClass
a copy of Node
that movingNode
iterator points to. That mean, copy constructor of Node
is called. As Node
has no user-defined copy constructor, compiler auto-generates one, that copy value of all members, so id
value should be copied (of course if correct iterator is used for push_back
). Of course original copy of node you are relocating is destructed with erase
, but this does not affect new copy.
关于您突出显示为潜在问题来源的代码段:destinationClass-> push_back(* movingNode);正在向destinationClass输入movingNode迭代器指向的Node的副本。这意味着,调用Node的复制构造函数。由于Node没有用户定义的复制构造函数,编译器会自动生成一个复制所有成员的值,因此应复制id值(当然,如果正确的迭代器用于push_back)。当然,您要重新定位的节点的原始副本会被擦除破坏,但这不会影响新副本。