枚举完整图表的完美匹配

时间:2014-05-15 22:14:08

标签: java graph-theory

对于N个节点的完整图表,有( N -1)!!独特的完美搭配。如何在 Java 中实现一个方法来枚举所有唯一匹配?

N 的样本输出= 4

[ (0,1), (2,3) ]   
[ (0,2), (1,3) ]  
[ (0,3), (1,2) ]

N 的样本输出= 6

[ (0,1),(2,3),(4,5) ]
[ (0,1),(2,4),(3,5) ]
[ (0,1),(2,5),(3,4) ]
[ (0,2),(1,3),(4,5) ]
[ (0,2),(1,4),(3,5) ]
[ (0,2),(1,5),(3,4) ]
[ (0,3),(1,2),(4,5) ]
[ (0,3),(1,4),(2,5) ]
[ (0,3),(1,5),(2,4) ]
[ (0,4),(1,2),(3,5) ]
[ (0,4),(1,3),(2,5) ]
[ (0,4),(1,5),(2,3) ]
[ (0,5),(1,2),(3,4) ]
[ (0,5),(1,3),(2,4) ]
[ (0,5),(1,4),(2,3) ]

1 个答案:

答案 0 :(得分:1)

我很快就敲了一个Scala程序来做这个,然后转换成Java。所以它不漂亮。

此处使用地图作为对的列表。

/**
 *
 * @param nodes The nodes still to be added to our edge list.
 * @param edges The current edge list. This is mutated, so always return a clone!
 */
public static <N> List<Map<N,N>> enumerateEdges(List<N> nodes,Map<N,N> edges){
    if(nodes.isEmpty()) // No more nodes to create edges from, so return our current edge list in a new list.
        return Collections.singletonList(new HashMap<>(edges));


    N start = nodes.get(0); //The start node of our next pair.

    List<Map<N,N>> acc = new LinkedList<>(); //The accumulation of the EdgeLists

    for(int i = 1; i<nodes.size(); ++i){

        N end = nodes.get(i); //The end node of our pair
        edges.put(start,end); //Add this pair to our edge list

        List<N> unused = new ArrayList<>(nodes); // The nodes not used in our edge list.
        unused.remove(i);
        unused.remove(0);

        acc.addAll(enumerateEdges(unused,edges));

        edges.remove(start); //Remove this pair from our edge list.
    }

    return acc;
}

可以使用 accumulators / tail recursion / lazyness 完成更多工作以提高性能。但这很有效。

用以下方式调用:

List<Map<Integer,Integer>> results = enumerateEdges(Arrays.asList(0,1,2,3),new HashMap<>());