2012-01-12 63 views
5

在生成具有唯一值號的多個序列我有數字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

回答

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個人,其中有他們有彼此的帽子和其他的有彼此的帽子?這是否可接受和/或理想?

+0

事後看來:花了我多一點時間來理解你的意思,但理論上這似乎是最優雅的解決方案,因爲它不需要任何循環(「試錯」)! – user1092247 2012-01-13 18:38:09

+0

@ user1092247,沒問題,我不得不編輯我的答案,使其更具可讀性。隨意建議任何重新措詞。 – 2012-01-13 18:49:17

2

這個問題被稱爲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

1

安德烈已經指出你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