【发布时间】:2017-11-14 02:06:06
【问题描述】:
我的目标是生成一个有 n 个顶点的有向图,这样每个顶点都有一条出边和一条进边。我认为这样做的一种方法是将所有顶点放在一个罐子中,然后为顶点轮流洗牌并拉出条目 - 例如,如果顶点 1 拉出顶点 3,那么这意味着将有一条从 1 到 3 的边。如果一个顶点将自己拉出底池,它只会把它放回去并改组。如果最后,最后一个顶点发现锅只包含自己,那么我们需要重新开始。这是我的 Kotlin 代码:
fun generateGraph(n: Int): Map<Int, Int> {
val vertices : List<Int> = (1..n).toList()
while (true) {
val pot = vertices.toMutableList()
val result = mutableMapOf<Int, Int>()
for (vertex in 1 until n) {
do {
java.util.Collections.shuffle(pot)
} while (pot[0] == vertex)
result.put(vertex, pot.removeAt(0))
}
if (pot[0] != n) {
result.put(n, pot.removeAt(0))
return result
}
else {
// The last vertex left in the pot is also the last one unassigned. Try again...
}
}
}
它似乎工作。但是,在测试时,我发现它的一些图表比其他图表更多。当 n 为 3 时,唯一有效的图是循环
{1=3, 2=1, 3=2}
{1=2, 2=3, 3=1}
但我发现第一个出现的次数是第二个的两倍:
fun main(args: Array<String>) {
val n = 3
val patternCounts = mutableMapOf<Map<Int, Int>, Int>()
val trials = 10000
(1..trials).forEach({
val graph = generateGraph(n)
patternCounts[graph] = patternCounts.getOrDefault(graph, 0) + 1
})
println(patternCounts)
}
刚刚打印了这个运行
{{1=3, 2=1, 3=2}=6669, {1=2, 2=3, 3=1}=3331}
我错过了什么?而且,有没有办法让这个公平?
【问题讨论】: