创建更好的随机算法的问题 - 每日传播
Issue creating better random algorithm - daily spread
我需要一个算法,按照该时间规则的最小/最大百分比,将一些数字按百分比分布在一天中,这就是我的 atm:
public function getSpread() {
$rules = [
'00-07' => ['min' => 5, 'max' => 10],
'08-12' => ['min' => 20, 'max' => 30],
'13-16' => ['min' => 20, 'max' => 30],
'17-22' => ['min' => 25, 'max' => 40],
'23-24' => ['min' => 10, 'max' => 15],
];
$spread = [];
foreach ($rules as $time => $rule) {
$value = rand($rule['min'], $rule['max']);
while ($this->getNewSum($spread, $value) > 100) {
$value = $value - 1;
}
$spread[$time] = $value;
}
return $spread;
}
private function getNewSum($spread, $value) {
$sum = 0 + $value;
foreach ($spread as $s) {
$sum = $sum + $s;
}
return $sum;
}
结果:
array:5 [
"00-07" => 5
"08-12" => 24
"13-18" => 30
"19-22" => 32
"23-24" => 9
]
array:5 [
"00-07" => 8
"08-12" => 29
"13-18" => 29
"19-22" => 27
"23-24" => 7
]
array:5 [
"00-07" => 8
"08-12" => 28
"13-18" => 21
"19-22" => 33
"23-24" => 10
]
array:5 [
"00-07" => 9
"08-12" => 20
"13-18" => 21
"19-22" => 25
"23-24" => 15
]
array:5 [
"00-07" => 8
"08-12" => 28
"13-18" => 20
"19-22" => 29
"23-24" => 10
]
array:5 [
"00-07" => 9
"08-12" => 20
"13-18" => 22
"19-22" => 28
"23-24" => 15
]
array:5 [
"00-07" => 5
"08-12" => 23
"13-18" => 23
"19-22" => 40
"23-24" => 9
]
有什么方法可以优化它并使其更多 "random",我希望能够增加最小、最大规则,但如果我这样做,结束元素会受到影响,并且总是变成 0
我实际上最好按小时创建它,而不是从 - 到小时。
您需要使用适当的条件概率。对不起 Python 3.
import collections
import random
def sample(total, intervals):
counts = [collections.Counter({0: 1})]
for interval in reversed(intervals):
counts.append(collections.Counter())
for x in interval:
for tot, n in counts[-2].items():
counts[-1][x + tot] += n
samp = []
for interval in intervals:
outcome = random.randrange(counts.pop()[total])
for x in interval:
outcome -= counts[-1][total - x]
if outcome < 0:
samp.append(x)
break
else:
assert False
total -= samp[-1]
return samp
for i in range(20):
print(sample(100, [
range(5, 11),
range(20, 31),
range(20, 31),
range(25, 41),
range(10, 16),
]))
示例输出:
[10, 21, 20, 39, 10]
[7, 27, 26, 29, 11]
[6, 28, 21, 31, 14]
[7, 22, 27, 34, 10]
[10, 21, 29, 27, 13]
[9, 23, 24, 34, 10]
[7, 24, 30, 26, 13]
[7, 22, 20, 39, 12]
[10, 28, 25, 27, 10]
[9, 22, 20, 38, 11]
[5, 26, 30, 29, 10]
[7, 25, 22, 33, 13]
[5, 27, 21, 37, 10]
[9, 23, 25, 28, 15]
[6, 28, 25, 28, 13]
[7, 30, 23, 30, 10]
[7, 21, 20, 38, 14]
[6, 26, 22, 34, 12]
[8, 24, 23, 30, 15]
[9, 29, 25, 25, 12]
我需要一个算法,按照该时间规则的最小/最大百分比,将一些数字按百分比分布在一天中,这就是我的 atm:
public function getSpread() {
$rules = [
'00-07' => ['min' => 5, 'max' => 10],
'08-12' => ['min' => 20, 'max' => 30],
'13-16' => ['min' => 20, 'max' => 30],
'17-22' => ['min' => 25, 'max' => 40],
'23-24' => ['min' => 10, 'max' => 15],
];
$spread = [];
foreach ($rules as $time => $rule) {
$value = rand($rule['min'], $rule['max']);
while ($this->getNewSum($spread, $value) > 100) {
$value = $value - 1;
}
$spread[$time] = $value;
}
return $spread;
}
private function getNewSum($spread, $value) {
$sum = 0 + $value;
foreach ($spread as $s) {
$sum = $sum + $s;
}
return $sum;
}
结果:
array:5 [
"00-07" => 5
"08-12" => 24
"13-18" => 30
"19-22" => 32
"23-24" => 9
]
array:5 [
"00-07" => 8
"08-12" => 29
"13-18" => 29
"19-22" => 27
"23-24" => 7
]
array:5 [
"00-07" => 8
"08-12" => 28
"13-18" => 21
"19-22" => 33
"23-24" => 10
]
array:5 [
"00-07" => 9
"08-12" => 20
"13-18" => 21
"19-22" => 25
"23-24" => 15
]
array:5 [
"00-07" => 8
"08-12" => 28
"13-18" => 20
"19-22" => 29
"23-24" => 10
]
array:5 [
"00-07" => 9
"08-12" => 20
"13-18" => 22
"19-22" => 28
"23-24" => 15
]
array:5 [
"00-07" => 5
"08-12" => 23
"13-18" => 23
"19-22" => 40
"23-24" => 9
]
有什么方法可以优化它并使其更多 "random",我希望能够增加最小、最大规则,但如果我这样做,结束元素会受到影响,并且总是变成 0
我实际上最好按小时创建它,而不是从 - 到小时。
您需要使用适当的条件概率。对不起 Python 3.
import collections
import random
def sample(total, intervals):
counts = [collections.Counter({0: 1})]
for interval in reversed(intervals):
counts.append(collections.Counter())
for x in interval:
for tot, n in counts[-2].items():
counts[-1][x + tot] += n
samp = []
for interval in intervals:
outcome = random.randrange(counts.pop()[total])
for x in interval:
outcome -= counts[-1][total - x]
if outcome < 0:
samp.append(x)
break
else:
assert False
total -= samp[-1]
return samp
for i in range(20):
print(sample(100, [
range(5, 11),
range(20, 31),
range(20, 31),
range(25, 41),
range(10, 16),
]))
示例输出:
[10, 21, 20, 39, 10]
[7, 27, 26, 29, 11]
[6, 28, 21, 31, 14]
[7, 22, 27, 34, 10]
[10, 21, 29, 27, 13]
[9, 23, 24, 34, 10]
[7, 24, 30, 26, 13]
[7, 22, 20, 39, 12]
[10, 28, 25, 27, 10]
[9, 22, 20, 38, 11]
[5, 26, 30, 29, 10]
[7, 25, 22, 33, 13]
[5, 27, 21, 37, 10]
[9, 23, 25, 28, 15]
[6, 28, 25, 28, 13]
[7, 30, 23, 30, 10]
[7, 21, 20, 38, 14]
[6, 26, 22, 34, 12]
[8, 24, 23, 30, 15]
[9, 29, 25, 25, 12]