This question already has answers here:
Random weighted selection in Java
(7 answers)
Closed 1 year ago.
Today in interview they asked me this question? How to generate a discrete random variable in Java? I couldn't do it but I wonder the solution.
They gave me an array:
double[] probabilities={.2,.1,.3,.4};
double[] outcomes ={4,5,8,11.5};
And this should give the answer:
double discreteRV = problem.randPMF(probabilities,outcomes);
I couldn't understand how to solve this question.
Since all the probabilities will always add up to 1, you can generate a random number between 0 and 1 then iterate through the probabilities and subtract them. When the number is less than or equal to 0, the index of the last subtracted probability is the index of the outcome:
import java.util.Random;
public static double randPMF(double[] prob, double[] out) {
double rand = Math.random();
int index = -1;
while (rand >= 0) {
index++;
rand -= prob[index];
}
return out[index];
}
Here's my idea for a solution:
private double randPMF(double[] probabilities, double[] outcomes) {
double random = Math.random();
double p = 0;
for (int i = 0; i < probabilities.length; i++) {
p += probabilities[i];
if (random < p) {
return outcomes[i];
}
}
return outcomes[outcomes.length - 1];
}
This is what I came up with
private static double randPMF(double[] probabilities, double[] outcomes) {
int n = 10;
boolean nNotFound;
for (double probability: probabilities){
nNotFound = true;
while(nNotFound)
if (probability*n == (double)((int)(probability*n)))
break;
else
n *= 10;
}
double[] numbers = new double[n];
//j tracks the probability/occurence
int j;
//k tracks the new array
int k = 0;
//i tracks each element in our old arrays
for (int i = 0; i<probabilities.length; i++) {
j = 0;
while (j < (probabilities[i]*n)) {
numbers[k] = outcomes[i];
k++;
j++;
}
}
int index = new Random().nextInt(n);
System.out.println(numbers.length);
return numbers[index];
}
Related
The program I wrote simulates rolling dice and attempts to calculate the probability of rolling a six in 4 rolls. The issue I'm having is it always calculates 0.66 when it should be around 0.50 and I can't figure out why.
public class Die {
int outcome;
void roll() {
double x = Math.random();
x = 1.0 + (x * 6.0);
outcome = (int) Math.floor(x);
}
}
public class Application {
public static void main(String[] args) {
float sixesIn4 = 0F;
int sixesIn24 = 0;
double sixIn4Probability;
for (int k = 0; k < rolls; k++) {
for (int i = 0; i < 4; i++) {
die.roll();
if (die.outcome == 6) {
sixesIn4++;
}
}
}
sixIn4Probability = sixesIn4 / rolls;
System.out.println(sixIn4Probability);
}
}
Can anyone help me?
The probability of rolling at least one six in four rolls is 1-(5/6)**4, which is just over 0.5.
You are calculating the expected number of sixes from 4 rolls, which is 4*(1/6), 0.67.
You just need to increment your count once for each group of 4 rolls. The smallest change, without rewriting your whole code, is to add a break statement in your inner loop:
for (int i = 0; i < 4; i++) {
die.roll();
if (die.outcome == 6) {
sixesIn4++;
break;
}
}
That way you only count each group of 4 once, if it has a six in it, instead of counting the number of sixes you get from it.
There are a couple of problems in your code. Firstly, you are generating floating point random numbers and then converting to ints. Better to just generate ints. Secondly you are counting all 6s rolled, not just the sequence of rolls that result in at least 1 six.
Split out your 'at least 1 six' into a separate method:
private boolean atLeastOneSix() {
for (int i = 0; i < 4; i++) {
if (random.nextInt(6) + 1 == 6)
return true;
}
return false;
}
Then your counting becomes more obvious:
int sixCount = 0;
for (int t = 0; t < trials; t++) {
if (atLeastOneSix())
sixCount++;
}
double prob = 1.0 * sixCount / trials;
If you are comfortable with streams:
IntStream.range(4).map(i -> random.nextInt(6) + 1).anyMatch(r -> r == 6);
And
long sixCount = IntStream.range(trials).filter(i -> atLeastOneSix()).count();
You want to keep track of a boolean in each roll to determine if there are one or more sixes. My sample gives 0.526, which given your comments should be (close to) correct.
class Die {
int outcome;
void roll() {
double x = Math.random();
x = 1.0 + (x * 6.0);
outcome = (int)Math.floor(x);
}
}
public class Application {
public static void main(String[] args) {
int rolls = 1000;
Die die = new Die();
float sixesIn4 = 0F;
double sixIn4Probability;
boolean sixinRol;
for (int k = 0; k < rolls; k++) {
sixinRol = false;
for (int i = 0; i < 4; i++) {
die.roll();
if (die.outcome == 6) {
sixinRol = true;
}
}
if (sixinRol) sixesIn4 += 1;
}
sixIn4Probability = sixesIn4 / rolls;
System.out.println(sixIn4Probability);
}
}
just to preface, I am very new to coding in Java, or coding in general to be exact.
Here is what I am trying to accomplish. It is a project, where we take a input file of numbers, one integer being a competitor number, the next being their weight for a fish they caught, (Looking like this 3 26.7 (new line per two numbers) 2 2.6.. so on and so on), put them in a array, then sort them in one way or another. Now, I will post the whole code, but it is only the last method, "sort", that I am having difficulties right now.
The method is a bubble sorting method. The way I am approaching it is so that it will take the first array, compare it with the second array to see if it is less than, then swap the two competitor numbers if the logic is correct so that I can print the competitor numbers in the main method, and call the appropriate weight for the competitor (which is previously compiled in past if/then loop). Note, I do not have it currently trying to print the competitor weight.
I believe I am on the right track for this, but for some reason, the numbers printed, after calling the sort method, are not correct. If you could tell me what I am doing wrong, that would be greatly helpful. Thanks.
import java.io.*;
import java.util.Scanner;
public class Project8
{
public static void main(String[] args)
throws FileNotFoundException
{
Scanner inF = new Scanner(new File("data7.txt"));
PrintWriter outF = new PrintWriter(new File("pro7out.txt"));
int [] arrayNum = new int[7];
int [] sortedNum = new int[7];
double [] arrayWeight = new double[7];
int place, firstplace, lastplace;
double weight;
String line;
String entries[];
outF.printf("My name - Project 7: 4/10/18%nResults of the Rocking JR Fishing Contest%n");
outF.printf("Competitor Total%n Number Weight%n");
for (int m = 0; m < 7; m++)
{
arrayNum[m] = m + 1;
}
while (inF.hasNextLine())
{
line = inF.nextLine();
entries = line.split(" +");
place = Integer.parseInt(entries[0]);
weight = Double.parseDouble(entries[1]);
if (place == 1)
arrayWeight[0] += weight;
else if (place == 2)
arrayWeight[1] += weight;
else if (place == 3)
arrayWeight[2] += weight;
else if (place == 4)
arrayWeight[3] += weight;
else if (place == 5)
arrayWeight[4] += weight;
else if (place == 6)
arrayWeight[5] += weight;
else
arrayWeight[6] += weight;
}
for (int k = 0; k < 7; k++)
outF.printf("%5d %15.2f%n", arrayNum[k], arrayWeight[k]);
firstplace = first(arrayNum, arrayWeight);
lastplace = last(arrayNum, arrayWeight);
sortedNum = sort(arrayNum, arrayWeight);
outF.printf(" Winner is%n %d %3.2f%n", firstplace, arrayWeight[firstplace-1]);
outF.printf(" Not as successful%n %d %3.2f%n", lastplace, arrayWeight[lastplace-1]);
for (int k = 0; k < 7; k++)
outF.printf("%d", sortedNum[k]);
outF.printf(" Contest Over%n");
inF.close();
outF.close();
}
public static int first(int number[], double weight[])
{
int firstplace=0;
double max=0;
for (int k = 0; k < 7; k++)
{
if (weight[k] > max)
{
max = weight[k];
firstplace = number[k];
}
}
return firstplace;
}
public static int last(int number[], double weight[])
{
int lastplace=0;
double minimum=weight[0];
for (int k = 0; k < 7; k++)
{
if (weight[k] < minimum)
{
minimum = weight[k];
lastplace = number[k];
}
}
return lastplace;
}
public static int[] sort(int number[], double weight[])
{
int n = number.length;
int tempNum = 0;
for (int i = 0; i < n; i++)
{
for (int j = 1; j < (n-1); j++)
{
if (weight[j - 1] < weight[j])
{
tempNum = number[j - 1];
number[j - 1] = number[j];
number[j] = tempNum;
}
}
}
return number;
}
}
This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 6 years ago.
This should be a fairly simple homework assignment, but I've been pounding my face on it for a while now ... When executed, it should just populate an array and find the mean and standard deviation. I'm getting an out of bounds exception, but only in the arrayDeviation method. Any direction would be appreciated.
import java.util.Scanner;
import java.util.Random;
public class StandardDeviation
{
//declare global variables
final static int ELEMENTS = 100;
public static void main(String [] args)
{
//declare variables
final int RANGE = 500;
int[] numList = new int[ELEMENTS];
Random rand = new Random();
//populate array
for(int count = 0; count < ELEMENTS; count++)
{
numList[count] = rand.nextInt(RANGE) + 1;
}
//call printArray
printArray(numList);
//call arrayAverage
double mean = arrayAverage(numList);
System.out.println("\nMean: " + mean);
//call arrayDeviation
double standardDeviation = arrayDeviation(numList, mean);
System.out.print("Standard deviation: " + standardDeviation);
} //end main
//output 10 elements per line
public static void printArray(int[] list)
{
final int ELEMENTS_PER_LINE = 10;
for(int count = 0; count < ELEMENTS; count++)
{
System.out.printf("%-4d", list[count]);
if ((count + 1) % ELEMENTS_PER_LINE == 0)
{
System.out.println();
}
}
}
//returns average as double
public static double arrayAverage(int[] list)
{
int sum = 0, count;
double average;
for(count = 0; count < ELEMENTS; count++)
{
sum = sum + list[count];
}
average =(double) sum / count;
return average;
}
//calculate and return standard deviation
public static double arrayDeviation(int[] list, double mean)
{
double sum = 0.0, standardDeviation;
int count;
for(count = 0; count < ELEMENTS; count++);
{
sum = sum + Math.pow((list[count] - mean), 2);
}
standardDeviation = Math.sqrt(sum / 2);
return standardDeviation;
}
} //end class
Staring at this code for like 10 minutes I couldn't see why it's giving that Exception.Pasting it in Netbeans and it instatly highlights an empty for-loop
public static double arrayDeviation(int[] list, double mean)
{
double sum = 0.0, standardDeviation;
int count;
for(count = 0; count < ELEMENTS; count++); //This semicolon is your
//problem
{
sum = sum + Math.pow((list[count] - mean), 2);
}
This question already has answers here:
Int division: Why is the result of 1/3 == 0?
(19 answers)
Closed 4 years ago.
public class Solution {
public static void main(String[] args) {
int ne = 0;
int p = 0;
int z = 0;
Scanner in = new Scanner(System.in);
int n = in .nextInt();
int arr[] = new int[n];
for (int arr_i = 0; arr_i < n; arr_i++) {
arr[arr_i] = in .nextInt();
}
for (int arr_i = 0; arr_i < n; arr_i++) {
if (arr[arr_i] > 0) {
p++;
} else if (arr[arr_i] < 0) {
ne++;
} else {
z++;
}
}
double n1 = p / n; // this is showing 0 ouput
double n2 = ne / n; // this is showing 0 ouput
double n3 = z / n; // this is showing 0 ouput
System.out.println(n1);
System.out.println(n2);
System.out.println(n3);
}
}
question is to print the fraction of positive ,negative and zeros to the number of elements in array.
the output is showing 0 for everything plz suggest the mistake
Use the code below. You're doing integer division, which rounds the result down to 0.
double n1=((double)p)/n;
double n2=((double)ne)/n;
double n3=((double)z)/n;
Java 8 solution:
AtomicInteger countPositive=new AtomicInteger();
AtomicInteger countNegative = new AtomicInteger();
AtomicInteger countZeros = new AtomicInteger();
AtomicInteger countTotal = new AtomicInteger();
int[] arr = {-1,-1,0,1,1};
Arrays.stream(arr).forEach(x->{
if(x>0){
countPositive.getAndIncrement();
} else if(x==0){
countZeros.getAndIncrement();
}else{
countNegative.getAndIncrement();
}
countTotal.getAndIncrement();
});
System.out.println(new BigDecimal(countPositive.doubleValue()/countTotal.doubleValue()).setScale(6,BigDecimal.ROUND_HALF_EVEN));
System.out.println(new BigDecimal(countNegative.doubleValue()/countTotal.doubleValue()).setScale(6,BigDecimal.ROUND_HALF_EVEN));
System.out.println(new BigDecimal(countZeros.doubleValue()/countTotal.doubleValue()).setScale(6,BigDecimal.ROUND_HALF_EVEN));
Using atomicIntegers is necessary because Streams will not allow to modify local variables outside its scope if they are not enforced final. AtomicInteger ensures it is threadsafe when we increment and decrement.
Also, I computed countTotal while I am looping to get individual counts. You can do array.length, there will not be any cost to compute length as JVMs know the value as it is not changing.
This question already has answers here:
What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?
(26 answers)
Closed 6 years ago.
I created this method randomInt, that gives a random number, between -5, and 15. I created another method randomIntArray that calls randomInt, in a loop, and stores the random integers into an array. However, when I try to print it, it just returns an ArrayIndexOutOfBoundsException.
public static int randomInt(int low, int high) {
double e;
double x = Math.random();
e = low + x * (high - low);
return (int) e;
}
public static int[] randomIntArray(int n) {
int[] a = new int[n];
for (int i = 0; i < a.length; i++) {
a[i] = randomInt(-5, 15); //"-5&15 are the lower and upper bounds of the random number array
}
return a;
}
In randomInt, When I didn't cast the return value into an int, it worked, however I need it to return an int for the array to work.
Check your printing code after calling randomIntArray(number);
/**
* #param args the command line arguments
*/
public static void main(String[]args) {
int[] myArray = randomIntArray(10);
// Manual iteration through your array
for (int i = 0; i < myArray.length; i++) {
System.out.print(myArray[i] + " ");
}
System.out.println("");
// Use of Arrays class to print your array
System.out.println(Arrays.toString(myArray));
}
public static int randomInt(int low, int high) {
double e;
double x = Math.random();
e = low + x * (high - low);
return (int) e;
}
public static int[] randomIntArray(int n) {
int[] a = new int[n];
for (int i = 0; i < a.length; i++) {
a[i] = randomInt(-5, 15);
}//"-5&15 are the lower and upper bounds of the random number array
return a;
}
Results:
http://ideone.com/3OrTei
In the function calling randomIntArray(int n):
int[] array = randomIntArray(5);
for(int i = 0; i < array.length; i++)
{
System.out.println(array[i]);
}
The code works, just make sure you're printing the results properly