2014-04-15 76 views
0

我試圖創建一個文本文件,每個可能的100%分佈到n個容器中?因此,對於4個容器,它看起來是這樣的:在一個很好的方式枚舉分佈

0.97, 0.01, 0.01, 0.01 
0.96, 0.01, 0.01, 0.02 
0.96, 0.01, 0.02, 0.01 
0.96, 0.02, 0.01, 0.01 
... 

任何想法做到這一點?

+0

你似乎在做兩個(大)隱含的假設,但沒有說明它們。首先,你只需要數值到最接近的百分比 - 如果有任何百分比是允許的,有無數的解決方案,但是你沒有說明你想要的精度。其次,您的示例沒有顯示0%的示例 - 是否明確禁止? – pjs

+0

對不起。你是對的,我需要最接近的整體百分比,因爲就像你所說的那樣,否則就會有無限的解決方案,如果分佈數量低於整個百分點,分佈數量將呈指數增長。 0%是允許的,但不是必需的,因爲這些可以從n-1答案中輕鬆生成。 – user3534117

+0

在這種情況下,它相當於一個基於整數的枚舉問題,如果容器的數量是固定的,您可以用嵌套循環來解決它,或者如果容器的數量可能會發生更改,則可以通過遞歸來解決。 – pjs

回答

0

基於對上述評論的迴應,這裏是用Ruby遞歸解決方案:

$resolution = 100 
$res_f = $resolution.to_f 

def allocate(remainder, bin_number, all_bin_values, number_of_bins) 
    if bin_number >= number_of_bins 
    all_bin_values << remainder/$res_f 
    puts all_bin_values.join(", ") 
    all_bin_values.pop 
    else 
    remainder.downto(1) do |i| 
     if remainder - i >= number_of_bins - bin_number 
     all_bin_values << i/$res_f 
     allocate(remainder - i, bin_number + 1, all_bin_values, number_of_bins) 
     all_bin_values.pop 
     end 
    end 
    end 
end 

num_bins = (ARGV.shift || 4).to_i 
allocate($resolution, 1, [], num_bins) 

容器違約數量爲4,但可以通過提供的命令行參數覆蓋在運行時。

附錄

我被你的評論,一個環形的版本「是太緩慢」感到驚訝。所有其他條件相同,循環應該比遞歸更快,那是當我計時這裏給出的迭代版本的情況:

resolution = 100 
res_f = resolution.to_f 

resolution.downto(1) do |first| 
    remainder1 = resolution - first 
    remainder1.downto(1) do |second| 
    remainder2 = remainder1 - second 
    remainder2.downto(1) do |third| 
     fourth = remainder2 - third 
     printf "%g, %g, %g, %g\n", first/res_f, 
     second/res_f, third/res_f, fourth/res_f if fourth > 0 
    end 
    end 
end 

雖然這是快,缺點是,如果你想要一個不同數量的容器的代碼將不得不通過添加額外的嵌套循環來相應地進行修改。

+0

這很好用!嵌套循環太慢了,但這非常快。謝謝! – user3534117

+0

很高興幫助。 – pjs