我看到了很多在特定范圍內生成隨機浮點數的解決方案(像這樣),這實際上對我有幫助,以及生成隨機浮點數總和為 1(像這樣)的解決方案,單獨的解決方案作業得很好,但我不知道如何合并它們。
目前我的代碼是:
import random
def sample_floats(low, high, k=1):
""" Return a k-length list of unique random floats
in the range of low <= x <= high
"""
result = []
seen = set()
for i in range(k):
x = random.uniform(low, high)
while x in seen:
x = random.uniform(low, high)
seen.add(x)
result.append(x)
return result
仍然,申請
weights = sample_floats(0.055, 1.0, 11)
weights /= np.sum(weights)
回傳weights陣列,其中有一些浮點數少于0.055
我應該以某種方式np.random.dirichlet在上面的函式中實作,還是應該建立在基礎上np.random.dirichlet然后實作條件> 0.055?想不出任何解決辦法。
謝謝指教!
uj5u.com熱心網友回復:
IIUC,您要生成一個k值陣列,最小值為low=0.055.
更容易從 0 生成總和到 的數字1-low*k,然后相加low使最終陣列的總和為 1。因此,這保證了下限和總和。
關于high,我很確定添加這個約束在數學上是不可能的,因為一旦你確定了下限和總和,就沒有足夠的自由度來選擇上限。上限將為1-low*(k-1)(此處為 0.505)。
此外,要注意的是,與最小值,您一定強制執行最大k的1//low(在這里18個值)。如果您設定得k更高,則下限將不正確。
# parameters
low = 0.055
k = 10
a = np.random.rand(k)
a = (a/a.sum()*(1-low*k))
weights = a low
# checking that the sum is 1
assert np.isclose(weights.sum(), 1)
示例輸出:
array([0.13608635, 0.06796974, 0.07444545, 0.1361171 , 0.07217206,
0.09223554, 0.12713463, 0.11012871, 0.1107402 , 0.07297022])
uj5u.com熱心網友回復:
您可以k-1通過改變統一亂數生成器的下限和上限來迭代地生成數字 - 任何迭代的約束是生成的數字允許其余數字至少為low
def sample_floats(low, high, k=1):
result = []
generated = 0
while generated < k-1:
current_higher_bound = max(low, 1 - (k - 1 - generated)*low - sum(result))
next_num = random.uniform(low, current_higher_bound)
result.append(next_num)
generated = 1
last_num = 1 - sum(result)
result.append(last_num)
return result
print(sample_floats(0.01, 1, k=15))
#[0.08878760926151083,
# 0.17897435239586243,
# 0.5873150041878156,
# 0.021487776792166513,
# 0.011234379498998357,
# 0.012408564286727042,
# 0.015391011259745103,
# 0.01264921242128719,
# 0.010759267284382326,
# 0.010615007333002748,
# 0.010288605412288477,
# 0.010060487014659121,
# 0.010027216923973544,
# 0.010000064276203318,
# 0.010001441651377285]
uj5u.com熱心網友回復:
樣本是相關的,所以我相信你不能以 IID 方式生成它們。但是,您可以以迭代方式進行。例如,您可以按照我在下面的代碼中顯示的方式進行操作。還有一些特殊情況需要檢查,比如如果用戶輸入 low<high 或 high*k<sum。但是我認為您可以使用我對代碼的修改來找到并解釋它們。
import random
import warnings
def sample_floats(low = 0.055, high = 1., x_sum = 1., k = 1):
""" Return a k-length list of unique random floats
in the range of 'low' <= x <= 'high' summing up to 'sum'.
"""
sum_i = 0
xs = []
if x_sum - (k-1)*low < high:
warnings.warn(f'high = {high} is to high to be generated under the'
f' conditions set by k = {k}, sum = {x_sum}, and low = {low}.'
f' high automatically set to {x_sum - (k-1)*low}.')
if k == 1:
if high < x_sum:
raise ValueError(f'The parameter combination k = {k}, sum = {x_sum},'
' and high = {high} is impossible.')
else: return x_sum
high_i = high
for i in range(k-1):
x = random.uniform(low, high_i)
xs.append(x)
sum_i = sum_i x
if high < (x_sum - sum_i - (k-1-i)*low):
high_i = high
else: high_i = x_sum - sum_i - (k-1-i)*low
xs.append(x_sum - sum_i)
return xs
例如:
random.seed(0)
xs = sample_floats(low = 0.055, high = 0.5, x_sum = 1., k = 5)
print(xs)
print(sum(xs))
輸出:
[0.43076772392864643, 0.27801464913542906, 0.08495210994346317, 0.06568433355884717, 0.14058118343361425]
1.0
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/403500.html
標籤:
