firstly the language Im writing in is node (javascript) but really Im looking for the computer science behind it, and how to actually do it, not just the code.
Basically what I have is a 2,000 x 2,000 two dimensional array (what I mean by that is that every entry in the 2,000 entry long array has its own 2,000 entries). Inside this array I have values 0, 1, 2 3, etc. They are spaced out different, with different rarities as to how common each appears. What I want to do is generate this array based on a key, idc how long the key/seed is, just a reasonable length that can get the job done. I want the same key to generate the same array if its the same key and a different one if its a different key. Basically take a key and generate longer data from it but for no recognizable patterns to appear in this data.
My thoughts on this is to have a key that is a decimal of some sort I multiply against a bunch of constants to get a location in the array, but tbh I really have no Idea where to start. Essentially its like how minecraft takes a seed and turns it into map and the same seed will again generate an identical map.
Any random number generator (RNG) that can be seeded will give the same series of random values for a given seed & should have no determinable pattern. Unfortunately, the default RND for javascript is not seedable; as per this SE post, you will need to write your own or use a someone else's.
Once you have a seedable RNG, for each entry, first get a random value & then convert the random value into the desired output value. There's a number of different ways to do the conversion; if you only have a few, I would do something like this (assumes random_value is between 0 & 1):
if(rand_value <= 70){
output_value = 1;
}
else if(rand_value <= 90){
output_value = 2;
}
else if(rand_value <= 97){
output_value = 3;
}
else {
output_value = 4
}
This gives a 70%, 20%, 7% & 3% to get a 1,2,3 or 4 respectively; adjust the values as needed. Note: if you have many output values you should edit your question to reflect this, as there are cleaner ways to solve this than a giant if else block.
Related
I am creating a page on Wix where I have a repeater that only brings 3 items from my dataset at a time when clicking on the shuffling button (there are 22 cards in the dataset) that is supposed to shuffle and bring different combinations.
What I expect:
Click on the button, then it brings 3 random cards (that are images of cards in my data set) from a deck of 22 cards.
What is happening:
It is bringing the same few combinations of cards and it is not actually random and some cards never shows up.
Here is my code:
export function button7_click(event) {
// clear any filters in the dataset
$w("#dynamicDataset").setFilter( wixData.filter() );
// get size of collection that is connected to the dataset
let count = $w("#dynamicDataset").getTotalCount();
// get random number using the size as the maximum
let idx = Math.floor(Math.random() * count-1);
// set the current item index of the dataset
$w("#dynamicDataset").setCurrentItemIndex(idx);
}
What can I do to bring really random spread of 3 cards?
JavaScript's Math.random() function is fast, but it has issues. First, it's not seedable, second, its randomness leaves little to be desired. According to the Birthday Paradox, the existence of duplicate values does not mean that they are random. Although there are many ways to change the Random number pattern in JavaScript, here are three different methods adopted by the community:
Seedable Random Number Generator Algorithm: This algorithm allows to generate a seedable random number generator in Javascript that you can tweak to generate a deterministic random number sequence. Browsers do not provide a built-in way to seed Math.random(), so this solution is useful both when you need a completely predictable repeatable pseudo-random sequence and when you need a robust seed that is much more unpredictable than your browser's.
Mersenne Twister: This algorithm compensates for not being allowed to specify an initial value for Math.random().
Alea, PRNG Algorithm: A Pseudo-Random Number Generator (PRNG) is an algorithm for generating a sequence of numbers whose properties approximate those of sequences of random numbers. The Alea package implements this algorithm.
I need help because if I try to write a number that has a whole bunch of zeroes, it will come out as num1Enum2.
ie: for a googol it would write "1E100".
I want it to actually write the number, rather than the shortened form. How would I do this?
Note: I want it to still be an integer rather than a string.
If you "write out" a number, you get a string. Period. "Writing out" means outputting a sequence of characters that represent the number. But that's what a string is: a sequence of characters.
A number like 1E100 is too big to represent as a normal-sized integer, even internally. To get a value that big as an integer, you'll have to use some sort of library to represent big integers. Search around for one. There are several, with names like "BigInt", "BigInteger", "BigNumber", "LongDecimal" and so on. They should all be able to store internally arbitrarily large integer values, and should all provide a way to turn that value into a string, which you can then write out. Pick one you like.
You could try a big number handling library, like big.js. Otherwise, your only solution will be to split your big numbers into arrays and write your own math functions to manipulate them -- something like this function to treat an array as an integer and increment it:
var longVal=[0];
// inherits global array longVal[]
// increments each element from right to left
function inc() {
for (var i=longVal.length - 1; i>=0; i--) {
if (++longVal[i] == 10) {
longVal[i] = 0;
if (!i) {
longVal.splice(0, 0, 0);
i++;
}
continue;
}
else break;
}
}
I think if you exceed the length limit of your array, you could probably change the if (++longVal[i] == 10) line to something like if (++longval[i] == 1000000000) for great justice, but you'd have to left pad each array element except the first with zeros to make it ten digits. I haven't tested that though. My answer is the concept, rather than the implementation.
I am creating a game in Unity. I'm in the planning stage of it right now, but I'm trying to work out a problem I've come to. The game involves randomly selected objects from three different categories falling and the player has to catch the particular objects in particular bins.
So here's what needs to happen:
One or two of the arrays must be randomly chosen, one or two of the objects within that particular array must be chosen, no more than four objects can fall at once, the different objects must fall from different places and fall at different times.
Now I have a clip of code that I got from another project I did that's written in JavaScript (which is what I've been using, but I could also do it in Boo or C++) that solves part of the last point. It chooses a random location along the x access and then has the object fall until y=0, and then it resets.
function Update()
{
transform.position.y -= 50 * Time.deltaTime;
if(transform.position.y < 0)
{
transform.position.y = 50;
transform.position.x = Random.Range(0,60);
transform.position.z = -16;
}
}
I'm going to rewrite part of it to say that it will reset after it hits a particular collider, yields for a short time period, and find then a new random and drop that instead. But what I'm having problems with is the actual randomizing of the objects. I have six objects in each of the three arrays, and I've looked for codes where something is chosen from an array by numerical value, but nothing about randomly choosing one of the arrays and then choosing something within the random array. Neither have I found anything about the random selection in JavaScript, Boo, or C++.
Any information on this code would be helpful, thanks in advance!
To select one object at random from one of three arrays at random, you better work with an array of array. You then will need to generate two random numbers and store them as indexes to the array of arrays.
so instead of three different arrays, initialize a single array
var a = [];
a.push([1,2,3]);
a.push([10,20]);
a.push([100,200,300,400]);
and then
var i = Math.floor(Math.random()*a.length);
var j = Math.floor(Math.random()*a[i].length);
var o = a[i][j];
I’m having problems generating normally distributed random numbers (mu=0 sigma=1)
using JavaScript.
I’ve tried Box-Muller's method and ziggurat, but the mean of the generated series of numbers comes out as 0.0015 or -0.0018 — very far from zero!! Over 500,000 randomly generated numbers this is a big issue. It should be close to zero, something like 0.000000000001.
I cannot figure out whether it’s a method problem, or whether JavaScript’s built-in Math.random() generates not exactly uniformly distributed numbers.
Has someone found similar problems?
Here you can find the ziggurat function:
http://www.filosophy.org/post/35/normaldistributed_random_values_in_javascript_using_the_ziggurat_algorithm/
And below is the code for the Box-Muller:
function rnd_bmt() {
var x = 0, y = 0, rds, c;
// Get two random numbers from -1 to 1.
// If the radius is zero or greater than 1, throw them out and pick two
// new ones. Rejection sampling throws away about 20% of the pairs.
do {
x = Math.random()*2-1;
y = Math.random()*2-1;
rds = x*x + y*y;
}
while (rds === 0 || rds > 1)
// This magic is the Box-Muller Transform
c = Math.sqrt(-2*Math.log(rds)/rds);
// It always creates a pair of numbers. I'll return them in an array.
// This function is quite efficient so don't be afraid to throw one away
// if you don't need both.
return [x*c, y*c];
}
If you generate n independent normal random variables, the standard deviation of the mean will be sigma / sqrt(n).
In your case n = 500000 and sigma = 1 so the standard error of the mean is approximately 1 / 707 = 0.0014. The 95% confidence interval, given 0 mean, would be around twice this or (-0.0028, 0.0028). Your sample means are well within this range.
Your expectation of obtaining 0.000000000001 (1e-12) is not mathematically grounded. To get within that range of accuracy, you would need to generate about 10^24 samples. At 10,000 samples per second that would still take 3 quadrillon years to do...this is precisely why it's good to avoid computing things by simulation if possible.
On the other hand, your algorithm does seem to be implemented correctly :)
Is this correct? using - http://en.wikipedia.org/wiki/Binomial_probability
Looks like values are from .0000000000000000 to .9999999999999999
Probability of happening twice = p^2 = (1/9999999999999999)^2 = 1.0 e-32
I think I am missing something here?
Also, how does being a pseudo random number generator change this calculation?
Thank You.
In an ideal world Math.random() would be absolutely random, with one output being completely independent from another, which (assuming p=the probability of any given number being produced) results in a probably of p^2 for any value being repeated immediately after another (as others have already said).
In practice people want Math.random to be fast which means pseudo-random number generators are used by the engines. There are many different kinds of PRNG but the most basic is a linear congruential generator, which is basically a function along the lines of:
s(n + 1) = some_prime * s(n) + some_value mod some_other_prime
If such a generator is used then you won't see a value repeated until you've called random() some_other_prime times. You're guaranteed of that.
Relatively recently however it's become apparent that this kind of behaviour (coupled with seeding the PRNGs with the current time) could be used for some forms tracking have led to browsers doing a number of things that mean you can't assume anything about subsequent random() calls.
I think the probability of getting two numbers in a row is 1 divided by the range of the generator, assuming that it has a good distribution.
The reason for this is that the first number can be anything, and the second number needs to just be that number again, which means we don't care about the first number at all. The probability of getting the same number twice in a row is the same as the probability of getting any particular number once.
Getting some particular number twice in a row, e.g. two 0.5s in a row, would be p^2; however, if you just care about any number twice in a row, it's just p.
If the numbers were truly random, you'd expect them, indeed, to appear with probability 1/p, so twice that would be 1/p^2.
The value for p is not exactly the one you have though, because the numbers are being represented internally as binary. Figure out how many bits of mantissa the numbers have in javascript and use that for your combinatoric count.
The "pseudorandom" part is more interesting, because the properties of pseudorandom number generators vary. Knuth does some lovely work with that in Seminumerical Algorithms, but basically most usual PN generators have at least some spectral distributiuon. Cryptograp0hic PN generators are generally stronger.
Update: The amount of time shouldn't be significant. Whether it's a millisecond or a year, as long as you don't update the state The probabilities will stay the same.
The probability that you would get 2 given numbers is (1/p)^2, but the probability that you get 2 of same numbers (any) is 1/p. That is because the first number can be anything, and the second just needs to match that.
You can kind of find out, just let it run a few days :)
var last = 0.1;
var count = 0 | 0;
function rand(){
++count;
var num = Math.random();
if(num === last){
console.log('count: '+count+' num: '+num);
}
last = num;
}
while(true) rand();