我试图用n
个顶点枚举所有可能的DAG。我知道有很多这些,我假设n
非常小(3到5)。我想知道是否有办法枚举它们。我的初始解决方案是通过边数m
创建它们。考虑具有0个边的结构,然后考虑具有1个等的结构。 m=0
或m=n(n-1)/2
的案例是很好的研究(分别为1和n!
)。但是,我不清楚有多少DAG存在1<m<n(n-1)/2
个边缘。
更新:由于有些用户认为这是一个广泛的话题,我会尝试将其缩小到生成无向图。因为给定一个带有G
边的无向图m
,所以有2^|m|
方向,并且我已经实现了一种方法来检查确凿性。问题以另一种方式:如何为n
顶点生成所有可能的无向图?
答案 0 :(得分:2)
因为无向图只是一组边,如果我理解你的第二个问题,你就要求生成所有可能的边集的代码。是吗?
void getAllEdgeSets(List<Edge> currentEdges, List<Edge> remainingEdges) {
if (remainingEdges.isEmpty()) {
processSet(currentEdges);
} else {
Edge edge = remainingEdges.remove(0);
getAllEdgeSets(currentEdges, remainingEdges);
currentEdges.add(edge);
getAllEdgeSets(currentEdges, remainingEdges);
currentEdges.remove(edge);
}
}
使用空列表调用此方法:
getAllEdgeSets(Collections.EMPTY_LIST, edges);
您还可以将其转换为流的源,以便您可以随时处理(可能并行):
streamAllGraphs(5).filter(Graph::isAcyclic).forEach(...);
答案 1 :(得分:0)
应该有一个DFS解决方案来解决生成图形的问题,例如:
graph(g) { // g is current graph; start with an empty graph
find set V of vertices in g
if V is not empty
emit g
for every v in V {
find set V' of vertices not in g
for every v' in V' {
g' = g with new edge from v to v'
graph(g')
}
}
}