如何为访问n-churches的n-pastors创建一个时间表?

时间:2008-12-01 12:31:18

标签: java algorithm random

我想为许多牧师制定一份时间表。条件是:

  1. 每个月,每个牧师都必须去另一个教堂,
  2. 牧师不得去他所来的同一个教堂
  3. 在1年内,他必须去12个不同的教堂
  4. 有13个教堂和13个牧师,每个教会每个月只接受1个牧师
  5. 我不能随意使用(1到12),因为牧师有可能去同一个教堂(有机会他去同一个教堂的机率为8.3%)。

    我想让他去同一个教会的机会很小(大约3%或更少)。

2 个答案:

答案 0 :(得分:12)

你的条件并不要求随机选择下一个教会给定牧师。难道你不能遍历教会名单吗?

即,为每个牧师分配一个0-12的数字。为每个教会分配一个0-12的数字。第一个月:

  

第0个月:
  牧师-0 - >教堂0
  牧师-1 - >教堂1
  牧师-2 - >教堂-2
  ...
  pastor-n - >教堂-n

下个月,只需增加一个计数器(带环绕式)

  

第1个月:
  牧师-0 - >教堂1
  牧师-1 - >教堂-2
  牧师-2 - >教堂3
  ...
  pastor-n - >教堂-0

然后重复剩下的几个月:

  

第3个月:
  牧师-0 - >教堂-2
  牧师-1 - >教堂3
  牧师-2 - >教堂4
  ...
  牧师 - (n-1) - >教堂0
  pastor-n - >教堂-1

所有这一切都有一个非常简单的循环(O(n))。如果它让你感到困惑,我建议用n = 3来试试纸上的循环。

如果要求随机性,请更新您的问题。

编辑PAX

我正在删除我的答案并对此进行投票,因为它是O(n)并且我的扩展以满足编辑的要求至少为O(n ^ 2)。

你仍然可以通过将pastor-0到pastor-N值索引变成一个随机排序的牧师数组来实现随机性,这样就可以使这个解决方案至少和我的一样好。

结束编辑PAX

答案 1 :(得分:1)

鉴于你有相同数量的牧师和教会,这是一个非常简单的算法:

  1. 每个教会的编号从0到12

  2. 构造一个包含0到12元素的数组。

  3. 在阵列上执行Knuth Shuffle(见下文),生成随机改组的教堂列表。

  4. 每位牧师都在他们自己的教会开始(如果牧师没有指定教会,只需对牧师0到12进行任意编号,并将他们与教会相同的数字进行匹配)。每个月,每位牧师都会搬到名单上的下一个教堂。如果他们在名单上的最后一个教堂,他们会去第一个。

  5. 这有一个很容易解释的好处:只需给每个牧师提供洗牌清单并告诉他们从哪里开始。

    Knuth shuffle(大致)是:

    def knuth_shuffle(l):
        for i in range(len(l)):
            j = random.randint(i, len(l))
            l[i], l[j] = l[j], l[i]
    

    非常重要的是要注意,在每次迭代中,您都要使用从已经选择 not 的那些中选择的随机元素交换列表中的当前项。这确保了可能的shuffle的数量与排列的数量完全匹配(因此,它们都具有相同的概率),基于交换随机元素的天真shuffle,或者将当前元素与整个列表中的任何元素交换,don'有。。