每个索引

问题描述:

在生成具有唯一值号的多个序列我有数字1:n一行。我期待还添加了第二排与数字1:n但这些应该是随机顺序,同时满足以下:每个索引

  1. 没有位置有两行相同数量的
  2. 数没有发生结合两次

例如,在下面的

Row 1: 1 2 3 4 5 6 7 ... 
Row 2: 3 6 15 8 13 12 7 ... 

7号发生在两行1和2相同的位置(即位置7;而在2 + 7以下

Row 1: 1 2 3 4 5 6 7 ... 
Row 2: 3 7 15 8 13 12 2 ... 

组合出现两次(在位置2和7从而不满足规则1)

;由此不满足规则2)。

这或许会是可能的 - 但不必要的耗时 - 手工做到这一点(至少直到一个合理的数字),但必须在MATLAB这个一个相当优雅的解决方案。

+0

假设有10个人,如果他们中的三个人处于与其他人分开的循环中,你会感到高兴吗?例如1→2→2→3→3→1→。如果您希望禁止该组中的任何此类部门,那么我在我的答案中描述了一个简单的解决方案。 – 2012-01-13 00:24:22

这很简单。创建节点的随机排列,但解释列表如下:解释它是随机遍历节点,如果节点'b'出现在节点'a'之后,则意味着节点'b'出现在节点'a下面“在列表中:

因此,如果您最初的随机排列是

3 2 5 1 4 

那么在这种情况下,走的是3 -> 2 -> 5 -> 1 -> 4和你创建的行如下:

Row 1: 1 2 3 4 5 
Row 2: 4 5 2 3 1 

这个随机游走会满足这两个条件。

但是,你希望在网络中允许多个循环吗?我知道你不想让两个人戴上对方的帽子。但是,大约有7个人,其中有他们有彼此的帽子和其他的有彼此的帽子?这是否可接受和/或理想?

+0

事后看来:花了我多一点时间来理解你的意思,但理论上这似乎是最优雅的解决方案,因为它不需要任何循环(“试错”)! – user1092247 2012-01-13 18:38:09

+0

@ user1092247,没问题,我不得不编辑我的答案,使其更具可读性。随意建议任何重新措词。 – 2012-01-13 18:49:17

这个问题被称为derangment置换的
使用功能randperm,为了找到你的数据的随机排列。

x = [1 2 3 4 5 6 7]; 
y = randperm(x); 

然后,您可以检查序列是否合法。如果不是这样,一次又一次地做到这一点..
你的probability约0.3每一次成功,这意味着你需要大约10/3次尝试,直到你找到它。 因此,您会很快找到答案。

或者,您可以使用this algorithm创建随机derangment。

编辑

如果你想拥有大小> 2的唯一周期,这是问题的一个概括。 其中写道,that case中的概率 较小,但大到足以在固定数量的步骤中找到它。所以同样的方法仍然有效。

+0

我认为这是一种局部的紊乱。为了扩展你在PDF文件中的类比,你应该链接到:当没有绅士应该回到他们自己的帽子(混乱)时,也不应该有两个有别人帽子的绅士(规则2,请参阅我的编辑)。也许可以在matlab中创建一个脚本,比较这两个规则随机生成的“1:n”序列,直到找到满足两个规则的序列为止? – user1092247 2012-01-12 15:04:44

+0

@ user1092247,我已经更新了我的答案。欢迎来到SO。如果你喜欢我的回答,不要忘记加入并接受。 – 2012-01-12 15:17:08

+0

谁低估了,我很想听听有什么不对。 – 2012-01-13 16:47:21

安德烈已经指出你randperm和拒绝采样的方法。在产生排列p之后,检查其是否具有固定点的简单方法是any(p==1:n)。检查是否包含长度为2的循环的简单方法是any(p(p)==1:n)

所以这得到排列1:np满足您的要求:

p=[]; 
while (isempty(p)) 
    p=randperm(n); 
    if any(p==1:n), p=[]; 
    elseif any(p(p)==1:n), p=[]; 
    end 
end 

for循环,为while循环的每个计数迭代围绕这一点,似乎人们需要生成平均4.5排列对于每个“有效”的(如果不允许长度为3的周期,则为6.2)。很有意思。

+0

这是一段很棒的代码!满足第二个条件的解决方案(使用“p(p)”)效果很好(即使它确实需要“试错”)。谢谢! – user1092247 2012-01-13 18:43:47