我有一行数字1:n
。我正在寻找第二行还有数字1:n
但这些应该是随机顺序,同时满足以下条件:
例如,在下面的
中Row 1: 1 2 3 4 5 6 7 ...
Row 2: 3 6 15 8 13 12 7 ...
数字7出现在第1行和第2行的相同位置(即位置7;因此不满足规则1)
在以下
中Row 1: 1 2 3 4 5 6 7 ...
Row 2: 3 7 15 8 13 12 2 ...
2 + 7的组合出现两次(在第2和第7位;因此不满足规则2)。
或许可以 - 但是不必要地耗费时间 - 手动执行此操作(至少直到合理的数量),但在MATLAB中必须有相当优雅的解决方案。
答案 0 :(得分:2)
这个问题被称为排列的 derangment 使用 randperm 功能,以查找数据的随机排列。
x = [1 2 3 4 5 6 7];
y = randperm(x);
然后,您可以检查序列是否合法。如果没有,一次又一次地做 每次成功约有0.3 probability,这意味着你需要大约10/3次才能找到它。 因此,您会很快找到答案。
或者,您可以使用this algorithm创建随机设置。
修改强>
如果您想只有尺寸>的周期2,这是问题的概括。 在它写的概率 在that case中较小,但足够大,可以在固定的步骤中找到它。所以同样的方法仍然有效。
答案 1 :(得分:1)
这非常简单。创建节点的随机排列,但按如下方式解释列表:将其解释为在节点周围随机游走,如果节点'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个人呢,其中 3 有彼此的帽子而另一个 4 有彼此的帽子?这是可接受的和/或可取的吗?
答案 2 :(得分:1)
安德烈已经向你指出randperm
和类似拒绝抽样的方法。生成排列p
后,检查其是否具有固定点的简单方法是any(p==1:n)
。检查它是否包含长度为2的周期的简单方法是any(p(p)==1:n)
。
这样就可以p
满足您的要求1:n
的排列:
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
。非常有趣。