This question already has answers here:
Picking a random element from a set
(34 answers)
Closed 2 years ago.
I'm working on a problem in which I need to pull a random String from a keySet. Just wondering if anyone can give me some direction here. I'm pretty lost on it. I've found quite a few ways to do it if I were using an int, but not a String. For example I want to quiz a user on States and their Capitals, and to pull out a random Key from the keySet for the question.
Here's the set:
Set<String> states = stateCapitals.keySet();
Set is not the best data structure for random indexing.
Better convert to a List and use a random generator to select an index. If you really need to stay with a Set, you can generate a random index n and iterate through the Set, stop at the nth element. For selecting multiple elements, there is no benefit of working with a List. Any iterable would be fine.
The key idea is to dynamically adjust selection probability so you can choose m (out of sizeof(Set)): In the easiest example of m=1, select 1st element with probability of 1/N, if you didn't select it, select 2nd element with probability 1/(N-1)..and so on.
Use conditional probability to show all elements are selected under a fair chance 1/N.
A keySet similar to HashSet is un-ordered and thus makes no guarantee to the order of the element in the set. So pulling a random string might not be as effective thing to do from a set.
Convert the set into arrays or list and then performing random string gets might be good solution.
String ranKey = map.keySet().toArray()[new Random().nextInt(map.keySet().size())].toString();
Try this code
onPress: function () {
debugger;
var textArray = ['Pritesh', 'Nimesh', 'Harshil', 'Ravi', 'Amit', 'Brijesh'];
var randomNumber = Math.floor(Math.random() * textArray.length);
for (var i = 0; i < textArray.length; i++) {
if (i === randomNumber) {
console.log(textArray[i]);
}
}
ArrayList<States> statesList = new ArrayList<>( states );
State x = statesList.get( (int)(statesList.size() * Math.random()) );
The code above will get what you want but this could be inefficient if it's a very large list.
Related
This question already has answers here:
Generating Unique Random Numbers in Java
(21 answers)
Closed 7 years ago.
I'm creating a 50 states study app (To help me for school), and I want each choice of a state to have it's own random option. So I have an Array holding all of the state's. Is there anyway I can select randomly select a variable from this Array then drop the variable I just used (That way it's not used again). But I want It to take the minimum amount of data, because It will be in my game loop. Which is run 60 times per second (60 FPS). Any Ideas? Here is what I'v thought of:
String.valueOf(stateVariables.get(random.nextInt(3))) //It has four variables in it, so three is the max.
But this doesn't stop the variable it selects from being used again. Please Help!
If i understand you right, you are concerned about the performance during your game loop. I have a performant idea in mind. You could create an array with all indices and shuffle it randomely before running the game loop. Safe that array as some subclass of java.util.Queue. Then when the game loop runs you can just remove the first element of that Queue and select it from the array.
As every index is only once in the Queue it will not be reselected and the remove function from a Queue is pretty performant therefore you will not have to worry about that. Only the initialization of that Queue is relatively performance intense, however still in milliseconds.
Not sure if understood your question, but after selecting a array position, you want to exclude it and never be selected again?
If so, you can't delete an array position. What you can do is set this position to null, so when you pick it again, it'll return null and you'll know it have already been selected.
public int getRandom(int i) {
int randomNumber = array[i];
array[i] = null;
return randomNumber;
}
int selectedNumber = getRandom(3);
if (selectedNumber == null)
System.out.println("Number already selected");
else
System.out.println("Number never selected; can be used");
This question already has answers here:
Java generating non-repeating random numbers
(12 answers)
Closed 7 years ago.
not really sure about how to go about this. Been tasked (by a nonprofit organisation) to create an app that takes a maximum number (probably around 100) and then generates a random number in between. Simple enough; I then want it to rule that number out, and generate a new random, rule that out too, and so forth till all possible numbers are eliminated. Basically like a raffle. I know there is probably pages and pages of code to build this, i just need a steer in the right direction of what methods to use to achieve this. I'm studying Java at Uni and this intrigues me. To put it in context, the organisation is having an event where they will draw tickets from a hat to get a prize which has been donated. For some reason a lot of members don't like the idea of using the hat method, and want some way of making a trustworthy number generating method. They draw a ticket from the hat, then they propose they click a button for a random number, which in turn is attached to a prize. Obviously as the prizes are won their numbers must be ruled out. Thanks if anyone can help me!
You can create a list of numbers, and then use Collections.shuffle to randomize the list. After that you can take values from that list from the beginning one by one, to simulate a sequence of distinct random numbers.
int max = 10;
List<Integer> shuffled = new ArrayList<>(max);
for (int i = 0; i < max; ++i) {
shuffled.add(i);
}
Collections.shuffle(shuffled);
System.out.println(shuffled);
I have a really big vector that stores 100000 different values,ranging from 0 to 50000.
They represent the cylinders on a hard disk,and I want to sort this vector according to three different algorithms used for disk scheduling.
So far,I read those 100000 values from a file,store them into a vector and then sort them according to the desired algorithm(FCFS,SCAN,SSTF).The problem is,it takes too long,because I'm doing it in the least creative way possible:
public static Vector<Integer> sortSSTF(Vector<Integer> array){
Vector<Integer> positions = new Vector<Integer>(array);
Vector<Integer> return_array = new Vector<Integer>();
int current_pos = 0,minimum,final_pos;
while(positions.size() > 0){
minimum = 999999;
final_pos = current_pos;
for(int i=0 ; i < positions.size() ; i++){
//do some math
}
}
return_array.add(final_pos);
current_pos = final_pos;
positions.removeElement(final_pos);
}
return return_array;
}
My function takes a vector as a parameter,makes a copy of it,does some math to find the desired element from the copied array and store him in the other array,that should be ordered according to the selected algorithm.But in a array with N elements,it is taking N! iterations to complete,which is way too much,since the code should do that at least 10 times.
My question is, how can I make this sorting more efficient?
Java already has built-in methods to sort a List very quickly; see Collections.sort.
Vector is old and incurs a performance penalty due to its synchronization overhead. Use a List implementation (for example, ArrayList) instead.
That said, based on the content of your question, it sounds like you're instead having difficulty implementing the Shortest Seek Time First algorithm.
See related question Shortest seek time first algorithm using Comparator.
I don't think you can implement the SSTF or SCAN algorithm if you don't also supply the current position of the head as an argument to your sorting method. Assuming the initial value of current_postion is always 0 will just give you a list sorted in ascending order, in which case your method would look like this:
public static List<Integer> sortSSTF(List<Integer> cylinders) {
List<Integer> result = new ArrayList<Integer>(cylinders);
Collections.sort(result);
return result;
}
But that won't necessarily be a correct Shortest Seek Time First ordering if it's ever possible for current_pos > 0 when you first enter the method. Your algorithm will then probably look something like this:
Collections.sort(positions);
find the indices in positions that contain the nextLowest and nextHighest positions relative to current_pos (or currentPos, if following Java naming conventions)
whichever position is closer, remove that position from positions and add it to return_array (If it was nextLowest, also decrement nextLowestIndex. If it was nextHighest, increment nextHighestIndex)
repeat step 3 until positions is empty
return return_array.
Of course, you'll also need to check for nextLowestIndex < 0 and nextHighestIndex >= positions.size() in step 3.
Note that you don't need the for loop inside of your while loop--but you would use that loop in step 2, before you enter the while loop.
This question already has answers here:
Randomly select an item from a list
(5 answers)
Closed 4 years ago.
I am using java.util.LinkedList
Is there any method that helps me with this?
int len = list.size();
Random randomGenerator = new Random();
int randomInt = randomGenerator.nextInt(len);
If you only need one element you can use the Random class to generate a (pseudo) random value (as you wrote in your question):
E element = list.get(new Random().nextInt(list.size()));
Remember LinkedList.get(index) is an O(n) operation, as noted in the comments it's better to use an ArrayList for this purpose.
If you want to shuffle the whole array you can use the Collections api like this:
Collections.shuffle(list);
You can also shuffle the List using Collections.shuffle and pick the first element everytime though this might be a bit expensive computation wise. Just another trick you should be aware of. :-)
final List<String> lst = Arrays.asList("a", "b", "c");
Collections.shuffle(lst);
final String rndStr = lst.get(0);
Get the list length with size(), create a random number between 0 and size-1 and use get(index) to retrieve the element with that index.
If you really need just one element, go with dacwe's solution. If you need several values (e.g. when simulating a card game, bingo etc.) you can use java.util.Collections.shuffle(list);, and call list.remove(0); for every element you need.
Is it possible to do this in Java ? I want to generate a random number such that given a range say for example: between 1 and 70 - everytime the random number is generated it should be excluded from generation results.
so [1,70] rand = 56 (now 56 shouldn't be considered next time)
[1,70] = 63 (now 56,63 should be excluded from generation till my code runs)
This is equivalent to shuffling an array of numbers containing [1..70] and then dealing them out one at a time. Look up "shuffle algorithm" on Google. Here's a link http://www.vogella.de/articles/JavaAlgorithmsShuffle/article.html
I asked the same question here: How can I generate a random number within a range but exclude some?
The general strategy is something like filling an array with 70 values. Just remove the values that you randomly generate as per the link above.
you could populate the range into an array and shuffle the array. This would be inefficient though for very large ranges
Another trivial alternative, using HashMaps to keep track of random numbers.
It is sort of quick and dirty.
HashMap<Integer,Integer> hmRandomNum = new HashMap<Integer,Integer>();
Integer a = < generate random number>
if( hmRandomNum.get(a) == null)
{
hmRandomNum.put(a,a);
}
else
{
// ignore this random number. this was already selected and present in the hashmap.
}
//Iterate depending on how many numbers you want.