This can be solved algebraically. Let’s say that the current weight of epics in that list is e1
, and the total sum of all weights in that list is t1
. The chance of picking an epic level pet right now would be e1/t1
, but we want to double that. So let’s add some number x
to e1
such that the probability would be:
e2/t2 = (e1+x) / (t1+x) = 2 * e1 / t1
(Increasing e1
by x
also increases t1
by x
.)
Then solve for x
:
t * (e1 + x) = 2 * e1 * (t1 + x)
t*e1 + t*x = 2*e1*t1 + 2*e1*x
t*e1 - 2*e1*t1 = 2*e1*x - t1*x = x * (2*e1 - t1)
x = (t1*e1 - 2*e1*t1) / (2*e1 - t1)
x = (-t1*e1) / (2*e1 - t1)
The generic equation, where N
is the factor by which you want to multiply the chance, would be:
x = t1*e1(1 - N) / (N*e1 - t1)
My test code:
-- pick a random key from a weighted list
local function pick(list)
local total = 0
for _, v in pairs(list) do
total = total + v
end
local r = Random.new():NextNumber() * total
total = 0
for k, v in pairs(list) do
total = total + v
if (total >= r) then
return k
end
end
end
-- calculates the number you would need to add to a specific weight in order to change it's probability
local function increment(list, key, factor)
local t = 0
for _, v in pairs(list) do
t = t + v
end
local p = list[key]
local a = t * p * (1 - factor)
local b = factor * p - t
-- if it makes the chance go over 100%
if (b == 0 or (factor > 1 and math.sign(a) ~= math.sign(b))) then
return math.huge
else
return a / b
end
end
local probs = {
a = 30,
b = 20, -- note that 'b' is 20/100
c = 20,
d = 25,
e = 5
}
local results = {
a = 0, b = 0, c = 0, d = 0, e = 0
}
local n = 10000
for i = 1, n do
local k = pick(probs)
results[k] = results[k] + 1
end
print("test 1")
for k, v in pairs(results) do
print(k, ":", v / n) -- 'b' should be around .2
end
local results = {
a = 0, b = 0, c = 0, d = 0, e = 0
}
print("-")
probs['b'] = probs['b'] + increment(probs, 'b', 2)
for i = 1, n do
local k = pick(probs)
results[k] = results[k] + 1
end
print("test 2")
for k, v in pairs(results) do
print(k, ":", v / n) -- 'b' should be around .4
end
In the two outputs, the percentage of ‘b’ outputs in the second test should be about double what it was in the first test. Also be aware that the probabilities of everything else get smaller when one weight value is increased.