My professor asked us to generate random variables between 0 and 0.5. I wrote this code:
public class Random_Number_Generator {
double randomGenerator() {
Random generator = new Random();
double num = generator.nextDouble() * (0.5 - 0);
return num;
}
}
But my professor is saying this code is generating random numbers not random variables. What could this mean?
Apparently I misread the post; the following should be read with that in mind.
In that code, num and generators are local variables. A random number (a value) is assigned to the variable called num using the Random object named by the generator variable. Finally, the value stored in the variable num is returned from the method.
In any case, generator.nextDouble() returns a value between [0,1) so to get a value between [0,0.5), just scale it by half: divide it by two or, as done, multiply it by a half.
The - 0 in the above code is silly, but "okay" because (0.5 - 0) == 0.5.
(Also, it is good to get into the practice of to creating one Random instance and re-using it .. although this issue is more obvious in .NET.)
Now, actual random variable is, as far as I know, a function that maps values to their probability. I don't think you're supposed to return a function, so I've scratched this: the closest thing to what I guess you're supposed to do:
import java.util.*;
import java.lang.*;
class RandomVar
{
TreeMap<Double, Integer> variables;
public RandomVar()
{
variables = new TreeMap<Double, Integer>();
int count = Main.RandGen.nextInt(15);
double probabilityLeft = 1.0;
for (int i = 0 ; i < count - 1; i++)
{
int toPut = Main.RandGen.nextInt(100);
while (variables.containsValue(toPut)) toPut = Main.RandGen.nextInt(100);
double prob = probabilityLeft * Main.RandGen.nextDouble();
variables.put(prob, toPut);
}
int toPut = Main.RandGen.nextInt(100);
while (variables.containsValue(toPut)) toPut = Main.RandGen.nextInt(100);
double prob = probabilityLeft;
variables.put(prob, toPut);
}
public int getValue()
{
double rand = Main.RandGen.nextDouble();
double sum = 0;
for (double prob : variables.keySet()) //keySet() is sorted ascending
{
if (prob >= rand)
return variables.get(prob);
}
return variables.get(variables.lastKey());
}
//Shows probabilities of values
public void test()
{
for (double key : variables.keySet())
System.out.println(key + " :: " + variables.get(key));
}
}
class Main
{
public static Random RandGen = new Random();
public static void main (String[] args)
{
RandomVar rv = new RandomVar();
rv.test();
System.out.println("------------------------------");
for (int i = 0; i < 40 ; i++)
System.out.print(rv.getValue() + ", ");
}
}
This is very lousy solution, basically a class which allows you to return values with a set (random) probability. I still don't know if this is what you professor wants though...
Try this code:
public static void main(String[] arg) {
System.out.print(Random());
}
public static double Random() {
double START = 0;
double END = 0.5;
Random random = new Random();
double token = RandomNumber(START, END, random);
return token;
}
public static double RandomNumber(double aStart, double aEnd, Random aRandom) {
if (aStart > aEnd) {
throw new IllegalArgumentException("Start cannot exceed End.");
}
// get the range, casting to long to avoid overflow problems
double range = aEnd - aStart;
// compute a fraction of the range, 0 <= frac < range
double fraction = (range * aRandom.nextDouble());
double randomNumber = (fraction + aStart);
return randomNumber;
}
Related
I am a beginner at java, but I'm trying to learn.
This is my program i am working on, the user will enter some values, where the program sort all the even values of the index to be the variable radie and all the odd values of the index to be height no matter what the element is. Same goes for nominator och denominator in the next method. But now i am stuck and dont know how to return the arrayList. I want to return my new arrays so i can use them in my other methods. Like i said im very new at java but find it fun to work with but now i need your help. As you can see i have been using swedish words for the outprint, sorry for that.
import java.util.Scanner;
import java.util.ArrayList;
public class program
{
private static Scanner keyboard = new Scanner(System.in);
public static void main(String[] args)
{
System.out.println("-------------------------------");
System.out.println("# Test av area- och volymmetod.");
System.out.println("-------------------------------");
double result1 = area1(radie);
double result2 = area2(radie, height);
double result3 = volumeCone(radie, height);
System.out.println("Radie = " + radie + "\tHeight = " + height);
System.out.printf("Basytans area:%11.2f", result1);
System.out.println();
System.out.printf("Mantelytans area:%8.2f", result2);
System.out.println();
System.out.printf("Volym:%19.2f", result3);
System.out.println();
}
public static ArrayList<Integer> readFirstInputs(int numberOfInputs)
{
System.out.println("Please enter values, Q to quit:");
int[] inputs = new int[numberOfInputs];
ArrayList<Integer> radie = new ArrayList<Integer>();
ArrayList<Integer> height = new ArrayList<Integer>();
for(int i = 0; i < inputs.length; i++)
{
inputs[i] = keyboard.nextInt();
if (i % 2 == 0)
{
radie.add(inputs[i]);
}
else if (i % 2 != 0)
{
height.add(inputs[i]);
}
}
return ????? // return radie and height array, how?
}
public static ArrayList<Integer> readSecondInputs(int numberOfInputs)
{
System.out.println("Please enter values, Q to quit:");
int[] inputs = new int[numberOfInputs];
ArrayList<Integer> nominator = new ArrayList<Integer>();
ArrayList<Integer> denominator = new ArrayList<Integer>();
for(int i = 0; i < inputs.length; i++)
{
inputs[i] = keyboard.nextInt();
if (i % 2 == 0)
{
nominator.add(inputs[i]);
}
else if (i % 2 != 0)
{
denominator.add(inputs[i]);
}
}
return ????; // return nominator and denominator array, how?
}
/* Use my different arrays in the methods below. */
public static double area1(int radie)
{
double areaBas = Math.PI * Math.pow(radie, 2);
return areaBas;
}
public static double area2(int radie, int height)
{
double areaMantel = Math.PI * radie * Math.sqrt((Math.pow(radie, 2) + Math.pow(height, 2)));
return areaMantel;
}
public static double volumeCone(int radie, int height)
{
double volume = Math.PI * Math.pow(radie, 2) * height / 3;
return volume;
}
public static int fractionToInteger(int nominator, int denominator)
{
int amount = nominator / denominator;
return amount;
}
public static int fractionToFraction(int nominator, int denominator)
{
int remainingAmount = nominator % denominator;
return remainingAmount;
}
}
Are you allowed to use a list instead? it's way more efficient since once created, you can't change the size of an array, but if you instead create two empty lists you can just use the .add method that lists have, looking similar to this:
public static List<Integer> readFirstInputs(int numberOfInputs)
{
System.out.println("Please enter values, Q to quit:");
int[] inputs = new int[numberOfInputs];
List<Integer> evens = new List<Integer>();
List<Integer> odds = new List<Integer>();
for(int i = 0; i < inputs.length; i++)
{
inputs[i] = keyboard.nextInt();
if (i % 2 == 0)
{
evens.add(inputs[i]);
}
else if (i % 2 != 0)
{
odds.add(inputs[i]);
}
}
}
of course I am a bit confused on exactly what you want to do so you are definitely gonna have to change this up a bit, I just want to use this as a basic example of how to use a list instead.
If I understand you correctly, you would like to return from the function an array of odd numbers and an array of even numbers from user input.
but you are returning only one array which is just an array of the users inputs (with no logical meaning for the conditions in the loop).
from what I know - it is not possible to return 2 arrays, but there are solutions of course. you can return a class or a dictionary, for example.
if you choose a dictionary it will be something like Dictionary<string,object>, and will have 2 items, the string will be "odd" \ "even", and the object will be the matching array of the numbers (int[] or List<int>). odd numbers array a value of "odd" key, and even numbers array a value of "even" key in the dictionary.
two problems that appear to me here other than that:
1.) you are trying to use 2 variables that are not defined or even mentioned in the function (even and odd).
2.) in each condition you wrote return. this will exit the loop and function on the first iteration.
hope this was helpfull.
public class numberCube {
public static int size;
public static int tosses;
public static int random;
public static int value;
public static int values;
public static void cubeSize(){
// Gets the range of numbers that are allowed to be randomized
String x = JOptionPane.showInputDialog
("How many numbers do you want on your cube?");
int size = Integer.parseInt(x);
}
public static void numTosses(){
// Gets the amount of times that a randomizer will loop
String y = JOptionPane.showInputDialog
("How many times do you want to toss the dice?");
int tosses = Integer.parseInt(y);
}
public static void randomizer(){
// creates the random numbers. Heres where the problem is. I need to be able //to allow the user to specify the range of numbers and how many times it will //be randomized
For example, for cubeSize() I could enter 3, and for numTosses() I could enter 5. A possible output would be: 1,1,3,2,3
}
}
}
You're duplicating the initialization of variables (ex: size,tosses,etc) here.
If want to manipulate a property of a specific class you need to use this keyword. So,
int size = Integer.parseInt(x); becomes this.size = Integer.parseInt(x);
int tosses = Integer.parseInt(y); becomes this.tosses = Integer.parseInt(y);
etc..
Then in your randomizer() method you could try something like :
Random random = new Random();
for (int i = 1; i <= this.tosses; i++) {
int value = 1 + random.nextInt(this.size);
System.out.println(value);
}
You mean something like this?
Random r = new Random();
for (int i = 0; i < numTosses; ++i) {
int rand = 1 + r.nextInt(cubeSize);
// use rand, which will be an integer from 1 to cubeSize (inclusive)
}
How would i prevent duplicating numbers from random numbers.
I need to generate 5 numbers between 1 and 9 that are each different.
I would often get same numbers like 23334, how can i prevent that?
Any help would be great!
int num2 = (int) Math.round((Math.random()*9) +1);
int num1 = (int) Math.round((Math.random()*9) +1);
int num5 = (int) Math.round((Math.random()*9) +1);
int num3 = (int) Math.round((Math.random()*9) +1);
int num4 = (int) Math.round((Math.random()*9) +1);
One option is to use shuffle algorithm (e.g. Fisher-Yates shuffle ) to generate random sequence from 1 to 9, then take first 5 numbers of the sequence
Further explanation on StackOverflow: https://stackoverflow.com/a/196065/950427
Set<Integer> set=new HashSet<>();
while (set.size()<5) {
set.add( Math.round((Math.random()*9) +1));
}
After the set is filled you have 5 unique random numbers.
UPDATE: just to illustrate Jared Burrows' comment
Create a List includes the numbers that you want (1 to 9).
Generate random number from 0 to (size of the list minus 1).
Remove one element by index from the above generated random number. And add the removed element to a array which to be returned as a results
public static void main(String[] args) {
int []answers= returnRandomNonRepeatingNumbers(5,0,9);
for(int answer: answers) {
System.out.println(answer);
}
}
public static int[] returnRandomNonRepeatingNumbers(int sizeYouWant, int poolStart, int poolEnd) {
List<Integer> pool=new ArrayList<Integer>();
for(int i=poolStart;i<=poolEnd;i++) {
pool.add(i);
}
int []answers=new int[sizeYouWant];
for(int i=0;i<sizeYouWant;i++) {
//random index to be pick and remove from pool
int randomIndex = (int) Math.round((Math.random()*(pool.size()-1)));
answers[i]=pool.remove(randomIndex);
}
return answers;
}
If the number of possible random values is small, you want to use shuffle.
List<Integer> values = IntStream.range(0, 10).boxed().collect(toList());
Collections.shuffle(values);
values = values.subList(0, 5);
If the number of possible random values is large, you want to test adding them to a Set (or the original list if small enough)
Set<Integer> valueSet = new HashSet<>();
Random rand = new Random();
while(valuesSet.size() < 5) valuesSet.add(rand.nextInt(9) + 1);
List<Integer> values = new ArrayList<>(valueSet);
Collections.shuffle(values, rand);
Note: you need to shuffle the set as it doesn't preserve order. e.g. the numbers 1,2,3 will always come out in that order with HashSet, not 3,2,1.
Floyd's subset selection algorithm is designed to do exactly what you want, and is extremely efficient even for large sets. Selecting m items from a set of n is O(m) average running time, independent of n. Here's a Java implementation.
/*
* Floyd's algorithm to chose a random subset of m integers
* from a set of n, zero-based.
*/
public static HashSet<Integer> generateMfromN(int m, int n) {
HashSet<Integer> s = new HashSet<Integer>();
for (int j = n-m; j < n; ++j) {
if(! s.add((int)((j+1) * Math.random()))) {
s.add(j);
}
}
return s;
}
One possible approach to this problem can be divide & conquer. Step of following describes the approach:
Say m is the minimum & n is the maximum, within what i wanna get x number of randoms
Choose a random p between m & n. Save it to an array of answer. decrease x by 1 as we get one answer to our problem.
Now take a q a random number between m & p-1, another r a random number between p+1 & n. Fill up the answer array with q & r decrease x 1 for q and another 1 for the r.
Now carry on this process recursively, until the lower bound (m) & higher bound (n) becomes equal or x becomes 0.
Benefit: benefit of this approach is that, in worst case, it's runtime will be O(x), where x is the number of random number required. The best case scenarion is also o(x), as i have to find at least n number of random. These two comprise average case to θ(x) complexity.
import java.util.Random;
class GenerateDistinctRandom{
static int alreadyPut = 0;
static Random rand = new Random();
public static int[] generateDistinctRandom(int howMany, int rangeMin, int rangeMax)
{
int randomNumbers[] = new int[howMany];
GenerateDistinctRandom.recursiveRandomGenerator(rangeMin, rangeMax, randomNumbers, howMany);
return randomNumbers;
}
private static void recursiveRandomGenerator(int rangeMin, int rangeMax, int[] storage ,int storageSize)
{
if(rangeMax - rangeMin <= 0 || GenerateDistinctRandom.alreadyPut == storageSize)
{
return ;
}
int randomNumber = GenerateDistinctRandom.rand.nextInt(rangeMax-rangeMin) + rangeMin;
storage[GenerateDistinctRandom.alreadyPut] = randomNumber;
GenerateDistinctRandom.alreadyPut++;
//calling the left side of the recursion
recursiveRandomGenerator(rangeMin, randomNumber - 1, storage, storageSize);
recursiveRandomGenerator(randomNumber + 1, rangeMax, storage, storageSize);
}
public static void main(String []args){
int howMany = 5;
int distinctNumber[] = GenerateDistinctRandom.generateDistinctRandom(howMany 0, 9);
for(int i = 0;i < howMany;i++)
{
System.out.println(distinctNumber[i]);
}
}
}
I suppose you would need to store the ones that have been generated into an array and compare the new random number to the list to ensure it is unique.
public static void main (String[] args) throws java.lang.Exception
{
// your code goes here
int[] numbers = new int[5];
int tempNumber = 0;
for(int numberCounter = 0; numberCounter < numbers.length;)
{
tempNumber = (int) Math.round((Math.random()*9) +1);
if(!contains(numbers, tempNumber)){
numbers[numberCounter++] = tempNumber;
}
}
}
public static boolean contains(final int[] numbersArray, final int tempNumber) {
for (final int numberFromArray : numbersArray) {
if (numberFromArray == tempNumber) {
return true;
}
}
return false;
}
I notice you did not use an array in your example, so in case you do not know how to use them yet, you could also make 5 variables.
int randomNumber = 0;
int firstNumber = Math.round((Math.random()*9) +1);
int secondNumber = 0;
while(secondNumber == 0){
randomNumber = Math.round((Math.random()*9) +1)l
if(randomNumber != firstNumber){
secondNumber = randomNumber;
}
}
And you could continue making while statements like that. But if you are supposed to know about arrays, you should definitely be using one to store the numbers.
How about this?
package com.se;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
public class TestRandom {
List<Integer> comp = new ArrayList<>();
int listSize = 20;
public void doTask() {
Random ran = new Random();
int i = 0;
while(i < listSize){
int randomNumber = ran.nextInt(80) + 1;
if(!comp.contains(randomNumber)){
comp.add(randomNumber);
i++;
}
}
for(Integer num : comp){
System.out.println(num);
}
}
public static void main(String[] args) {
TestRandom testRandom = new TestRandom();
testRandom.doTask();
}
}
I wrote the code, but there is no conversion from double to int.
public class Array {
public static void main(String[] args) {
int i;
int[] ar1 = new int[100];
for(int i = 0; i < ar1.length; i++) {
ar1[i] = int(Math.random() * 100);
System.out.print(ar1[i] + " ");
}
}
}
How can it be corrected?
ar1[i] = (int)(Math.random() * 100);
Conversion in Java looks like cast in C.
It should be like
ar1[i] = (int)(Math.random() * 100);
When you cast, cast type should be in brackets e.g. (cast type)value
Try this:
package studing;
public class Array {
public static void main(String[] args) {
Random r = new Random();
int[] ar1 = new int[100];
for(int i = 0; i < ar1.length; i++) {
ar1[i] = r.nextInt(100);
System.out.print(ar1[i] + " ");
}
}
}
Why?
Using Math.random() can return 1, this means Math.random()*100 can return 100, but OP asked for maximum 99! Using nextInt(100) is exclusive 100, it can only return values from 0 to 99.
Math.random() can not return -0.000001 that would be round to 0 and 1.0000001 can not be returned that should round to 1. So you have less chance to get 0 or 99 than all the numbers between. This way it is not realy random, to guess "its not 0 or 99" is more true than "its not 1 or 98".
Also it do not make a detour via casting and mathematic operations you don't realy need, hey you dont need to strictfp on amd-cpus or old intel-cpus.
This is not actually using the java.lang.Math class, but in Java 8 a random array can also be created in this fashion:
int[] random = new Random().ints(100, 0, 100).toArray();
My solution uses Random class instead of Math.random. Here it is.
private static int[] generateArray(int min, int max) { // generate a random size array with random numbers
Random rd = new Random(); // random class will be used
int randomSize = min + rd.nextInt(max); // first decide the array size (randomly, of course)
System.out.println("Random array size: " + randomSize);
int[] array = new int[randomSize]; // create an array of that size
for (int i = 0; i < randomSize; i++) { // iterate over the created array
array[i] = min + rd.nextInt(max); // fill the cells randomly
}
return array;
}
Create an application containing an array that stores 20 double values,
such as 2.34, 7.89, 1.34, and so on. The application should:
* Display the sum of all the array elements
* Display the average of all the array elements
* Display the largest value of all the array elements
This is a java class assignment. I got a bad grade on this one because my professor said I used a numeric literal. I lost 28 points out of 40. Did I design the solution so bad? His exact comments:
"The program you submitted uses numeric literals in place of the array’s length.
This cause several runtime errors when I change the size of your array and tested the code."
AND my solution:
import java.util.Random;
import java.util.Arrays;
public class MyArray{
public static double[] doubles;
public static void main(String args[]) {
MyArray.createDoublesArray();
MyArray.displayDoublesArray();
MyArray.displaySum();
MyArray.displayAverage();
MyArray.displayTheLargestValue();
}
/*Fill up the double Array class member*/
public static void createDoublesArray(){
doubles = new double[20];
//Create Random object
Random r=new Random();
double rangeMin = 1, rangeMax = 9;
//Generate random double number - 20 times within the range of 2 to 9
for(int i=0;i<20;i++) {
//Generate random double numbers and round them to the two decimal places
double randomdouble = Math.round((rangeMin + (rangeMax - rangeMin) * r.nextDouble())*100.0)/100.0;
doubles[i] = randomdouble;
}
}
/*Display the double Array*/
public static void displayDoublesArray(){
String delimiter;
Arrays.sort(doubles);
System.out.println("The double array: ");
// iterate through all the array elements
System.out.print("{");
for(int i=0;i<20;i++) {
if(i < 19){
delimiter = ", ";
}
else{
delimiter = "}";
}
System.out.print(doubles[i]+ delimiter);
}
System.out.println("\n");
}
/*Displays the sum of the double array.*/
public static void displaySum() {
//initialize the sum with 0
double sum = 0.0;
// iterate through all the array elements
for (int i = 0; i < doubles.length; i++) {
// add up each element to the sum variable
sum += doubles[i];
}
// display the sum
System.out.println("The sum is: " + Math.round(sum*100.0)/100.0 + "\n");
}
/*Displays the average of the double array.*/
public static void displayAverage() {
// initialize the sum with 0
double sum = 0.0;
// iterate through all the array elements
for (int i = 0; i < doubles.length; i++) {
sum += doubles[i];
}
// display the average by dividing the sum to the length of the array
System.out.println("The average is: " + Math.round((sum / doubles.length)*100.0)/100.0 + "\n");
}
/*Displays the largest value from the double array */
public static void displayTheLargestValue() {
//initialize the largest value with the first element
double largestValue = doubles[0];
//iterate through the remaining elements (ignore the first)
for (int i = 1; i < doubles.length; i++) {
// check if "i" element is greater then the current largest value
if (doubles[i] > largestValue) {
largestValue = doubles[i];
}
}
// display the largest value
System.out.println("The largest value is: " + largestValue);
}
}
I'm guessing that instead of things like the following
for(int i=0;i<20;i++)
he wanted you to use the length property
for(int i=0;i<doubles.length;i++)
additionally, here
//initialize the largest value with the first element
double largestValue = doubles[0];
you're assuming that doubles is not empty, and when it is empty, that will thrown an exception
To allow us to maintain this code easily I would 1st of all create:
private final static int SIZE = 20;
createDoublesArray:
public static void createDoublesArray(){
doubles = new double[SIZE];
//Create Random object
Random r=new Random();
double rangeMin = 1, rangeMax = 9;
//Generate random double number - 20 times within the range of 2 to 9
double randomdouble = 0.0; // <- we don't want to initiate double in 'for' loop
for(int i=0;i<SIZE;i++) {
//Generate random double numbers and round them to the two decimal places
randomdouble = Math.round((rangeMin + (rangeMax - rangeMin) * r.nextDouble())*100.0)/100.0;
doubles[i] = randomdouble;
}
}
displayDoublesArray:
/*Display the double Array*/
public static void displayDoublesArray(){
String delimiter;
Arrays.sort(doubles);
System.out.println("The double array: ");
// iterate through all the array elements
StringBuilder buff = new StringBuilder(); // use buffer
buff.append("{");
for(int i=0;i<SIZE;i++) {
if(i < SIZE-1){
delimiter = ", ";
}
else{
delimiter = "}";
}
buff.append(doubles[i]+ delimiter);
}
buff.append("\n");
System.out.println(buff.toString());
}
Our code seems a bit more generic and i can change SIZE (if needed) without actually change my code.
I agree with Maxim Shoustin...
Just one comment to add
1) It is not required to always use double. for eg.
double rangeMin = 1, rangeMax = 9; //can be replaced by int.
ref: Primitive Data Types