There is a function noiseSeed(int) to set the seed for a program, but is there any way to print the seed of a program when it begins?
I am making generative art sketches and it would be more convenient to store just a seed number for a result than an entire image.
You can't get the default random seed value.
Check out Processing's source code (specifically the random() and randomSeed() functions) to see that Processing uses an instance of the Random class to generate random numbers. That class does not have a public way to access its seed value, and even if it did, the internalRandom used by Processing isn't accessible to you anyway.
What you can do is create your own seed value and then store that in your own variable. Something like this:
long seed;
void setup(){
seed = (long)random(1000);
randomSeed(seed);
println("Seed value: " + seed);
}
How you come up with that seed is up to you. Here I'm generating a random seed between 0 and 1000, but in real life it can be any long value.
You could then also input this from the user in order to have repeatable random behavior based on the input value.
Related
I have just jumped in Solana on-chain program.
I am going to make coin game which judge frontside or backside.
I tried to use std:: rand and get_random crate but they don't work.
If you have experience about it, please let me know.
I use anchor for Solana on-chain program.
unfortunately, The random generator doesn't work on-chain.
if you want some randoms, you should get it from outside the chain.
why?
assume you making randoms using block hash or something similar, so users can exploit that by inserting an instruction or values that checks for favorable outcomes and even worse, forcing it to roll back if it's not satisfactory.
so what should we do?
try to use oracles like chainlink vrf(verifiable random function)
simulate oracle vrf services:
make transaction on-chain that your server listens to it. if this transaction
happened, make random number off-chain and callback it from your server.
anchor use randoms like this
use rand::rngs::OsRng;
.
.
.
let dummy_a = Keypair::generate(&mut OsRng);
so, if you require randomness for UUID-like behavior you can use a mechanism like the above from the anchor code repository but if your case is game logic like a dice roll, you need oracles or simulate that.
UPDATE 11/10/2022
As we know, the Metaplex candy machine tool uses randoms to select the next item to mint.
see this code snippet:
// (2) selecting an item to mint
let recent_slothashes = &ctx.accounts.recent_slothashes;
let data = recent_slothashes.data.borrow();
let most_recent = array_ref![data, 12, 8];
let clock = Clock::get()?;
// seed for the random number is a combination of the slot_hash - timestamp
let seed = u64::from_le_bytes(*most_recent).saturating_sub(clock.unix_timestamp as u64);
let remainder: usize = seed
.checked_rem(candy_machine.data.items_available - candy_machine.items_redeemed)
.ok_or(CandyError::NumericalOverflowError)? as usize;
let config_line = get_config_line(candy_machine, remainder, candy_machine.items_redeemed)?;
candy_machine.items_redeemed = candy_machine
.items_redeemed
.checked_add(1)
.ok_or(CandyError::NumericalOverflowError)?;
The idea is you can get blockhash and clock from Solana network as random input seeds to create the next random number.
another code snippet which will be good point to start creating randoms:
//convert blockhash to random seed string
let recent_blockhash_data = recent_blockhashes.data.borrow();
let most_recent = array_ref![recent_blockhash_data, 0, 16];
let some_numbers = u128::from_le_bytes(*most_recent);
let blockhash_random_seed: String = (some_numbers).to_string();
in the above code, we use recent blockhash and convert it to hex(as string). you can select each part of this hexadecimal hash string and use it as random value.
In the end, this is important to know that blockhash is deprecated now and Metaplex use slothash but if you look closer you can see they still use blockhash and just use the name of the variable as slothash.
cheers
I want to generate a different output of the same code every time I run it as it has random values assigned to some variables. Is there a way to do that, for example seeding using time as in C?
Sample code that has the randomization in it:
class ABC;
rand bit [4 : 0] arr []; // dynamic array
constraint arr_size{
arr.size() >= 2;
arr.size() <= 6;
}
endclass
module constraint_array_randomization();
ABC test_class;
initial begin
test_class = new();
test_class.randomize();
$display("The array has the value = %p ", test_class.arr);
end
endmodule
I this is probably dependent on the tool that is being used. For example xcelium from cadence supports xrun -seed some_seed(Questa has -sv_seed some_seed I think). I am certain all tools support something similar. Look for simulation tool reference/manual/guide/help it may support random seed for every simulation run.
Not sure if this is possible from inside of simulation.
As mentioned in the comments for Questa, -sv_seed random should do the trick.
Usually, having an uncontrolled random seeding at simulation creates repeatability issues. In other words, it would be very difficult to debug a failing case if you do not know the seed. But if you insist, then read the following.
You can mimic the 'c' way of randomizing with time. However, there is no good way in verilog to access system time. Therfore, there is no good way to do time based seeding from within the program.
However as always, there is a work-around available. For example, one can use the $system call to get the system time (is system-dependent). Then the srandom function can be used to set the seed. The following (linux-based) example might work for you (or you can tune it up for your system).
Here the time is provided as unix-time by the date +'%s' command. It writes it into a file and then reads from it as 'int' using $fopen/$fscan.
module constraint_array_randomization();
ABC test_class;
int today ;
initial begin
// get system time
$system("date +'%s' > date_file"); // write date into a file
fh = $fopen("date_file", "r");
void'($fscanf(fh, "%d", today)); // cast to void to avoid warnings
$fclose(fh);
$system("rm -f date_file"); // remove the file
$display("time = %d", today);
test_class = new();
test_class.srandom(today); // seed it
test_class.randomize();
$display("The array has the value = %p ", test_class.arr);
end
endmodule
While using a random number generator (RNG) with a given seed several times (ie. each time calling setSeed() with the same seed to start over), I have encountered some deviation in the sequence of numbers generated on each pass. After banging my head against the wall a few times I found the reason to be this:
box2d's World.createBody() calls LongMap.put(), which calls LongMap.push(), which calls MathUtils.random() inside a while loop.
To my knowledge particle effects call MathUtils.random() too.
So how can I trust a sequence of numbers to always repeat itself if LibGDX internally uses the same static RNG instance and therefor could mess up the sequence?
How am I supposed to know exactly where and when MathUtils.random() gets called outside my code?
As noted by #Peter R, one can create one's own RNG which guarantees nothing would interfere with the sequence of numbers.
Either Java's Random can be used:
import java.util.Random;
private Random random = new Random();
or RandomXS128 that is used by MathUtils (which extends Java's Random but is faster):
import com.badlogic.gdx.math.RandomXS128;
private Random random = new RandomXS128();
The convenient wrapper methods (random() signatures) in MathUtils can be used too (copied into one's own class) as per needed, whether static or not. eg:
/** Returns a random number between start (inclusive) and end (inclusive). */
public int random (int start, int end) {
return start + random.nextInt(end - start + 1);
}
/** Returns a random number between start (inclusive) and end (exclusive). */
public float random (float start, float end) {
return start + random.nextFloat() * (end - start);
}
For myself I'm still befuddled as to why MathUtils provides a shared RNG to be used both internally and externally, which makes using it with a seed unsafe, and with no mention of that in the comments.
But the above workaround should be satisfactory to anyone who is not as petty as I am.
I am relatively new to Modelica (Dymola-environment) and I am getting very desperate/upset that I cannot solve such a simple problem as a random number generation in Modelica and I hope that you can help me out.
The simple function random produces a random number between 0 and 1 with an input seed seedIn[3] and produces the output seed seedOut[3] for the next time step or event. The call
(z,seedOut) = random(seedIn);
works perfectly fine.
The problem is that I cannot find a way in Modelica to compute this assignment over time by using the seedOut[3] as the next seedIn[3], which is very frustrating.
My simple program looks like this:
*model Randomgenerator
Real z;
Integer seedIn[3]( start={1,23,131},fixed=true), seedOut[3];
equation
(z,seedOut) = random(seedIn);
algorithm
seedIn := seedOut;
end Randomgenerator;*
I have tried nearly all possibilities with algorithm assignments, initial conditions and equations but none of them works. I just simply want to use seedOut in the next time step. One problem seems to be that when entering into the algorithm section, neither the initial conditions nor the values from the equation section are used.
Using the 'sample' and 'reinit' functions the code below will calculate a new random number at the frequency specified in 'sample'. Note the way of defining the "start value" of seedIn.
model Randomgenerator
Real seedIn[3] = {1,23,131};
Real z;
Real[3] seedOut;
equation
(z,seedOut) = random(seedIn);
when sample(1,1) then
reinit(seedIn,pre(seedOut));
end when;
end Randomgenerator;
The 'pre' function allows the use of the previous value of the variable. If this was not used, the output 'z' would have returned a constant value. Two things regarding the 'reinint' function, it requires use of 'when' and requires 'Real' variables/expressions hence seedIn and seedOut are now defined as 'Real'.
The simple "random" generator I used was:
function random
input Real[3] seedIn;
output Real z;
output Real[3] seedOut;
algorithm
seedOut[1] :=seedIn[1] + 1;
seedOut[2] :=seedIn[2] + 5;
seedOut[3] :=seedIn[3] + 10;
z :=(0.1*seedIn[1] + 0.2*seedIn[2] + 0.3*seedIn[3])/(0.5*sum(seedIn));
end random;
Surely there are other ways depending on the application to perform this operation. At least this will give you something to start with. Hope it helps.
I have following problem with my function which should return a random numer. When I want to generate a couple of numbers by calling that function, they are exactly the same. How can I fix the problem of returning the same number all the time when I call the function? I need that random to keep in function.
Here is the code:
with Ada.Numerics.discrete_Random
function generate_random_number ( n: in Positive) return Integer is
subtype Rand_Range is Integer range 0 .. n;
package Rand_Int is new Ada.Numerics.Discrete_Random(Rand_Range);
use Rand_Int;
gen : Rand_Int.Generator;
ret_val: Rand_Range;
begin
Rand_Int.Reset(gen);
ret_val := Random(gen);
return ret_val;
end;
The random generator gen should not be local to the function. Currently you are creating it anew on each generate_random_number call, and initialising it, so it's not surprising you always get the same result.
If you make gen - for instance - a global variable, initialised once, then each time you use it you'll get a new random number. (Yes, global variables are bad : but see below)
Unfortunately this does not play particularly well with the semantics of function generate_random_number ( n: in Positive) which can restrict the range of the random number differently each time. The simplest solution is to make gen return any valid integer and use modular arithmetic to return a number in the correct range for each call. This will work but you should be aware that it potentially introduces cryptographic weaknesses, beyond my skills to analyze.
If that is the case you will need a different approach, for example creating a different random generator for each range you need; taking care to seed (reset) them differently otherwise there may again be crypto weaknesses such as correlations between different generators.
Now global variables are poor structure for all the usual reasons in any language. So a much better way is to make it a resource by wrapping it in a package.
package RandGen is
function generate_random_number ( n: in Positive) return Positive;
end RandGen;
And that is all the client needs to see. The package is implemented as follows:
with Ada.Numerics.discrete_Random;
package body RandGen is
subtype Rand_Range is Positive;
package Rand_Int is new Ada.Numerics.Discrete_Random(Rand_Range);
gen : Rand_Int.Generator;
function generate_random_number ( n: in Positive) return Integer is
begin
return Rand_Int.Random(gen) mod n; -- or mod n+1 to include the end value
end generate_random_number;
-- package initialisation part
begin
Rand_Int.Reset(gen);
end RandGen;
EDIT : Jacob's suggestion of rejecting out-of-range values is better but inefficient if n is much smaller than the generator range. One solution might be to create several generators and let the generate_random_number function choose the one which covers 0 .. N with least waste.
The Random procedure with only one parameter is supposed to initiate the random number generator with a "time-dependent state". However, if it is called more than once rapidly in succession, it is very likely that the "time" that the program uses will be the same each time, since the program is likely to run faster than the clock resolution. (Try your test with something like delay 0.5 in between the two uses of generate_random_number; most likely you will get two different results.)
In any event, the intended use of a random number generator is to use Reset on it once to set the seed, and then generate a sequence of random numbers starting with the seed. By doing this, you can also use the same seed every time in order to get a duplicatable sequence of random numbers, for testing; or you can use a time-dependent seed. However, resetting the random number generator every time you want a random number is not the normal or recommended way of using RNG's. Therefore, you need to move the Reset call out of generate_random_number. Unfortunately, this also means that you have to use the same generator even if the n parameter will be different on every call, which means you may be forced to use Float_Random instead of Discrete_Random.
P.S. Looking into it further, I found this in G.2.5: "Two different calls to the time-dependent Reset procedure shall reset the generator to different states, provided that the calls are separated in time by at least one second and not more than fifty years." [Emphasis mine.] I'm sure that when you tried it, the calls were less than one second apart.
Assuming that the upper limit can be determined when you start the program:
Package Random (specification):
with Generic_Random;
with Upper_Limit_Function;
package Random is new Generic_Random (Upper_Limit => Upper_Limit_Function);
Generic package Generic_Random (specification):
generic
Upper_Limit : Positive;
package Generic_Random is
subtype Values is Natural range 0 .. Upper_Limit;
function Value return Values;
end Generic_Random;
Generic package Generic_Random (body):
with Ada.Numerics.Discrete_Random;
package body Generic_Random is
package Random is new Ada.Numerics.Discrete_Random (Values);
Source : Random.Generator;
function Value return Values is
begin
return Random.Random (Source);
end Value;
begin
Random.Reset (Source);
end Generic_Random;