Skip to content

Instantly share code, notes, and snippets.

@StrayDragon
Last active May 7, 2020 11:42
Show Gist options
  • Save StrayDragon/4e8278e67505d1248a769fba2d1966a7 to your computer and use it in GitHub Desktop.
Save StrayDragon/4e8278e67505d1248a769fba2d1966a7 to your computer and use it in GitHub Desktop.
import random
from typing import List
from pprint import pprint
from dataclasses import dataclass, field
debug = False
@dataclass
class Item:
id: int = field(init=False)
# id: int
rate: float
# FIXME: 总和不到1
def make_random_items(n: int) -> List[Item]:
return [
Item(id=i, exposure_rate=random.uniform(0.0, 1.0) * 0.5)
for i in range(n)
]
# FIXME: 总和不到1
def make_random_sorted_items(n: int) -> List[Item]:
items = make_items(n)
items.sort(key=lambda d: d.rate, reverse=True)
i = 0
for d in items:
d.id = i
i += 1
return items
def make_sorted_fixed_items() -> List[Item]:
items = [
Item(rate=0.5),
Item(rate=0.3),
Item(rate=0.1),
Item(rate=0.1),
]
i = 0
for d in items:
d.id = i
i += 1
return items
def show(d: List[Item]):
from matplotlib import pyplot
ids, rates = [], []
for e in d:
ids.append(e.id)
rates.append(e.rate)
pyplot.plot(ids, rates)
pyplot.xlabel('rate')
pyplot.ylabel('item id')
pyplot.title('item_id & rate')
pyplot.yticks([0.0, 0.25, 0.50, 0.75, 1.0])
pyplot.xticks(ids)
# pyplot.fill_between(rates, ids, 10, color = 'green')
pyplot.show()
def hit_proper_item_by_rate(d: List[Item]) -> Item:
lucky_number = random.uniform(0.0, 1.0)
cumulative_probability = 0.0
if debug: print(f'\n> {lucky_number=}')
for e in d:
cumulative_probability += e.rate
if cumulative_probability > lucky_number: break
return e
def test(items: List[Item], amount: int = 100, tolerance: int = 10):
print(f"概率测试 共{amount}次")
kv: dict = {d.id: 0 for d in deliveries}
for _ in range(amount):
d = hit_proper_item_by_rate(items)
kv[d.id] += 1
for d in items:
expect_amount = amount * d.rate
hit_count = kv[d.id]
result = abs(expect_amount - hit_count) < tolerance
print(
f"delivery-{d.id} 命中 {hit_count} 次, 符合预期吗(误差+-{tolerance})? {expect_amount} == {hit_count} => {result}"
)
# items = make_random_items(5)
# items = make_random_sorted_items(3)
items = make_sorted_fixed_items()
pprint(items)
show(items)
d = hit_proper_item_by_rate(items)
print(f'命中: {d=}')
test(items, amount=300)
test(items, amount=3000)
test(items, amount=30000)
test(items, amount=300000)
test(items, amount=3000000)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment