Created
October 29, 2016 18:17
-
-
Save ZLOY5/f1d627b5216fa2e17bd8acc979b44dc0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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