我試圖創建一個文本文件,每個可能的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
...
任何想法做到這一點?
我試圖創建一個文本文件,每個可能的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
...
任何想法做到這一點?
基於對上述評論的迴應,這裏是用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
雖然這是快,缺點是,如果你想要一個不同數量的容器的代碼將不得不通過添加額外的嵌套循環來相應地進行修改。
這很好用!嵌套循環太慢了,但這非常快。謝謝! – user3534117
很高興幫助。 – pjs
你似乎在做兩個(大)隱含的假設,但沒有說明它們。首先,你只需要數值到最接近的百分比 - 如果有任何百分比是允許的,有無數的解決方案,但是你沒有說明你想要的精度。其次,您的示例沒有顯示0%的示例 - 是否明確禁止? – pjs
對不起。你是對的,我需要最接近的整體百分比,因爲就像你所說的那樣,否則就會有無限的解決方案,如果分佈數量低於整個百分點,分佈數量將呈指數增長。 0%是允許的,但不是必需的,因爲這些可以從n-1答案中輕鬆生成。 – user3534117
在這種情況下,它相當於一個基於整數的枚舉問題,如果容器的數量是固定的,您可以用嵌套循環來解決它,或者如果容器的數量可能會發生更改,則可以通過遞歸來解決。 – pjs