Im implementing 2 algorithms for the TSP which uses a class which includes the routes, their cost, etc. At the minute it uses random values which is fine, although I now need to compare the algorithms so to make this fair I need to make the inputs the same (which is obviously unlikely to happen when using random inputs!) The issue im having is I dont know how to change it from random values to inserting pre-determined values into the 2D array, not just that but I also dont know how to calculate the costs of these values.
Randomly generates node values:
Random rand = new Random();
for (int i=0; i<nodes; i++) {
for (int j=i; j<nodes; j++) {
if (i == j)
Matrix[i][j] = 0;
else {
Matrix[i][j] = rand.nextInt(max_distance);
Matrix[j][i] = Matrix[i][j];
}
}
}
Im assuming for the above a declare a matrix of say [4][4] and then int matrix [][] = insert values ?
I do not help with some other sections of this class but I think I need to make sure this part is right before asking anymore!
Thanks a lot in advance!
you can do initialization of 2D array like this:
double matrix[][] = { { v1, v2, ..., vn }, { x1, x2, ..., xn }, ..., { y1, y2, ..., yn } };
where each inner {} represents the outter (first) index and each inner element represents the innermost (second) intex.
Example: to acess element x1 you do this:
matrix[1][0];
This is the answer that you asked for, but I still think that it's better to use the same set of random values for both algorithms, Jon Taylor showed a good way for doing that. The code to set the seed looks like this:
int seed = INTEGER_VALUE;
Random rand = new Random(seed);
this way you will ever get the same set of values.
You could set a seed instead for each random number generator therefore guaranteeing that for each implementation you test, the same sequence of pseudo-random numbers is being created.
This would save the effort of manually entering lots of values.
Edit to show seed method:
Random r = new Random(56);
Every time r is created with the seed of 56 it will produce the exact same sequence of random numbers. Without a seed I believe the seed is defaulted to the system time (giving the illusion of truly random numbers).
Related
I was having some problem to come out with a solution for a problem, I am currently still in the thought process. So basically the problem is to random generate numbers between 0 to 12, and get the two numbers to perform multiplication within a time frame.
However, the solution provided must guaranteed that the all 169 random generated number pairs must be shown eventually, so cannot just randomly select a number. I was thinking adding a weight to random selected number helps in this case? Or there is better approach for this?
Thanks!
What this boils down to: you don't really want the number pairs to be random, because a random value means that your next value does not depend on any previous value.
Instead, you want 169 known number pairs to come up, each only once, but you want the order of them to be random.
As if these number pairs were printed in playing cards, and you were shuffling the playing cards.
And Java has a nice method for that: Collections.shuffle acts like a professional dealer who shuffles a deck of playing cards.
You want an approach where you first generate all the playing cards, and then shuffle them. Something like this:
List<Integer[]> l = new ArrayList<>();
for (int x = 0; x <= 12; x++) {
for (int y = 0; y <= 12; y++) {
l.add(new Integer[] {x, y});
}
}
Collections.shuffle(l);
I'm trying to put a certain amount of integers into an array in random spots without putting them in the same place.
My combine method concatenates two given integers and returns the Int.
Places is an arrayList to keep the locations of the integers already put into the array.
The random method returns a random integer in between the two given ints.
The combine method works and so does the random method, but I'm not sure why it isn't working.
public void fillOne(int b)
{
for(int x = 0; x < b; x++)
{
int kachow = random(0, 5);
int kachigga = random(0, 5);
int skrrt = combine(kachow, kachigga);
if(notInArray(skrrt))
{
locations[kachow][kachigga] = 1;
places.add(skrrt);
}
}
}
You haven't really explained what isn't working. But an obvious flaw in your algorithm is that it isn't guaranteed to set b elements to 1. If your algorithm generates a duplicate position then it will set fewer than b elements.
Your logic for storing the combined positions is overly complex. One solution would be to reverse the logic: generate a single integer representing both dimensions then divide it into two when you are setting the location. That makes the checks a lot simpler.
For example, if your array is 5x5:
Set<Integer> positions = new HashSet<>();
while (positions.size() < n)
positions.add(random.nextInt(25));
for (int p: positions)
locations[p/5][p%5] = 1;
Because positions is a set it automatically excludes duplicates which means the code will keep adding random positions until their are n distinct positions in the set.
Even simpler, if you are using Java 8:
random.ints(0, 25)
.distinct().limit(n)
.forEach(p -> locations[p/5][p%5] = 1);
I have two integers, let them be
int a = 35:
int b = 70;
I want to pick one of them randomly at runtime and assign to another variable. I.e.
int c = a or b:
One of the ways that come into my mind is to create an array with these two integers and find a random integer between 0 and 1 and use it as the index of the array to get the number..
Or randomize boolean and use it in if-else.
My question is that is there a better and more efficient way to achieve this? I.e. pick a number from two previously defined integers?
Is there a specific reason you are asking for a more efficient solution? Unless this functionality sits in a very tight inner loop somewhere (e.g. in a ray tracer), you might be trying to prematurely optimize your code.
If you would like to avoid the array, and if you don't like the "bloat" of an if-statement, you can use the ternary choice operator to pick between the two:
int a = 35;
int b = 70;
int c = random.nextBoolean() ? a : b;
where random is an instance of java.util.Random. You can store this instance as a final static field in your class to reuse it.
If you don't require true randomness, but just want to switch between the two numbers in each invocation of the given block of code, you can get away with just storing a boolean and toggling it:
...
int c = toggle ? a : b;
toggle = !toggle;
Since I can't comment on other answers, I'd like to point out an issue with some of the other answers that suggest generating a random integer in a bigger range and making a decision based on whether the result is odd or even, or if it's lower or greater than the middle value. This is in effect the exact same thing as generating a random integer between 0 and 1, except overly complicated. The nextInt(n) method uses the modulo operator on a randomly generated integer between -2^31 and (2^31)-1, which is essentially what you will be doing in the end anyway, just with n = 2.
If you are using the standard library methods like Collections.shuffle(), you will again be overcomplicating things, because the standard library uses the random number generator of the standard library.
Note that all of the suggestions (so far) are less efficient than my simple nextBoolean() suggestion, because they require unnecessary method calls and arithmetic.
Another way to do this is, store the numbers into a list, shuffle, and take the first element.
ArrayList<Integer> numbers=new ArrayList<Integer>();
numbers.add(35);
numbers.add(70);
Collections.shuffle(numbers);
numbers.get(0);
In my opinion, main problem here is entropy for two numbers rather than making use of that entropy. Indexed array or boolean are essentially the same thing. What else you can do (and, hopefully, it will be more random) is to make Java give you a random number between limits say 0 to 100. Now, if the chosen random number is odd, you pick int c = a. Pick b otherwise. I could be wrong, but picking random between 0 to 100 seems more random as compared to picking random between two numbers.
You can simply use secure random generator(java.security.SecureRandom ).
try {
r = SecureRandom.getInstance("SHA1PRNG");
boolean b1 = r.nextBoolean();
if (b1) {
c = a;
} else {
c = b;
}
} catch (NoSuchAlgorithmException nsae) {
// Process the exception in some way or the other
}
Refer this link for more information
Randomize an integer between 1 and 10, if it's more than 5 then take the value of b other wise go with a. As far as I know there are no other ways to select from integers.
int a=1;
int b=2;
int get = new Random().nextBoolean()? a : b;
I am trying to generate random integers within a range to sample a percentile of that range. For example: for range 1 to 100 I would like to select a random sample of 20%. This would result in 20 integers randomly selected for 100.
This is to solve an extremely complex issue and I will post solutions once I get this and a few bugs worked out. I have not used many math packages in java so I appreciate your assistance.
Thanks!
Put all numbers in a arraylist, then shuffle it. Take only the 20 first element of the arraylist:
ArrayList<Integer> randomNumbers = new ArrayList<Integer>();
for(int i = 0; i < 100; i++){
randomNumbers.add((int)(Math.random() * 100 + 1));
}
Collections.shuffle(randomNumbers);
//Then the first 20 elements are your sample
If you want 20 random integers between 1 and one hundred, use Math.random() to generate a value between 0 and 0.999... Then, manipulate this value to fit your range.
int[] random = new int[20];
for(int i =0; i< random.length;i++)
{
random[i] = (int)(Math.random()*100+1);
}
When you multiply Math.random() by 100, you get a value between 0 and 99.999... To this number you add 1, yielding a value between 1.0 and 100.0. Then, I typecasted the number to an integer by using the (int) typecast. This gives a number between 1 and 100 inclusive. Then, store the values into an array.
If you are willing to go with Java 8, you could use some features of lambdas. Presuming that you aren't keeping 20% of petabytes of data, you could do something like this (number is the number of integers in the range to get) it isn't efficient in the slightest, but it works, and is fun if you'd like to do some Java 8. But if this is performance critical, I wouldn't recommend it:
public ArrayList<Integer> sampler(int min, int max, int number){
Random random = new Random();
ArrayList<Integer> generated = new ArrayList<Integer>();
IntStream ints = random.ints(min,max);
Iterator<Integer> it = ints.iterator();
for(int i = 0; i < number; i++){
int k = it.next();
while(generated.contains(k)){
k = it.next();
}
generated.add(k);
}
ints.close();
return generated;
}
If you really need to scale to petabytes of data, you're going to need a solution that doesn't require keeping all your numbers in memory. Even a bit-set, which would compress your numbers to 1 byte per 8 integers, wouldn't fit in memory.
Since you didn't mention the numbers had to be shuffled (just random), you can start counting and randomly decide whether to keep each number or not. Then stream your result to a file or wherever you need it.
Start with this:
long range = 100;
float percentile = 0.20f;
Random rnd = new Random();
for (long i=1; i < range; i++) {
if (rnd.nextFloat() < percentile) {
System.out.println(i);
}
}
You will get about 20 percent of the numbers from 1 to 100, with no duplicates.
As the range goes up, the accuracy will too, so you really wouldn't need any special logic for large data sets.
If an exact number is needed, you would need special logic for smaller data sets, but that's pretty easy to solve using other methods posted here (although I'd still recommend a bit set).
I want to generate a file containing timestamps (integers between 0 and a bound value x, in increasing order) which represents arrivals of an event.
The "Event arrival rate" should be "normal distributed" which means, somehow in the "middle" of the dataset the rate of arrivals should be more frequently as at the beginning and the end.
How can i generate such a list of values using java?
regards
I agree with greedybuddha that a Gaussian function is what you want here, but you also stated that you want your events to be ordered - Random.nextGaussian() won't give you that, it will give you random numbers that are normally distributed. Instead, use the gaussian function to calculate the frequency of events at each point in time:
for (int t = 0; t < max; t++)
{
f = Math.exp(-Math.pow(t - CENTER, 2.0) / (2.0 * Math.pow(WIDTH, 2.0)));
for (int j = 0; j < f; j++)
{
writeEvent(t);
}
}
CENTER is where you want the "peak" of the curve to be (probably max/2), and WIDTH is a parameter that controls the spread of the distribution.
Java has a Random class and one of it's methods is a nextGaussian which will give you a normal distribution from 0-1.0 (Gaussian Distribution and Normal Distribution are synonyms).
From there you just need to multiply that by your range to get a value from that range.
Random random = new Random();
public int nextNormalTime(int upperTimeBound){
return (int)(random.nextGaussian()*upperTimeBound);
}
If you want to create an ordered list of these, you can just add the times into a list and sort, or into something like a PriorityQueue.
List<Integer> list = new ArrayList<Integer>(nTimes);
for (int i=0;i<nTimes;i++){
list.add(nextNormalTime(upperTimeBound));
}
Collections.sort(list);