Sieve of Eratosthenes Issue Java - java

I've got an issue with an assignment that I have requiring the use of arrays. I need to create the Sieve of Eratosthenes algorithm and print out all the prime numbers. I'm quite confused because as far as I can tell, my order of operations is correct. Here is the code:
//Declare the array
boolean numbers [] = new boolean[1000];
int y = 0;
//Declare all numbers as true to begin
for(int i = 2; i < 1000;i++){
numbers[i] = true;
}
//Run loop that increases i and multiplies it by increasing multiples
for (int x = 2; x < 1000; x++) {
//A loop for the increasing multiples; keep those numbers below 1000
//Set any multiple of "x" to false
for(int n = 2; y < 1000; n++){
y = n * x;
numbers[y] = false;
}
}
I first set all the numbers in the array to true. Then the second loop will start "x" at 2, then inside it is a nested loop that will multiply "x" by values of "n" and "n" will continue to increase as long as the product of that multiplication ("y") is below 1000. Once "y" reaches that maximum, "x" will go up one number and the process repeats until all non-prime numbers are set to false.
That was my logic when I made the code, but when I try to run it I get the "ArrayIndexOutOfBoundsException" error. From what I can tell I set everything to stay below 1000 so it shouldn't be going over the array size.
I know its probably not the most efficient algorithm because as "x" increases it will go over numbers it already went over but it was the most simple one I could think of.

Here:
for(int n = 2; y < 1000; n++){
y = n * x;
numbers[y] = false;
}
you first check that y < 1000, and then intialize and use it. This is the wrong way around.
Also, you can get away with running the above loop only when x is prime. This won't affect correctness, but should make your code much faster.

Related

How to initialize a large number of variables in Java quickly and easily?

So I have a really basic coding question, I just started learning this year, and I have an assignment for a code that is supposed to
flip a fair coin n times and count how many heads it gets. The program will do m experiments and then
print out the results as a (vertical) histogram. The program will first ask the user to input the number of
experiments to perform (m) and the number of coin flips in each experiment (n). n can be at most 79. The
output will be a histogram made up of spaces and asterisks (*), with n+1 columns (for the number of heads
which can go from 0 to n)
I have the code for the histogram all done, but the problem I have is how to store the number of heads as it's own variable. For example, if it flipped the coin 80 times and 40 of them were heads, I would want it to create an int for 40 flips, then add one to it. I just don't know how to go about initializing 80 variables without writing out int one = 0; int two = 0, int three = 0; until the end of time, then writing 80 if statements until it finds the right integer to add one to. Is there an easy way to do this or should there be a different approach I should be taking? Here is the code, please be gentle, literally only a month or so into an extremely basic java class
for(m=m; m>0; m--) { //runs m number of experiments of n coinflips, keeping track of total heads
n = o; // when N gets set to 0 through the while loop, o resets it back to it's original so it can loop again
while(n>0) {
n--;
if(random.nextBoolean()) {
heads++;
total++;
/** here is where I want the number of heads saved to a
variable, so that way later I can run a loop to put as many *'s as I need in the histogram later */
Just use an array for the 80 (or n) experiments:
I don't understand, this would just count how many heads/tails there are right? This doesn't save them (ie it flipped 5 heads 6 times, 4 heads 3 times, 3 heads twice, ect) unless I'm misunderstanding
If you are storing the number of head m times (where m is < 80), you can:
1) print the histogram as you generate the results (no array needed) OR
2) store the 80 results in an array
Example for 1 (no array):
for(int x=0; x<experiments; x++){
int heads = 0;
for(int y=0; y<flips; y++){
if(rnd.nextInt(2) == 0) //assume 0 is head
heads ++;
}
//print histogram
for(int y=0; y<heads; y++)
System.out.print("*");
System.out.println();
}
Example for 2 (with array):
int[] expr = new int[80]; //store results for 80 experiments
for(int x=0; x<expriments; x++)
for(int y=0; y<flips; y++)
if(rnd.nextInt(2) == 0)
expr[x] ++;
Use an array:
int n = 80;
// space for n integers, with indexes 0..n
int[] histogram = new int[n + 1];
for (int i = 0; i < experiments; i++) {
// flip coin n times, counting heads
int heads = ...;
histogram[heads] = histogram[heads] + 1;
}
for (int i = 0; i < histogram.length; i++) {
printStars(histogram[i]);
}
If you're unfamiliar with arrays, the Java Tutorial has a good explanation.

Java random with low percentage on boolean array (quantile function)

I have a boolean array of aproximattely 10 000 elements. I would like to with rather low,set probability (cca 0,1-0,01) change the value of the elements, while knowing the indexes of changed elements. The code that comes to mind is something like:
int count = 10000;
Random r = new Random();
for (int i = 0; i < count; i++) {
double x = r.nextDouble();
if (x < rate) {
field[i]=!field[i];
do something with the index...
}
}
However, as I do this in a greater loop (inevitably), this is slow. The only other possibility that I can come up with is using quantile function (gaussian math), however I have yet to find any free to use code or library to use. Do you have any good idea how to work around this problem, or any library (standard would be best) that could be used?
Basically, you have set up a binomial model, with n == count and p == rate. The relevant number of values you should get, x, can be modeled as a normal model with center n*p == count*rate and standard deviation sigma == Math.sqrt(p*(1-p)/n) == Math.sqrt(rate * (1-rate) / count).
You can easily calculate
int x = (int) Math.round(Math.sqrt(rate * (1-rate) / count)
* r.nextGaussian() + count * rate)
Then you can generate x random numbers in the range using the following code.
Set<Integer> indices = new HashSet<Integer>();
while(indices.size() < x){
indices.add(r.nextInt(count));
}
indices will now contain the correct indices, which you can use as you wish.
You'll only have to call nextInt a little more than x times, which should be much less than the count times you had to call it before.

Random Uniform Distribution

So i want to get random elements of a list with uniform distribution in Java. I know that in the Random class, for example the nextInt method, already give me something like that:
Returns a pseudorandom, uniformly distributed int value between 0 (inclusive) and the specified value (exclusive), drawn from this random number generator's sequence.
So given something like the code below:
Random rnd = new Random();
int numTimes = 10;
for(int i = 0; i < numTimes*n; i++){
System.out.println(rnd.nextInt(10));
}
I expect that for small "n" I can't quite see a good uniform distribution, probably increasing it, I will see something better. So my question is, how can I guarantee a uniform distribution within smaller n, or in other words, with "n = 2" how can I get every number at least once?
Trying to explain better: giving 10-number range dataset, and for example 20 iterations, is there a way that each number is printed 1-3 times, in other words, at least once?
If you want to generate numbers that occur exactly the same number of times (which is not the same as a uniform distribution), then there is a better way to do it.
int n = 2; // your "n"
int t = 100; // how often you want each number x to occur, where 0 <= x < n
// Build a list of numbers
List<Integer> l = new ArrayList<>();
for (int i = 0; i < t; i++) {
for (int j = 0; j < n; j++) {
l.add(j);
}
}
// Shuffle the list randomly; this ensures the order is random but each number x occurs
// as often as any other x
Collections.shuffle(l);
for (Integer value : l) {
System.out.println(value);
}
If you want to have some numbers at least once, but don't care about the others; then insert 1 of each number that you want at least once and the rest randomly. If I understand you correctly, you want the numbers 1, 2 and 3 at least once, and then randomly numbers 1, 2 and 3. So, that would be:
int n = 3; // your "n"
// Build a list of numbers
List<Integer> l = new ArrayList<>();
for (int x = 1; x <= n; x++) {
l.add(x);
}
int t = 17; // add 17 more random numbers in range 1-3 inclusive
for (int i = 0; i < t; i++) {
l.add(rnd.nextInt(n) + 1);
}
// Shuffle
Collections.shuffle(l);
// Print
for (Integer value : l) {
System.out.println(value);
}

How to get a 50/50 chance in random generator

I am trying to get a 50/50 chance of get either 1 or 2 in a random generator.
For example:
Random random = new Random();
int num = random.nextInt(2)+1;
This code will output either a 1 or 2.
Let's say I run it in a loop:
for ( int i = 0; i < 100; i++ ) {
int num = random.nextInt(2)+1 ;
}
How can I make the generator make an equal number for 1 and 2 in this case?
So I want this loop to generate 50 times of number 1 and 50 times of number 2.
One way: fill an ArrayList<Integer> with fifty 1's and fifty 2's and then call Collection.shuffle(...) on it.
50/50 is quite easy with Random.nextBoolean()
private final Random random = new Random();
private int next() {
if (random.nextBoolean()) {
return 1;
} else {
return 2;
}
}
Test Run:
final ListMultimap<Integer, Integer> histogram = LinkedListMultimap.create(2);
for (int i = 0; i < 10000; i++) {
nal Integer result = Integer.valueOf(next());
histogram.put(result, result);
}
for (final Integer key : histogram.keySet()) {
System.out.println(key + ": " + histogram.get(key).size());
}
Result:
1: 5056
2: 4944
You can't achieve this with random. If you need exactly 50 1s and 50 2s, you should try something like this:
int[] array = new int[100];
for (int i = 0; i < 50; ++i)
array[i] = 1;
for (int i = 50; i < 100; ++i)
array[i] = 2;
shuffle(array); // implement shuffling algorithm or use an already existing one
EDIT:
I understand that if you are looking to accomplish exactly 50-50 results, then my answer was not accurate. You should use a pre-filled collection, since it is impossible to achive that using any kind of randomness. This considered, my answer is still valid for the title of the question, so, this is it:
Well, you do not need the rnd generator to do this.
Comming from javascript, I would go with a single liner:
return Math.random() > 0.5 ? 1: 2;
Explanation: Math.random() returns a number between 0(inclusive) and 1(exclusive), so, we just examine weather is larger than 0.5 (middle value). In theory there is a 50% change that does.
For a more generic use, you can just replace 1:2 to true:false
You can adjust the probability along the way so that the probability of getting a one decreases as you get more ones. This way you don't always have a 50% chance of getting a one, but you can get the result you expected (exactly 50 ones):
int onesLeft = 50;
for(int i=0;i<100;i++) {
int totalLeft = 100 - i;
// we need a probability of onesLeft out of (totalLeft)
int r = random.nextInt(totalLeft);
int num;
if(r < onesLeft) {
num = 1;
onesLeft --;
} else {
num = 2;
}
}
This has an advantage over shuffling because it generates numbers incrementally so it desn't need memory to store the numbers.
You have already successfully created a random generator that returns 1 or 2 with equal probability.
As (many) other's have mentioned, your next request, to force an exact 50/50 distributions in 100 trials, does not fall in line with random number generation. As shown in https://math.stackexchange.com/questions/12348/probability-of-getting-50-heads-from-tossing-a-coin-100-times, the realistic expectation of that occurring is only around 8%. So even while you might expect 50 of each, that exact outcome is actually rather rare.
The Law of Large Numbers states that you should close in on expected value as your number of trials increases.
So for your actual question: How can I make the generator make an equal number for 1 and 2 in this case?
The best (humorous) answer I can come up with is: "Run it in an infinite loop."

problems with loop running continuously

my loops problems seems to be running an not stopping
am not getting the loop to stop it running cont and wont stop
rate=interest/100;
double monthly_rate=rate/period;
double n=period*length;
payment = (principal * Math.pow((1 + monthly_rate), n)) / n;
System.out.printf("Test acoount amount is %.2f",payment);
for(double i=payment; n<=n; n++){
System.out.println(i+ "" +(payment-i));
}
n <= n
will generally always be true.
You need to figure out the terminating condition of the loop, and possibly fix the n++ as well. It's likely to be something like:
for (int prd = 1; prd <= n; prd++) ...
which will loop n times with prd holding the values 1 through n inclusive.
Your problem is right there in the for statement itself:
for(double i=payment; n<=n; n++){
in the conditional n<=n
Basically your expression will never evaluate to anything other than what it's set too, because 'n will always equal n'
What you need is for your check to be a different variable or some kind of upper limit that you wish to cut things off at eg:
int max = 10;
for(double i=payment; n<=max; n++){
How you set and / or control max depends on exactly what your trying to achieve.

Categories

Resources