拖曳成对约束

时间:2019-01-04 15:20:05

标签: python shuffle

我有n个列表,每个列表的长度为m。假设n*m是偶数。我想获得一个包含所有元素的随机混排列表,其约束条件是i,i+1位置i=0,2,...,n*m-2中的元素永远不会来自同一列表。编辑:除了这个限制,我不想偏向随机列表的分布。也就是说,解决方案应该等效于重新随机选择直到约束成立的完整随机选择。

示例:

列表1:a1,a2

列表2:b1,b2

列表3:c1,c2

允许:b1,c1,c2,a2,a1,b2

不允许:b1,c1,c2,b2,a1,a2

4 个答案:

答案 0 :(得分:1)

一个可能的解决方案是将您的数字集视为n个项目块,每个块的长度为m。如果您从每个列表中为每个块随机选择恰好一个项目,那么您将永远不会死胡同。只需确保每个块中的第一个项目(第一个块除外)将与上一个块的最后一个元素具有不同的列表即可。

您还可以迭代地随机分配数字,始终确保您从与前一个数字不同的列表中进行选择,但是随后您可能会陷入困境。

最后,另一种可能的解决方案是按顺序在每个位置上随机分配一个数字,但只能从那些“可以放在该位置”的位置进行随机化,也就是说,如果您放置一个数字,则不会违反任何约束,即,您将至少有一个可能的解决方案。

答案 1 :(得分:1)

上面b的变体避免了死胡同:在每个步骤中,选择两次。首先,随机选择一个项目。其次,随机选择放置位置。在第K步中,有k个放置项目的可选位置(新项目可以注入到两个现有项目之间)。当然,您只能从允许的位置中进行选择。 钱!

答案 2 :(得分:1)

  1. 将您的列表排列成列表列表
  2. 将列表中的每个项目保存为元组,列表列表中的列表索引为
  3. 循环n * m次
  4. 甚至转弯-拼合成一个列表,然后随机弹出-产生项目和项目组
  5. 在奇怪的转弯处-暂时删除最后一个项目组并像以前一样弹出-最后将删除的组添加回去

重要-如何避免死锁?

如果所有其余项目仅来自一个组,则可能发生死锁。
为避免这种情况,请在每次迭代中检查所有列表的长度
检查最长的列表是否长于所有其他列表的总和
如果为真-为该列表拉动

那样,您将永远不会只剩下一个完整的列表


这是一个尝试在python中解决这个问题的要点 https://gist.github.com/YontiLevin/bd32815a0ec62b920bed214921a96c9d

答案 3 :(得分:0)

我正在尝试的一种非常快速简单的方法是:

random shuffle
loop over the pairs in the list:
   if pair is bad:
   loop over the pairs in the list:
      if both elements of the new pair are different than the bad pair:
         swap the second elements
         break

这总能找到解决方案吗?在找到合法的解决方案之前,解决方案的分布是否会与幼稚的改组相同?