Wednesday, March 16, 2011

k random numbers from n


import java.util.*;
/** There is a linked list of numbers of length N. N is very large and you don't know N.
* You have to write a function that will return k random numbers from the list.
* Numbers should be completely random.
*/
public class KrandN {

public class Number implements Comparable<Number> {
private int value;
Number(int v) {
value = v;
}
public int getValue() {return value;}
public String toString(){
return ""+value;
}
public int compareTo(Number other) {
return value - other.value;
}
}
public class KNumber implements Comparable<KNumber> {
private int k;
private Number num;
KNumber(int v, int k) {
this.num = new Number(v);
this.k = k;
}
public int getValue() {return num.getValue();}
public int getK() {return k;}
public String toString(){
return "[k:"+k+","+getValue()+"]";
}
public int compareTo(KNumber other) {
return k - other.k;
}
}

/* traverse the list, generating a new random number for each entry.
* remember the top k highest random numbers, and their associated entries.
* When we hit the end of the list, the numbers in the chart are the required random numbers.
*/
public PriorityQueue<KNumber> krandn(Vector<Number> list) {
PriorityQueue<KNumber> p = new PriorityQueue<KNumber>();
int size = list.size();
System.out.println("\n\nrands for k including repeats, PriorityQueue will take care of it:");
for (Number n : list) {
int r=rand.nextInt(size);
System.out.print(","+r);
KNumber k = new KNumber(n.getValue(), r);
p.add(k);
}
System.out.println("\n");
return p;
}

private static final int num=152;
private static final int maxnumk=20;
Vector<Number> list = new Vector<Number>();

public Vector<Number> shuffle(Vector<Number> list){
if (list == null || list.size() < num) {
System.out.println("\ninitialize list");
list = new Vector<Number>(); // new list
for (int i=0; i<num; i++) {
Number c = new Number(i);
list.add(c);
}
}
int [] arr = new int[num];
int j=0;
for (Number n : list) {
arr[j++] = n.getValue();
}
shuffleArr(arr);
list = new Vector<Number>(); // new list
for (int i=0; i<num; i++) {
Number c = new Number(arr[i]);
list.add(c);
}
return list;
}
Random rand = new Random();
public void shuffleArr(int [] arr){
for (int i=0; i<arr.length-1; i++) {
int rnd = i+ rand.nextInt(arr.length-i);
//swap arr[i] and a[rnd]
int tmp = arr[i];
arr[i] = arr[rnd];
arr[rnd] = tmp;
}
}

public static void main(String[] args) {
KrandN inst = new KrandN();
Vector<Number> list = null;
list = inst.shuffle(list);
System.out.println("\nout:");
for (Number n : list) {
System.out.print(","+n.toString());
}
PriorityQueue<KNumber> p = inst.krandn(list);
System.out.println("\n top k list, random k elements (up to "+maxnumk+"):");
int i = 0;
while (!p.isEmpty() && i++ < maxnumk) {
KNumber n = p.remove();
System.out.print(","+n);
}

//System.out.println("\nsorted:");
//Collections.<Number>sort(list);
//for (Number n : list) {
// System.out.print(","+n.toString());
//}
}
}


top k list, random k elements (up to 20):
,[k:1,29],[k:2,27],[k:2,105],[k:4,23],[k:6,30],[k:7,64],[k:9,102],[k:9,8],[k:9,1
7],[k:11,82],[k:12,128],[k:13,58],[k:13,135],[k:13,145],[k:13,15],[k:14,109],[k:
16,126],[k:17,111],[k:19,37],[k:19,53]

No comments:

Post a Comment