GMLscripts.com

Discuss and collaborate on GML scripts
Invert

You are not logged in.

#1 2018-12-26 20:18:17

lostdarkwolf
Member
Registered: 2015-11-19
Posts: 22

RNG with random, uneven, and shifting distribution.

Random number generation with uneven distribution.

Both scripts are required.

///irandom_uneven_setup(n_max,range_set_max,deviation)
//
// Performs initial setup for "irandom_uneven".
// This should be executed only once per calling object, such as in a create event.
//
// n_max           the highest integer used for RNG. 
// range_set_max   maximum number of sets of range distributions.
// deviation       initial random deviation from 0.5.
//
/// GMLscripts.com/license

var nn, devi;
nn=argument0;
set_max=argument1;
devi=median(argument2,0,1);

irandom_uneven_n_max=nn;
irandom_uneven_range_grid=ds_grid_create(set_max+1,nn+1);

//create distribution (raw data)
var ii_set,ii_n;
ii_set=0;
while ii_set<=set_max {
 ii_n=0;
 while ii_n<=nn {
  ds_grid_add(irandom_uneven_range_grid,ii_set,ii_n,median(0.5+((-0.5*devi)+random(devi)),1,0));
  ii_n+=1;
 }
 ii_set+=1;
}

the wording on the script below has been corrected as of 1/6/19.

///irandom_uneven(n,range_set,deviation)
//
// Generates and returns a random number with random, uneven, and shifting distribution.
// This should be called on-demand.
// returns a number between zero and n.
//
// n           Max number. Result will be between zero and n. real integer.
// range_set    Deviation set to use. real integer.
// deviation   Amount of (even distribution) random flux for range data. real normal.
//
/// GMLscripts.com/license

var nn=argument[0];
var range_set=argument[1];
var devi=argument[2];
var Return=0;

//create distribution chart from distribution (raw data).
var ii, irandom_uneven_range_chart;
ii=0;
irandom_uneven_range_chart=ds_grid_create(1,nn+1)
var var_pr=0; // pr = previous range
repeat nn+1 {
 ds_grid_set(irandom_uneven_range_chart,0,ii,var_pr+ds_grid_get(irandom_uneven_range_grid,range_set,ii))
 var_pr=ds_grid_get(irandom_uneven_range_chart,0,ii)
 ii+=1;
}

//pick a number from the distribution chart
var chosen_spot=random(ds_grid_get(irandom_uneven_range_chart,0,ii-1)-0.00001);
ii=0;
var done=0;
while done=0 {
 if chosen_spot>=ds_grid_get(irandom_uneven_range_chart,0,ii) ii+=1;
 else {
  Return=ii;
  done=1;
 }
 if ii>nn { // happens when all distribution ranges are zero.
  Return=random(nn);
  done=1;
 }
}

//deviate distribution
if devi>0 {
 ii=0;
 repeat irandom_uneven_n_max {
  ds_grid_set(irandom_uneven_range_grid,range_set,ii,median(ds_grid_get(irandom_uneven_range_grid,range_set,ii)+((-0.5*devi)+random(devi)),0.00001,0.99999));
  ii+=1
 }
}

//finalize
ds_grid_destroy(irandom_uneven_range_chart);
return Return;

Last edited by lostdarkwolf (2019-01-06 16:52:47)

Offline

#2 2018-12-27 11:51:16

xot
Administrator
Registered: 2007-08-18
Posts: 1,201

Re: RNG with random, uneven, and shifting distribution.

This needs more explanation, examples of use.


Abusing forum power since 1986.

Offline

#3 2018-12-28 04:46:41

lostdarkwolf
Member
Registered: 2015-11-19
Posts: 22

Re: RNG with random, uneven, and shifting distribution.

Cool! happy

This script is a way of getting random numbers where you have no idea what the likelihood distribution is, because the likelihood distribution is also random. Furthermore, the likelihood distribution is capable of (evenly) randomly changing every time a random number is requested. I realize that many may not want to pull random numbers from just one distribution identity, so that's what the sets are for. In the example, I only needed one distribution set, so that's all I made. This script uses local variables, and thus it will only apply to the object that is calling it.

This tallys the occorance of 0 through 9, with the script.
Create event:
(you want the deviation to be high unless you want to start with a more even distribution. If I had also wanted to tally 0 through 14, then max_n would be at least 14.)

irandom_uneven_setup(9,0,0.7)

testval[0]=0
testval[1]=0
testval[2]=0
testval[3]=0
testval[4]=0
testval[5]=0
testval[6]=0
testval[7]=0
testval[8]=0
testval[9]=0

Step event:
(you want the diviation to be low, otherwise the range values would jump around so much, that it would likely risk losing some of this script's uneven nature.)

repeat 100 {
 testval[ irandom_uneven(9,0,0.015) ]+=1;
}

Draw event:

draw_text(10,10,'0: '+string(testval[0])+'#1: '+string(testval[1])+'#2: '+string(testval[2])+'#3: '+string(testval[3])+'#4: '+string(testval[4])+'#5: '+string(testval[5])+'#6: '+string(testval[6])+'#7: '+string(testval[7])+'#8: '+string(testval[8])+'#9: '+string(testval[9]))

- - - - - - - -
To compare, here is how you tally 0 through 9 without the script (and with even distribution).
Create event:

tally[0]=0;
tally[1]=0;
tally[2]=0;
tally[3]=0;
tally[4]=0;
tally[5]=0;
tally[6]=0;
tally[7]=0;
tally[8]=0;
tally[9]=0;

Step event:

repeat 100 {
 tally[irandom(9)]+=1;
}

Draw event:

draw_text(200,10,'0: '+string(tally[0])+'#1: '+string(tally[1])+'#2: '+string(tally[2])+'#3: '+string(tally[3])+'#4: '+string(tally[4])+'#5: '+string(tally[5])+'#6: '+string(tally[6])+'#7: '+string(tally[7])+'#8: '+string(tally[8])+'#9: '+string(tally[9]))

Last edited by lostdarkwolf (2018-12-28 05:23:06)

Offline

Board footer

Powered by FluxBB