Skip to content

Instantly share code, notes, and snippets.

@ZLOY5
Created October 29, 2016 18:17
Show Gist options
  • Save ZLOY5/f1d627b5216fa2e17bd8acc979b44dc0 to your computer and use it in GitHub Desktop.
Save ZLOY5/f1d627b5216fa2e17bd8acc979b44dc0 to your computer and use it in GitHub Desktop.
PseudoRandomDistribution = {}
PseudoRandomDistribution.__index = PseudoRandomDistribution
function PseudoRandomDistribution:New(nChance)
local obj = {
counter = 0,
chance = nChance,
const = self:CalculateConstant(nChance)
}
setmetatable(obj,self)
return obj
end
function PseudoRandomDistribution:Trigger()
self.counter = self.counter + 1
local counter = self.counter
if RandomFloat(0,1) < self.counter*self.const then
self.counter = 0
return true,counter
end
return false,counter
end
function PseudoRandomDistribution:SetChance(nChance)
self.counter = 0
self.chance = nChance
self.const = self:CalculateConstant(nChance)
end
function PseudoRandomDistribution:CalculateConstant(nChance)
local Cupper = nChance
local Clower = 0
local Cmid
local p1
local p2 = 1
while true do
Cmid = ( Cupper + Clower ) / 2
p1 = self:CalculateChance( Cmid )
if math.abs( p1 - p2 ) <= 0 then
break
end
if p1 > nChance then
Cupper = Cmid
else
Clower = Cmid
end
p2 = p1
end
print(Cmid)
return Cmid;
end
function PseudoRandomDistribution:CalculateChance(const)
local pProcOnN = 0
local pProcByN = 0
local sumNpProcOnN = 0
local maxFails = math.ceil( 1 / const )
for N = 1,maxFails do
pProcOnN = math.min( 1, N * const ) * (1 - pProcByN)
pProcByN = pProcByN + pProcOnN
sumNpProcOnN = sumNpProcOnN + N * pProcOnN
end
return 1/sumNpProcOnN
end
local test = PseudoRandomDistribution:New(0.1)
local result = {}
for i=1,600000 do
local bProc,counterPos = test:Trigger()
--print(bProc,counterPos)
if bProc then
result[counterPos] = (result[counterPos] or 0) + 1
end
end
DeepPrintTable(result)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment