Array with 10 different random elements with no duplicate - java

im trying to make an array of 10 different elements with Random(), so basically i have this
public static int[] RandomArray (int xArra[]) throws java.io.IOException {
Random Rand = new Random();
int nal;
for (int i = 0; i < xArra.length; i++) {
nal = Rand.nextInt(11); /*I would like to make this thing work with any
numbers, for example, changing this to 50 or 100.
In an array of 10 elements it should be
impossible to have a duplicate because with
11 it just prints from 1 to 10.
Thats why i put 11 here. */
for ( int j = 0; j < xArra.length; j++) {
if (nal == xArra[j]) {
nal = Rand.nextInt(11);
j=0;
}
}
xArra[i] = nal;
}
return xArra;
}
Basically im storing a random number in nal and I run my array in a second For to check
this random number with the already given ones, and if its equal to any number given in the array it changes it with random again, and runs the For again checking that the new number isnt duplicated, if its not, I stored in xArra[i].
When i run it 3 times, the results look like this:
First run:
8
1
6
4
3
2
10
8
9
7
Second run:
9
3
8
10
7
1
4
5
9
6
Third run:
3
5
2
3
6
7
1
4
10
9
So, as you can see i almost though i had it but it duplicates just 1 number, no 2 or 3, so basically i just want to make this thing work. I just want to print 10 random numbers with no duplicate, no repeats.
Heres my full code:
import java.io.*;
import java.util.*;
public class ArraynoR {
public static void main (String[] args) throws java.io.IOException {
int Array[]= new int [10];
RandomArray(Array);
for(int i=0; i<Array.length; i++){
System.out.println("Array[" + (i + 1) + "]:" + Array[i]);
}
}
public static int[] RandomArray (int xArra[]) throws java.io.IOException... //up
}
Please forgive my bad english, I hope I explained myself.
Thanks!

Instead of storing and searching for duplicates, create an ArrayList containing the numbers in the range of interest. Use Collections.shuffle() to randomize the values, then select however many you want from the shuffled set. Guaranteed to give no duplicates, and much more efficient than a search/reject approach.
ADDENDUM
Perhaps not the prettiest code, but it works and gives the idea...
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
public class ShuffleDemo {
public static int[] RandomArray(int len) {
ArrayList<Integer> al = new ArrayList<Integer>(len);
for(int i = 1; i <= len; ++i) { // initialize the ArrayList with values 1 to len
al.add(i);
}
Collections.shuffle(al); // shuffle to random order
int[] results = new int[len];
// switching return type to ArrayList could eliminate the following loop
for(int i = 0; i < len; ++i) { // copy to array of ints
results[i] = al.get(i); // note: create a subset by reducing
} // the upper bound for this loop
return results;
}
public static void main(String[] args) {
System.out.println(Arrays.toString(RandomArray(10)));
}
}

Set j=-1 when you are resetting for the inner for loop and try it. Then it should work
for ( int j = 0; j < xArra.length; j++) {
if (nal == xArra[j]) {
nal = Rand.nextInt(11);
j=-1;
}
}
At the end of the for loop the loop increments the variable so when you set it to 0, before the next check it becomes 1 due to the internal code of the for loop

you can use the method nextPermutation of the class org.apache.commons.math3.random.RandomDataGenerator (see help here docs) in Apache Math. This method generate random numbers without repetition.

Related

Unable to make array with 25 integers populated with random numbers from 10 to 99. /java [duplicate]

This question already has answers here:
What's the simplest way to print a Java array?
(37 answers)
Array Printing Java
(3 answers)
Closed 2 years ago.
I have to use the math.random to populate my array with 25 random integers between the range 10 and 99. I'm also having problems trying to print the array. Instead of the full array being printed, only the memory location is printed. How to I write the command for it to print? This is how I've written my code and I know there's something wrong with it but just done know how to iron it out.
public class Proj5COMP110
{
public static void main(String args[])
{
System.out.println ("Project 5: Quick Sort");
int i;
int mSample [] = new int[25];
for ( i= 0; i< mSample.length ; i++)
{
mSample[25] = (int)(Math.random ()* (99-10)+10);
}
System.out.print(mSample[25]);
}
}
The problem as already mentioned in comments is that you have to change
mSample[25] = (int)(Math.random ()* (99-10)+10);
to
mSample[i] = (int)(Math.random ()* (99-10)+10);
I would like to prefer below code, which is less erroneous and doesn't have any warning.
public static void main(String[] args) {
int[] mSample = new int[25];
for (int loop = 0; loop < mSample.length; loop++)
mSample[loop] = new Random().nextInt(90) + 10;
for (int element : mSample)
System.out.println(element);
}
You are storing values into wrong index. use mSample[i] instead of mSample[25] to store value at index i.
mSample[i] = (int)(Math.random ()* (99-10)+10);
Also don't forget to change this line: System.out.print(mSample[25]); This will give you an indexOutOfBounds exception. Learn why this exception occurred.
public class Proj5COMP110
{
public static void main(String args[])
{
System.out.println ("Project 5: Quick Sort");
int i;
int mSample [] = new int[25];
for ( i= 0; i< mSample.length ; i++)
{
mSample[i] = (int)(Math.random ()* (99-10)+10);
}
for ( i= 0; i< mSample.length ; i++)
{
System.out.print(mSample[i]);
}
}
}
In an array the index starts from 0, therefore you should be able to store from mSample[1-24], mSample[25] would be out of bounds. When you are trying to print mSample[25], it is printing garbage value and not memory address.

Break large 2D array into multiple smaller 2D array using JAVA

I have a 2D array which consist of image pixels which its size depends on the size of the input image. I need to break it into smaller 9x9 arrays. To give a clearer picture, I try to illustrate the situation:
//The number of rows and columns of the smallerArray will look something like this:
It should copy them from the imagePixels array iterating through each 8 columns, then move on to the next 8 rows.
1st small 2nd small 3rd small and so on..
array: array: array:
012345678 91011121314151617 181920212223242526 ....
0 0 0
1 1 1
2 2 2
3 3 3
4 4 4
5 5 5
6 6 6
7 7 7
8 8 8
Then move on to next 8 rows:
012345678 91011121314151617 181920212223242526 ....
9 9 9
10 10 10
11 11 11
12 12 12
13 13 13
14 14 14
15 15 15
16 16 16
17 17 17
.
.
.
I have done the following code but could not get my logic right. How can I stop the iteration:
Copy up until the 9th column or row, store it in an array, resume copying on the 10th column/row, stop when it reaches 9 column/row after, store it in another array, and keep on doing that till it finishes copying the imagePixels array.
I tried to store the arrays in an ArrayList so it would be easier for me to manipulate and do calculation stuffs with all the smallerArrays.
ArrayList<double[][]> collectionofSmallArrays = new ArrayList();
double[][] imagePixels = new double[1600][1000]; //Lets say this is the size of the image
double[][] smallerArray = new double[9][9];
for(int a = 0; a<smallerArray.length; a++)
{
for(int b =0; b<smallerArray[a].length; b++)
{
for(int c=0; c<imagePixels.length; c++)
{
for(int d=0; d<imagePixels[c].length; d++)
{
smallerArray[a][b] = imagePixels[c][d];
...(code to stop the iteration if it reaches 9, store it in array then resume where it stops with another new array)
collectionofSmallArrays.add(smallerArray);
}
}
}
}
Can anyone work around the code to achieve the expected result? Appreciate it.
You should probably provide more context information. Saying that an array of double values represents pixels sounds dubios. If you are working with images, then you might find solutions on a completely different level of abstraction (I'm thinking about BufferedImage#createSubImage here).
However, to answer the question: You should break the task up into smaller parts. Particularly, it might be easier to implement two methods:
One method that receives an input array, some coordinates, and an output array, and that copies the data from the specified coordinates of the input array to the output array
One method that calls the above mentioned method with the appropriate coordinates to split the whole array into the parts of the desired size.
In pseudocode:
for (each coordinates (9*r,9*c)) {
copy the rectange (9*r,9*c)-(9*r+9,9*c+9) of the input array into an array
A very simple implementation/test is shown in the following example. Note that this could be generalized and improved, but I think it shows the basic idea:
import java.util.ArrayList;
import java.util.List;
public class SubArrayTest
{
public static void main(String[] args)
{
double inputArray[][] = createInputArray(160, 100);
System.out.println("inputArray: "+toString(inputArray));
List<double[][]> subArrays = createSubArrays(inputArray, 9, 9);
for (double subArray[][] : subArrays)
{
System.out.println("subArray:\n"+toString(subArray));
}
}
private static List<double[][]> createSubArrays(
double inputArray[][], int subRows, int subCols)
{
List<double[][]> subArrays = new ArrayList<double[][]>();
for (int r=0; r<inputArray.length; r+=subRows)
{
for (int c=0; c<inputArray[r].length; c+=subCols)
{
double subArray[][] = new double[subRows][subCols];
fillSubArray(inputArray, r, c, subArray);
subArrays.add(subArray);
}
}
return subArrays;
}
private static void fillSubArray(
double[][] inputArray, int r0, int c0, double subArray[][])
{
for (int r=0; r<subArray.length; r++)
{
for (int c=0; c<subArray[r].length; c++)
{
int ir = r0 + r;
int ic = c0 + c;
if (ir < inputArray.length &&
ic < inputArray[ir].length)
{
subArray[r][c] = inputArray[ir][ic];
}
}
}
}
//===Test methods=========================================================
private static double[][] createInputArray(int rows, int cols)
{
double array[][] = new double[rows][cols];
for (int r=0; r<array.length; r++)
{
for (int c=0; c<array[r].length; c++)
{
array[r][c] = r*100+c;
}
}
return array;
}
private static String toString(double array[][])
{
String format = "%7.1f";
StringBuilder sb = new StringBuilder();
for (int r=0; r<array.length; r++)
{
for (int c=0; c<array[r].length; c++)
{
sb.append(String.format(format, array[r][c])+" ");
}
sb.append("\n");
}
return sb.toString();
}
}
Side notes:
You should always declare variables with their interface type. This means that you should not write
ArrayList<String> x = new ArrayList<String>();
but always
List<String> x = new ArrayList<String>();
In the posted code, you seemed to always add the same instance of the sub-array to the list. This means that in the end you would have many instances of the same array in the list, all with the same content. Somewhere in between you have to create a new double[9][9] array.
smallerArray[a][b] = imagePixels[c][d] line looks strange. You reuse same array instance. Your output array list will contain multiple reference to same array.
You cannot reuse smallerArray. Create the instance inside the for loop and store the size in a constant.
I think a map with some corner coordinates as a key would be far better than a list for storing your results.
What happens if the length or width or your image is not divisible by 9?

Level of randomness

my goal is to randomly shuffle an array, (from 0 to 9) but every number has to appear in the array only once. I have got two (working) ideas, but I would like to find out how many times must this random2 method iterate to achieve the same level of randomness in array as in the first method (random1).
import java.util.Random;
class RandomStuff {
static Random r;
final static int iteraction = 10;
public static void main (String[] args) {
r = new Random();
int[] array = new int[10];
random1(array);
random2(array, iteraction);
}
static void random1(int[] array) {
for(int i = 0; i < array.length; i++) pole[i] = -1;
for(int i = 0; i < array.length; i++) {
while(true) {
int y = r.nextInt(10);
if(!find(array, y)) {
array[i] = y;
break;
}
}
}
}
static void random2(int[] array, int iteraction) {
for(int i = 0; i <= iteraction; i++) {
int y1 = r.nextInt(array.length);
int y2 = r.nextInt(array.length);
int p = array[y1];
array[y1] = array[y2];
array[y2] = p;
}
}
static boolean find(int[] array , int value) {
for(int i = 0; i < array.length; i++) {
if(pole[i] == value) return true;
}
return false;
}
}
The first method (random1) works assigning of random numbers and testing, if they are/aren't in the array already. Which seems to be pretty random to me.
The second method (random2) works on swaping two random random values in the array. So the question is, how many times do I have to swap two numbers in the array to achieve the same level of randomness. (or what value shoud the variable iteraction have).
Thanks for any reply.
How about assigning a random number to each element of the array, arrange the random numbers in order and in that order read the element of the array assigned to that random number
0.64342 0
0.95229 1
0.23047 2
0.82793 3
0.19014 4
0.18528 5
0.15684 6
0.99546 7
0.54524 8
0.90612 9
Order
0.15684 6
0.18528 5
0.19014 4
0.23047 2
0.54524 8
0.64342 0
0.82793 3
0.90612 9
0.95229 1
0.99546 7
numbers 0 to 9 now in random order
To answer your original question, "how many times must this random2 method iterate to achieve the same level of randomness in array as in the first method?"
The answer is: it will never achieve the same level of randomness.
For any position that has been swapped, there is an equal chance of it arriving in any position, which means a 10% chance it ends up back where it started.
In each iteration, 2 numbers are swapped (or zero if the number is swapped to its own position). That means there's an 80% chance for any given position to never have been swapped, after 1 iteration. After N iterations, there is still a 0.8^N chance that it was never swapped. If it was swapped, there is a 10% chance it went back where it started. So the probability that any given digit is in its starting position is 10% + 0.8^N. This is always > 10%, so you will never get a perfectly even distribution.
For example, for your choice of 10 iterations, there remains a 10.7% chance for each digit that it never moved, or a total of 19.7% chance it'll be in its starting position. So ten iterations is not even close to enough.

ArrayList is filled with random numbers, weirdly causing foreach to draw from a random index

I'm still fairly new to Java and have recently started dabbling a bit with ArrayList and LinkedList. While programming a simple lottery-algorithm, I have encountered a problem I don't quite understand.
Here's my code:
import java.util.*;
public class Millionaire
{
public static void main(String[] args)
{
ArrayList<Integer> lottery = new ArrayList<Integer>();
Random draw = new Random();
for (int i = 0; i < 6; i++)
{
lottery.add(draw.nextInt(50));
}
for (int m : lottery)
{
System.out.println(lottery.get(m));
}
}
}
Compiling goes without a hitch, but running the program pretty much always causes an OutOfBoundsExeption. It seems that the printing loop tries to use the content of the Arraylist as the indexes it tries to access, so that any entry larger than 6 causes the program to crash. Could anybody help my understand why it does that?
Basically, m is the lottery number, not an index. So if your ArrayList were:
30,11,2,4,8,17
Then your for-loop would first fetch the first value (30), and attempt to get the lottery value at index 30 (causing your exception).
You can simply change your second for-loop to do this:
System.out.println(m);
Alternatively, if you want to get the value at index m, then you should change your for-loop to the following:
int c = lottery.size();
for(int i = 0; i < c; i++) {
System.out.println(lottery.get(i));
}
Bearing that in mind: m in you for loop is the value in ArrayList<Integer>, it is not the index of the List ArrayList<Integer>. m ranges [0, 50). You are trying to generate 6 int random numbers, if the random number is generated greater than 6, then, with such random numbers, it will cause Exception : OutOfBoundsExeption with your for-loop below:
for (int m : lottery)
{
System.out.println(lottery.get(m));
}
There are 2 ways for you to avoid the Exception.
Way#1:
Change
for (int m : lottery)
{
System.out.println(lottery.get(m));
}
To
for (int m : lottery)
{
System.out.println(m);
}
Way#2
Change
for (int m : lottery)
{
System.out.println(lottery.get(m));
}
To
for(int i=0; i < lottery.size();i++)
{
System.out.println(lottery.get(i));
}
That's because the for cycle
for (int m : lottery)
iterates over the values of the lottery array. So the m has 6 random values. You assumed that m will be an index value.
Try this:
public static void main(String[] args) {
ArrayList<Integer> lottery = new ArrayList<Integer>();
Random draw = new Random();
for (int i = 0; i < 6; i++) {
lottery.add(draw.nextInt(50));
System.out.println(lottery.get(i));
}
In your last loop you already have the random integer m. You dont need to to the lottery.get(...) part.

Efficient way of generating all combinations of 12 numbers that add to 100 in Java [duplicate]

This question already has an answer here:
How to iterate through array combinations with constant sum efficiently?
(1 answer)
Closed 9 years ago.
I have 12 products at a blend plant (call them a - l) and need to generate varying percentages of them, the total obviously adding up to 100%.
Something simple such as the code below will work, however it is highly inefficient. Is there a more efficient algorithm?
*Edit: As mentioned below there are just too many possibilities compute, efficiently or not. I will change this to only having a maximum of 5 or the 12 products in a blend and then running it against the number of ways that 5 products can be chosen from the 12 products.
There is Python code that some of you have pointed to that seems to work out the possibilities from the combinations. However my Python is minimal (ie 0%), would one of you be able to explain this in Java terms? I can get the combinations in Java (http://www.cs.colostate.edu/~cs161/Fall12/lecture-codes/Subsets.java)
public class Main {
public static void main(String[] args) throws FileNotFoundException, UnsupportedEncodingException {
for(int a=0;a<=100;a++){
for(int b=0;b<=100;b++){
for(int c=0;c<=100;c++){
for(int d=0;d<=100;d++){
for(int e=0;e<=100;e++){
for(int f=0;f<=100;f++){
for(int g=0;g<=100;g++){
for(int h=0;h<=100;h++){
for(int i=0;i<=100;i++){
for(int j=0;j<=100;j++){
for(int k=0;k<=100;k++){
for(int l=0;l<=100;l++){
if(a+b+c+d+e+f+g+h+i+j+k+l==100)
{
System.out.println(a+" "+b+" "+c+" "+d+" "+e+" "+f+" "+g+" "+h+" "+i+" "+j+" "+k+" "+l);
}}}}}}}}}}}}}
}
}
Why make it so difficult. Think simple way.
To explain the scenario simpler, consider 5 numbers to be generated randomly. Pseudo-code should be something like below.
Generate 5 random number, R1, R2 ... R5
total = sum of those 5 random number.
For all item to produce
produce1 = R1/total; // produce[i] = R[i]/total;
Please, don't use nested for loops that deep! Use recursion instead:
public static void main(String[] args) {
int N = 12;
int goal = 100;
generate(N, 0, goal, new int[N]);
}
public static void generate(int i, int sum, int goal, int[] result) {
if (i == 1) {
// one number to go, so make it fit
result[0] = goal - sum;
System.out.println(Arrays.toString(result));
} else {
// try all possible values for this step
for (int j = 0; j < goal - sum; j++) {
// set next number of the result
result[i-1] = j;
// go to next step
generate(i-1, sum + j , goal, result);
}
}
}
Note that I only tested this for N = 3 and goal = 5. It absolutely makes no sense to try generating all these possibilities (and would take forever to compute).
Let's take your comment that you can only have 5 elements in a combination, and the other 7 are 0%. Try this:
for (i = 0; i < (1<<12); ++i) {
if (count_number_of_1s(i) != 5) { continue; }
for (j = 0; j < 100000000; ++j) {
int [] perc = new int[12];
int val = j;
int sum = 0;
int cnt = 0;
for (k = 0; k < 12; ++k) {
if (i & (1 << k)) {
cnt++;
if (cnt == 5) {
perc[k] = 100 - sum;
}
else {
perc[k] = val % 100;
val /= 100;
}
sum += perc[k];
if (sum > 100) { break; }
}
else { perc[k] = 0; }
}
if (sum == 100) {
System.out.println(perc[0] + ...);
}
}
}
The outer loop iterates over all possible combinations of using 12 items. You can do this by looping over all numbers from 1:2^12, and the 1s in the binary representation of that number are the elements you're using. The count_number_of_1s is a function that loops over all the bits in the parameter and returns the number of 1s. If this is not 5, then just skip this iteration because you said you only want at most 5 mixed. (There are 792 such cases).
The j loop is looping over all the combinations of 4 (not 5) items from 0:100. There are 100^4 such cases.
The inner loop is looping over all 12 variables, and for those that have a 1 in their bit-position in i, then it means you're using that one. You compute the percentage by taking the next two decimal digits from j. For the 5th item (cnt==5), you don't take digits, you compute it by subtracting from 100.
This will take a LONG time (minutes), but it won't be nearly as bad as 12 nested loops.
for(int a=0;a<=100;a++){
for(int b=0;b<=50;b++){
for(int c=0;c<=34;c++){
for(int d=0;d<=25;d++){
for(int e=0;e<=20;e++){
for(int f=0;f<=17;f++){
for(int g=0;g<=15;g++){
for(int h=0;h<=13;h++){
for(int i=0;i<=12;i++){
for(int j=0;j<=10;j++){
for(int k=0;k<=10;k++){
for(int l=0;l<=9;l++){
if(a+b+c+d+e+f+g+h+i+j+k+l==100)
{
// run 12 for loops for arranging the
// 12 obtained numbers at all 12 places
}}}}}}}}}}}}}
In Original approach(permutation based), the iterations were 102^12 = 1.268e24. Even though the 102th iteration was false, it did check the loop terminating condition for 102th time.
So you had 102^12 condition checks in "for" loops, in addition to "if" condition checks 101^12 times, so in total, 2.4e24 condition checks.
In my solution(combination based),No of for loop checks reduces to 6.243e15 for outer 12 loops, &
if condition checks = 6.243e15.
Now, the no of for loops(ie inner 12 for loops) for every true "if" condition, is 12^12 = 8.9e12.
Let there be x number of true if conditions. so total condition checks
=no of inner for loops*x
= 8.9e12 * x + 6.243e15
I'm not able to find the value of x. however, I believe it wouldnt be large enough to make total conditon checks greater than 2.4e24

Categories