Random probability (Customizing random function)

My goal is to give a linear probability to the random function.
That is, to give a higher probabiliy as lower the number`in a linear way.
However the code below gives a parabola like outcome…
Where am I wrong in my logic?

int t;
int[] num = new int[5050];
int[] h = new int[1000];

void setup() {
  background(255);
  size(1000, 600);
  for (int i = 1; i <= 100; i++) {
    for (int j = 100; j >= i; j--) { 
      num[t] = i;
      t++;
    }
  }
  for (int i = 0; i <= 999; i++) {
    h[i] = num[int(random(0, 5499))];
    line(i, height/2-3*h[i], i, height/2);
  }
  h = sort(h);
stroke(0, 0, 255);
  for (int i = 0; i <= 999; i++)  line(i, height-6*h[i], i, height);
}  

2 Likes

The code you posted does not run the first list should be
int[] num = new int[5500];

After that it is difficult to see how your algorithm is supposed to work, some comments in the code might help. I must say that your algorithm looks over complicated.

You might want to explain in more detail what you mean by

Ok, the first loop sets an array of 100 times 1, 99 times 2, 98 times 3, until 1 time 100.
This way if you chose a random index you have an ** almost** linear chance to pick lower values. I say ‘almost’, because now I realized that the graphic really has to be parabolic as you can see in the image with code below.
Now I have to.find some a formula that makes it really linear.
Any idea?
And yes, if the code is over complicated, please explain how.

int t;
int res = 45; // resolution
int[] num = new int[1050];

void setup() {
  background(255);
  size(1000, 600);
  for (int i = 1; i <= res; i++) {
    for (int j = res; j >= i; j--) { 
      num[t] = i;
      t++;
    }
  }
  for (int i = 0; i <= 1049; i++) {
    line(i, height-15*num[i], i, height);
  }
}

1 Like

you’re def on the right track and it’s a good approach but you might want to check out this redblob article about probability. if you go down to the Asymmetry section and you change the values you will end up with the output you seek as shown below

the good thing about the methods explained on that page is that they are capable of many outputs with very simple modifications

4 Likes

Thanks for the link.
The function used on the referred page is:

function rollDice(N, S):
    # Sum of N dice each of which goes from 0 to S
    value = 0
    for 0 ≤ i < N:
        value += random(S+1)
    return value

I assume that an equivalent Processing code would be something like this:

float value;

void rollDice(int N, float S) {
  value = 0;
  for (int i = 0; i < N; i++) {
    value += random(S+1);  
  }
}

I’ve experimented some different codes to implement this function,
But it still doesn’t make sense to me.

Here is an image of what I managed to get. Looks good to me. :grin:

What is even better the solution is very uncomplicated :wink:.

graph

float y_low, y_high;
float[] y;

void setup() {
  size(640, 400);
  background(255);
  y = new float[width];
  y_low = 0;
  y_high = height / 2;
  // Draw th graph
  stroke(64);
  for (int i = 0; i < y.length; i++) {
    y[i] = randomLinear(y_low, y_high);
    line(i, height / 2 - y[i], i, height / 2);
  }
  // Draw the sorted graph
  y = sort(y);
  stroke(255, 10, 100);
  for (int i = 0; i < y.length; i++) {
    line(i, height - y[i], i, height);
  }
}  

/**
 Return a random value >= low and < high such
 that the distribution is proportional to the 
 returned value.
 */
float randomLinear(float low, float high) {
  float r = sqrt(2) * random(1/sqrt(2));
  return r * (high - low) + low;
}
2 Likes

Thank you so much. This is exactly what I need. Meanwhile, I was writing a code to work with a table so that you can customize the random function like described in the site link given by @hotfooted . Later on, I will post it.

The idea of customizing the random function consists in creating an array of for instance 1000 integers, each with a value from 0 to, for instance, 500. Such an array can be created by drawing a line in a window from left to right with the height y giving the value of index x.

When these indexes are randomly accessed, the chance of picking a lower or higher value is determined by the shape of the line shown in the picture. Customized random tables are sometimes used in games. Another usage you can find on this topic.
The code will generate a one-line string of the customized random table in the console that can be copied/pasted into the other sketch.

float x, y, old_x, old_y, targetX, targetY;
float easing = 0.11; // increase for more details
boolean down, begin = true;
String str = "";
int i, j=0;

void setup() {
  size(1000, 500);
  smooth();
  erase();
}

void draw() {
  if (down) {
    if (begin) {
      old_x = 0; 
      old_y =  mouseY;
      x = mouseX;
      y = mouseY;
      begin = false;
    }
    targetX = mouseX;
    targetY = mouseY;
    x += (targetX - x) * easing;
    y += (targetY - y) * easing;   
    line(old_x, old_y, x, y);
    old_x = x;
    old_y = y;
  }
}

void mousePressed() {
  if (mouseX > width-200 && mouseX < width-120 && mouseY < 30) send();
  if (mouseX > width-100 && mouseY < 30) erase();
} 

void mouseDragged() {
  down  = true;
} 

void mouseReleased() {
  down  = false;
} 

void send() {
  // searching for black pixels is needed because when drawing
  // some pixels may have been missed
  down = false;
  for ( i = 0; i <= width; i++) {
    for (j = 0; j <= height; j++) {
      color c = get(i, j);
      if (c == color(0)) {
        str +=  str(height-j)+',';  
        break;
      }
    }
  }
  println ("int[]num={"+str+"};");
  exit();
}

void erase() {
  begin = true;
  stroke(0);
  strokeWeight(2);
  background(255);
  fill(230);
  rect(width-200, 5, 80, 30);
  rect(width-100, 5, 80, 30);
  fill(0);
  text("Save", width-190, 25);
  text("Clear", width-90, 25);
}

table

1 Like