TL; DR我需要找到所有可能的方式来遍历无向循环,可能断开的图,以找到满足特定条件的所有连接节点集。
有一个节点图,其中为每个节点分配了一个值,并且边表示兼容的节点。
可将兼容节点放到一个集合中,但前提是每个节点都必须与所有其他节点兼容。例如,给定以下图,以邻接表表示:
0: 2, 3
1:
2: 0, 4, 6, 7
3: 0, 4, 6, 7
4: 2, 3, 5, 6
5: 4, 7
6: 2, 3, 4, 6
7: 2, 3, 5, 6
节点{4,5}可以与节点{3,4,6}一起形成一个集合,而节点1只能形成一个元素集。
现在,假设每个节点都有一个值,则找到n个组合值最高的集合。对于上面的示例,如果节点具有以下值:
0: 4
1: 6
2: 4
3: 5
4: 6
5: 3
6: 3
7: 5
n = 2的解决方案是集合{3,4,6}和{2,7},其组合值为23。
我开始的方法是使用DFS的修改版本,在该版本中,堆栈中仅填充了与到目前为止的当前集中所有节点兼容的节点。如果没有这样的节点,我们将创建一个新集合并继续处理尚未访问的节点。
伪代码:
// As long as we have any unvisited nodes
while(visited.contains(false))
{
// Take first unvisited node and push it onto a stack
stack.push(find_first(visited, false));
// Modified DFS
while (!stack.empty())
{
Node n = stack.pop();
// Add the node to the set (this will always be either first or compatible node)
temp_set.add(n);
// Find all compatible nodes by finding intersection of the adjecency list of the nodes
// already in the set
compatibleNodes = find_all_compatible_nodes(set);
// Add the first compatible, unvisited node we find to the stack
for(c : compatibleNodes)
{
if(!visited[c])
{
stack.push(c);
visited[c] = true;
break;
}
}
}
// Once we run out of compatible nodes for this set, we add it to candidate solution and start with a new one
candidateSolution.add(temp_set);
temp_set.clear();
}
// Once we've visited all the nodes, we have a candidate solution where two sets with the highest score are the possible answer
现在这适用于单个可能的解决方案,但是无法探索不同的遍历路径。基本上,它会构建一棵树,其中每个分支代表一个集合,并包含所有图节点。我需要找到所有可以建造的树木,以便找到得分最高的树木。
我想我知道下一步需要做什么。从最后一个解决方案开始,回溯到可以采用替代路径的位置,然后从那里构建一个新的解决方案。然后继续做,直到我返回第一个节点并且没有其他要访问的节点。但是我不能全神贯注于实现。任何帮助表示赞赏。