-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathweighted_unique_random.lua
More file actions
53 lines (42 loc) · 1.46 KB
/
Copy pathweighted_unique_random.lua
File metadata and controls
53 lines (42 loc) · 1.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
local function weighted_unique_random(tbl_weight, tbl_exists, random_func, id, weight)
random_func = random_func or math.random
id = id or "id"
weight = weight or "weight"
local t = {}
local total_weight = 0
for _, v in pairs(tbl_weight) do
if not tbl_exists[v[id]] then
assert( type(v[weight]) == "number" )
total_weight = total_weight + v[weight]
table.insert(t, { [id] = v[id], [weight] = v[weight], value = v })
end
end
table.sort(t, function (a, b) return a[weight] > b[weight] end )
if total_weight == 0 then
return nil
end
local rand = random_func(1, total_weight)
local curweight = 0
for _, v in ipairs(t) do
curweight = curweight + v[weight]
if rand <= curweight then
return v.value
end
end
assert(false, string.format("%d %d", rand, curweight))
end
math.randomseed( os.time() )
local t = {}
t[1] = { weight = 2000, id = 1 }
t[2] = { weight = 2000, id = 2 }
t[3] = { weight = 30, id = 3 }
t[4] = { weight = 40, id = 4 }
t[5] = { weight = 50, id = 5 }
local r = {}
for i = 1, 5 do
local v = weighted_unique_random(t, r, math.random)
assert(v)
r[v.id] = v
print(v.id, v.weight)
end
assert( weighted_unique_random(t, r) == nil )