I started making a project where there are goats! Yeah Goats. Currently there is only one function, when I click a goat, it create another goat in a Random position. I realized that there is a pattern of positions:
Here is the code:
public class GameActivity extends Activity {
private int[] arrGoats = new int[5];
private RelativeLayout battlefield;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
battlefield = (RelativeLayout) findViewById(R.id.rel_battlefield);
arrGoats[0] = R.drawable.amarelo;
arrGoats[1] = R.drawable.azul;
arrGoats[2] = R.drawable.branco;
arrGoats[3] = R.drawable.verde;
arrGoats[4] = R.drawable.vermelho;
criarCabra(60, 100);
}
private void criarCabra(float x, float y) {
int cabraImg = arrGoats[new Random().nextInt(4)];
ImageView cabra = new ImageView(this);
cabra.setImageResource(cabraImg);
cabra.setX(x);
cabra.setY(y);
LayoutParams params = (LayoutParams) new LayoutParams(MarginLayoutParams.WRAP_CONTENT,
MarginLayoutParams.WRAP_CONTENT);
params.width = 150;
params.height = 120;
cabra.setLayoutParams(params);
cabra.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
criarCabra(new Random().nextInt(2000), new Random().nextInt(1000));
}
});
battlefield.addView(cabra);
}
}
I would like to know why this pattern is being created although I'm using Random().NextInt()
to define goats positions.
Am I crazy?
A random sequence of events, symbols or steps often has no order and does not follow an intelligible pattern or combination. Individual random events are, by definition, unpredictable, but if the probability distribution is known, the frequency of different outcomes over repeated events (or "trials") is predictable.
But good random number generators don't have any clear pattern to their output, making finding which page of their codebook they correspond to very difficult.) There is no limit to the size of the codebook that algorithmic random number generation can support.
Rather than predictably rounding up or down in a repeating pattern, it is possible to round up or down in a random pattern. Approximately 175 graves have been identified at the cemetery, of which 125 are in the western half, in an apparently random pattern.
Apophenia refers to the human tendency to see patterns and meaning in random information. The term was coined in 1958 by German neurologist Klaus Conrad, who was studying the “unmotivated seeing of connections” in patients with schizophrenia. Statisticians refer to apophenia as patternicity or a “type I error.”
First, you're creating a new Random
object each time. In Android, the initial seed is derived from current time and the identity hash code:
public Random() {
// Note: Using identityHashCode() to be hermetic wrt subclasses.
setSeed(System.currentTimeMillis() + System.identityHashCode(this));
}
For two objects created in sequence, the identity hash codes are close to each other. On my Android KitKat Dalvik VM, I get identity hash codes that differ only by 32.
The currentTimeMillis()
does not provide much difference to the seeds either.
The random itself is a linear congruential generator of the form
random[i+1] = a * random[i] + b (mod c)
where random[0]
is the seed and a
, b
and c
are parameters.
Based on this answer, similar seeds indeed produce similar results in linear congruential generators:
The reason you're seeing similar initial output from nextDouble given similar seeds is that, because the computation of the next integer only involves a multiplication and addition, the magnitude of the next integer is not much affected by differences in the lower bits.
Hence, your two successively generated Random
s with default seeds will produce values that seem to be correlated and make your goats get positioned on a line.
To fix it, use the same Random
object and/or a more random pseudorandom generator than a linear congruential one.
You are creating new instances of Random
with every call to criarCabra
and every invocation of onClick
. Create a single static instance of Random
, then re-use it.
Unless you really know what you're doing and have a very good reason to be doing it, the best practice is to only create one instance of Random
per program and then poll it whenever you need additional values.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With