Here is what I am suppose to be getting.
This is what I am actually getting.
Write a program DiscreteDistribution.java that takes an integer command-line argument m, followed by a sequence of positive integer command-line arguments a1,a2,…,an, and prints m random indices (separated by whitespace), choosing each index i with probability proportional to ai.
So far I have
public static void main(String[] args) {
// number of random indices
int m = Integer.parseInt(args[0]);
// read in frequency of occurrence of n values
int n = args.length;
int[] freq = new int[n];
for (int i = 0; i < n; i++) {
freq[i] = Integer.parseInt(args[i]);
}
// compute total count of all frequencies
int total = 0;
for (int i = 0; i < n; i++) {
total += freq[i];
}
for (int j = 0; j < m; j++) {
// generate random integer with probability proportional to frequency
int r = (int) ((total) * Math.random() - 1); // integer in [0, total)
int sum = 0;
int event = -1;
for (int i = 0; i < n && sum <= r; i++) {
sum += freq[i];
event = i;
System.out.println(freq[i]);
}
}
}
Under the assumption that I understand your problem correctly, then you can use the following algorithm to produce m random numbers in the range 1 to n according to the given frequencies:
public static void main(String[] args) {
// number of random indices
int m = Integer.parseInt(args[0]);
// read in frequency of occurrence of n values
int n = args.length;
int[] freq = new int[n];
for (int i = 1; i < n; i++) {
freq[i] = Integer.parseInt(args[i]);
}
// compute total count of all frequencies
int total = 0;
for (int i = 1; i < n; i++) {
total += freq[i];
}
double[] summedProbabilities = new double[n];
for (int i = 1; i < summedProbabilities.length; i++) {
final double probability = freq[i] / (double) total;
summedProbabilities[i] = summedProbabilities[i -1] + probability;
}
for (int j = 0; j < m; j++) {
// generate random integer with probability proportional to frequency
double randomProbability = Math.random();
int i = 1;
while (randomProbability > summedProbabilities[i]) {
i++;
}
System.out.print(i + " ");
if (j % 10 == 0) {
System.out.println();
}
}
}
I strongly suggest you to refactor the code in a way that you use methods to calculate small pieces and compose it then.
public class DiscreteDistribution{
public static void main(String[] args) {
// takes in number of times we must loop to print indices
int m = Integer.parseInt(args[0]);
// set the array size to the number of input from command line
//minus the first input
//because we are not considering the input at args[0]
int [] n = new int[args.length-1];
// cSum to store the cummulatives
int [] cSum = new int[args.length];
// to store an array of random generated
//number of size m
int [] rand = new int[m];
int count = 1;
int cCount = 1;
int sum = 0; // to add the inputs n;
// to store user input in an array in n ignoring the first input
for(int i =0; i < n.length; i++)
{
n[i] = Integer.parseInt(args[count]);
count++;
}
//stores the cummulatives of n in cSum
for(int j = 0; j < n.length; j++)
{
sum = sum + n[j];
cSum[j+1] = sum;
}
//generate a random number and stores in rand representing the //probabilites
for(int p = 0; p < m; p++) {
int r = (int)(1+Math.random()*cSum[cSum.length-1]);
rand[p] = r;
}
// loop from 0 to m to print the indices of n;
for(int s = 0; s < m; s++) {
//prints the indices corresponding to the condition
for(int q = 1; q < n.length; q++) {
if(rand[s] <= cSum[q-1]) {
System.out.print(q+" ");
}
}
}
}
Related
public class Bonus1{
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
int[] numbers = new int[n];
for (int i = 0; i < n; i++ ) {
numbers[i] = i;
}
for (int i = 0; i < n; i++ ) {
int r = i + (int)(Math.random() * (n - i));
int tmp = numbers[i];
numbers[i] = numbers[r];
numbers[r] = tmp;
System.out.print(numbers[i]);
}
int min = Integer.MAX_VALUE;
int count = 0;
while(data.hasNext()){
int y = data.nextInt();
if(y < min){
min = y;
count += 1;
}
}
System.out.println(count);
}
}
this code isn't complete, the first 2 for-loops will generate an array between 0 to a given number in the commandline -1
So for example java Bonus1 10 would first generate an array between 0-9 and then it will shuffle these numbers around so that it creates a random permutation.
the while loop is something I've used before to read input and determine how many times a new lowest number is detected. so for example if I get the permutation 7 8 2 3 4 5 1 0 6 9 it will count 7 as the lowest, then 2 as the lowest and then 1 as the lowest and finally 0 as the lowest, making the total amount of times a new lowest number has been detected 4.
but this only works if I use inputs, I need to use the previously generated output as the input in the same file, is there a clever way to do that?
You should iterate for the array numbers like this.
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
int[] numbers = new int[n];
for (int i = 0; i < n; i++) {
numbers[i] = i;
}
for (int i = 0; i < n; i++) {
int r = i + (int) (Math.random() * (n - i));
int tmp = numbers[i];
numbers[i] = numbers[r];
numbers[r] = tmp;
System.out.print(numbers[i]);
}
System.out.println();
int min = Integer.MAX_VALUE;
int count = 0;
for (int i = 0; i < n; ++i) {
int y = numbers[i];
if (y < min) {
min = y;
++count;
}
}
System.out.println(count);
}
output:
6457098123
3
My code is supposed to take the random number generated in the random method and sort them but it's only giving me one number.
My program is a random number generator that is supposed to make 1000 numbers that I can sort but my code only inserts one number into the array.
public static void main(String[] args) {
// write
int max = 1000;
int min=0;
int range = max - min + 1;
// generate random numbers within 1 to 10
for (int i = 0; i < 1000; i++) {
int rand = (int) (Math.random () * range) + min;
System.out.println ( rand );
int array[] = {rand};
int size = array.length;
for ( i = 0; i < size - 1; i++) {
int min1 = i;
for (int j = i + 1; j < size; j++) {
if (array[j] < array[min1]) {
min = j;
}
}
int temp = array[min1];
array[min1] = array[i];
array[i] = temp;
}
for (int k = 0; k < size; i++) {
System.out.print(" " + array[i]);
}
}
}
You need to break your program into separate steps:
Insert all the random numbers into the array
Sort the array
Print the contents of the array
Few problems I noticed:
Since you want to generate 1000 numbers from 1-10, max and min should have values of 10 and 1, respectively.
array should be declared before you start inserting values. It should also have a fixed size of 1000.
Your bubble sort algorithm also had some errors which led to incorrect output. If you wish to sort the array from greatest to least instead, simply change the > to < in the condition of the if statement.
I also decided to use Arrays.toString() to print the array instead of the loop.
public static void main(String[] args) {
int max = 10;
int min = 1;
int range = max - min + 1;
int size = 1000;
int[] array = new int[size];
for (int i = 0; i < size; i++) {
int rand = (int) (Math.random() * range + min);
array[i] = rand;
}
int temp = 0;
for (int i = 0; i < size; i++) {
for (int j = 1; j < size - i; j++) {
if (array[j - 1] > array[j]) {
temp = array[j - 1];
array[j - 1] = array[j];
array[j] = temp;
}
}
}
System.out.println(Arrays.toString(array));
}
your code will result an ArrayIndexOutException. below is the code change from your code ,i dont change too much so you can compare them and find your mistakes,wish good :D
public static void main(String[] args) {
int max = 1000;
int min=0;
int range = max - min + 1;
int[] array = new int[range];
// generate random numbers within 1 to 10
for (int i = 0; i < 1000; i++) {
int rand = (int) (Math.random () * range) + min;
array[i] = rand;
}
int size = array.length;
for (int i = 0; i < size; i++) {
int min1 = i;
for (int j = i + 1; j < size; j++) {
if (array[j] < array[min1]) {
min1 = j;//here min1
}
}
int temp = array[min1];
array[min1] = array[i];
array[i] = temp;
}
for (int k = 0; k < size; k++) {
System.out.print(" " + array[k]);
}
}
let me explain it more clearly,in the OP's code there has some questions,two majors:
one:
for ( i = 0; i < size - 1; i++) {
int min1 = i;
for (int j = i + 1; j < size; j++) {
if (array[j] < array[min1]) {
min = j;
}
}
int temp = array[min1];
array[min1] = array[i];
array[i] = temp;
}
will never run,because the array size is 1 ,so the for loop phrase will be ignore without running(mean for(int i = 0; i < 0; i++){....}).
two:
for (int k = 0; k < size; i++) {
System.out.print(" " + array[i]);
}
beacause the array size is 1,so when array[1] will throw index out exception.so the outermost loop will just run once then throw a exception.
:D
sorry for my bad english. I'm styding LSD String Sorts algorithm and I have a question related to it. Here my code. I want input W not fixed, for example:
String[] a = {"38A", "3TW723", "2IYEA938", "3CI34780720"};
public static void sort(String[] a, int w) { // Sort a[] on leading W characters.
int R = 256;
int N = a.length;
//For each of the character from right to left
for (int d = w - 1; d >= 0; d--) {
//1. count the frequencies
int[] count = new int[R + 1];
for (int i = 0; i < N; i++) {
count[a[i].charAt(d) + 1]++;
}
//2. Transform counts to indices
for (int r = 0; r < R; r++) {
count[r + 1] += count[r];
}
//3. Distribute
String aux[] = new String[N];
for (int i = 0; i < N; i++) {
aux[count[a[i].charAt(d)]] = a[i];
count[a[i].charAt(d)]++;
}
//4. Copyback
System.arraycopy(aux, 0, a, 0, N);
}
}
To develop an implementation of LSD string sort that works for variable-length strings, we need to do many works on the base of your code. We need to find the longest length of string in string[] a, so when d >= a[i].length(), we return 0, which means we add extra 0 to make every string in the same length. This is my code.
// Develop an implementation of LSD string sort
// that works for variable-length strings.
public class LSDForVariableLengthStrings {
// do not instantiate
private LSDForVariableLengthStrings() { }
// find longest length string in string[] a.
public static int findLongestLength(String[] a) {
int longest = 0;
for (int i = 0; i < a.length; ++i) {
if (a[i].length() > longest) {
longest = a[i].length();
}
}
return longest;
}
// if d >= 0 && d < a[i].length(), return a[i].charAt(d);
// else , return 0, which means least value to sort.
public static int findCharAtInString(int i, int d, String[] a) {
if (d < 0 || d >= a[i].length()) {
return 0;
}
return a[i].charAt(d);
}
// Rearranges the array of variable-length strings.
public static void sort(String[] a) {
int n = a.length;
int R = 256; // extended ASCII alphabet size.
String[] aux = new String[n];
int w = findLongestLength(a); // w is the length of longest string in a.
for (int d = w - 1; d >= 0; d--) {
// sort by key-indexed counting on dth character
// compute frequency counts
int[] count = new int[R + 1];
for (int i = 0; i < n; ++i) {
int c = findCharAtInString(i, d, a);
count[c + 1]++;
}
// compute cumulates
for (int r = 0; r < R; ++r) {
count[r + 1] += count[r];
}
// move data
for (int i = 0; i < n; ++i) {
int c = findCharAtInString(i, d, a);
aux[count[c]++] = a[i];
}
// copy back
for (int i = 0; i < n; ++i) {
a[i] = aux[i];
}
}
}
public static void main(String[] args) {
String[] a = {"38A", "3TW723", "2IYEA938", "3CI34780720"};
int n = a.length;
// sort the strings
sort(a);
// prints results
for (int i = 0; i < n; ++i) {
System.out.println(a[i]);
}
}
}
LSD sorts only fixed-length strings. Use MSD instead
When population oddList, evenList and negativeList from the inputList the program only populates it with one int instead of all corresponding ints from the inputList array. The output should be a list from each array whose numbers correspond to its title. The numbers are input by user into inputList array and then from there it determines whether it is odd, even, and negative and then fills the corresponding arrays.
I.E. evenList is filled with even ints from inputList.
public class ProjectTenOne
{
public static void main(String[] args)
{
int[] inputList = new int[10];
int[] oddList = null;
int[] evenList = null;
int[] negativeList = null;
int evenCount = 0;
int oddCount = 0;
int negCount = 0;
Scanner input = new Scanner(System.in);
//System.out.println("Enter any ten integers: ");
for(int list = 0; list < inputList.length; list++)
{
System.out.println("Enter any " + (inputList.length - list) + " integers: ");
inputList[list] = input.nextInt();
}
System.out.println();
System.out.println("The numbers you entered: ");
for(int in = 0; in < inputList.length; in++)
{
System.out.println(inputList[in]);
}
for(int ls = 0; ls< inputList.length; ls++)
{
if(inputList[ls] % 2 == 0)
{
evenCount = evenCount +1;
}
if(inputList[ls] % 2 != 0)
{
oddCount = oddCount +1;
}
if(inputList[ls] < 0)
{
negCount = negCount +1;
}
}
evenList = new int[evenCount];
oddList = new int[oddCount];
negativeList = new int[negCount];
for(int l = 0; l < inputList.length; l++)
{
if((inputList[l] % 2) == 0)
{
for(int j = 0; j < evenList.length; j++)
{
evenList[j] = inputList[l];
}
}
if((inputList[l] % 2) != 0)
{
for(int k = 0; k < oddList.length; k++)
{
oddList[k] = inputList[l];
}
}
if(inputList[l] < 0)
{
for(int h = 0; h < negativeList.length; h++)
{
negativeList[h] = inputList[l];
}
}
}
System.out.println("The ODD List is: ");
for(int i = 0; i < oddList.length; i++)
{
System.out.println(oddList[i]);
}
System.out.println("The EVEN List is: ");
for(int j = 0; j < evenList.length; j++)
{
System.out.println(evenList[j]);
}
System.out.println("The NEGATIVE List is: ");
for(int k = 0; k < oddList.length; k++)
{
System.out.println(negativeList[k]);
}
}
}
I'll take evenList as the example here, but the same applies to the other two arrays as well.
In your code, you iterate over your inputList and check for an even number. If it is even, you set the entire evenList array to the found value, instead of just a single element.
You can solve this problem by declaring an int outside of your outer loop that keeps track of the number of even numbers entered. As an example:
int evenIndex = 0;
for(int l = 0; l < inputList.length; l++)
{
if((inputList[l] % 2) == 0)
{
evenList[evenIndex++] = inputList[l];
}
/*Other code*/
}
You also made a mistake in your last loop. You iterate over negativeList, but you use the size of evenList. This will result in an ArrayIndexOutOfBoundsException when negativeList is smaller than evenList.
I asked a question on helping me with this question about a week ago
Java permutations
, with a problem in the print permutation method. I have tidied up my code and have a working example that now works although if 5 is in the 5th position in the array it doesn't print it. Any help would be really appreciated.
package permutation;
public class Permutation {
static int DEFAULT = 100;
public static void main(String[] args) {
int n = DEFAULT;
if (args.length > 0)
n = Integer.parseInt(args[0]);
int[] OA = new int[n];
for (int i = 0; i < n; i++)
OA[i] = i + 1;
System.out.println("The original array is:");
for (int i = 0; i < OA.length; i++)
System.out.print(OA[i] + " ");
System.out.println();
System.out.println("A permutation of the original array is:");
OA = generateRandomPermutation(n);
printArray(OA);
printPermutation(OA);
}
static int[] generateRandomPermutation(int n)// (a)
{
int[] A = new int[n];
for (int i = 0; i < n; i++)
A[i] = i + 1;
for (int i = 0; i < n; i++) {
int r = (int) (Math.random() * (n));
int swap = A[r];
A[r] = A[i];
A[i] = swap;
}
return A;
}
static void printArray(int A[]) {
for (int i = 0; i < A.length; i++)
System.out.print(A[i] + " ");
System.out.println();
}
static void printPermutation(int[] p)
{
int n = p.length-1;
int j = 0;
int m;
int f = 0;
System.out.print("(");
while (f < n) {
m = p[j];
if (m == 0) {
do
f++;
while (p[f] == 0 && f < n);
j = f;
if (f != n)
System.out.print(")(");
}
else {
System.out.print(" " + m);
p[j] = 0;
j = m - 1;
}
}
System.out.print(" )");
}
}
I'm not too crazy about
int n = p.length-1;
followed by
while (f < n) {
So if p is 5 units long, and f starts at 0, then the loop will be from 0 to 3. That would seem to exclude the last element in the array.
You can use the shuffle method of the Collections class
Integer[] arr = new Integer[] { 1, 2, 3, 4, 5 };
List<Integer> arrList = Arrays.asList(arr);
Collections.shuffle(arrList);
System.out.println(arrList);
I don't think swapping each element with a random other element will give a uniform distribution of permutations. Better to select uniformly from the remaining values:
Random rand = new Random();
ArrayList<Integer> remainingValues = new ArrayList<Integer>(n);
for(int i = 0; i < n; i++)
remainingValues.add(i);
for(int i = 0; i < n; i++) {
int next = rand.nextInt(remainingValues.size());
result[i] = remainingValues.remove(next);
}
Note that if order of running-time is a concern, using an ArrayList in this capacity is n-squared time. There are data-structures which could handle this task in n log n time but they are very non-trivial.
This does not answer the problem you have identified.
Rather i think it identifies a mistake with your generateRandomPermutation(int n) proc.
If you add a print out of the random numbers generated (as i did below) and run the proc a few times it allows us to check if all the elements in the ARRAY TO BE permed are being randomly selected.
static int[] generateRandomPermutation(int n)
{
int[] A = new int[n];
for (int i = 0; i < n; i++)
A[i] = i + 1;
System.out.println("random nums generated are: ");
for (int i = 0; i < n; i++) {
int r = (int) (Math.random() * (n));
System.out.print(r + " ");
Run the proc several times.
Do you see what i see?
Jerry.