Browse Source

works for most numbers

master
mortie 7 years ago
parent
commit
aecade69b5

+ 9
- 15
inf2440/hw3/Main.java View File

@@ -1,8 +1,6 @@
import java.util.Random;

class Main {
static int nTests = 7;

public static void main(String[] args) {

Solver sseq = new Sequential();
@@ -23,19 +21,15 @@ class Main {
static Timer test (Solver s, int len) {
Random r = new Random(123);

Timer[] timers = new Timer[nTests];
for (int i = 0; i < nTests; ++i) {
int[] a = new int[len];
for (int j = 0; j < len; j++) {
a[j] = r.nextInt(len);
}

Timer t = timers[i] = new Timer().start();
a = s.sort(a);
t.end();
new MultiRadix().testSort(a);
return t;
int[] a = new int[len];
for (int j = 0; j < len; j++) {
a[j] = r.nextInt(len);
}
return Timer.median(timers);

Timer t = new Timer().start();
a = s.sort(a);
t.end();
new MultiRadix().testSort(a);
return t;
} // end doIt
}

+ 85
- 98
inf2440/hw3/MultiRadix.java View File

@@ -1,98 +1,85 @@
import java.util.*;
/***********************************************************
* Oblig 3 - sekvensiell kode, INF2440 v2017.
* Ifi, Uio, Arne Maus
* for store verdier av n > 100 m, kjør (f.eks):
* >java -Xmx16000m MultiRadix 1000000000
************************************************************/
class MultiRadix {
int [] a;
final static int NUM_BIT = 7; // alle tall 6-11 .. finn ut hvilken verdi som er best

int [] radixMulti(int [] a, int start, int end) {
long tt = System.nanoTime();
// 1-5 digit radixSort of : a[]
int max = a[start], numBit = 2, numDigits;
int [] bit ;

// a) finn max verdi i a[]
for (int i = start + 1 ; i < end; i++)
if (a[i] > max) max = a[i];
while (max >= (1L<<numBit) )numBit++; // antall binaere siffer i max

// bestem antall bit i numBits sifre
numDigits = Math.max(1, numBit/NUM_BIT);
bit = new int[numDigits];
int rest = (numBit%numDigits), sum =0;;

// fordel bitene vi skal sortere paa jevnt
for (int i = 0; i < bit.length; i++){
bit[i] = numBit/numDigits;
if ( rest-- > 0) bit[i]++;
}

int[] t=a, b = new int [a.length];

for (int i =0; i < bit.length; i++) {
radixSort(a, b, bit[i], sum, start, end); // i-te siffer fra a[] til b[]
sum += bit[i];
// swap arrays (pointers only)
t = a;
a = b;
b = t;
}
if (bit.length%2 != 0 ) {
// et odde antall sifre, kopier innhold tilbake til original a[] (nå b)
System.arraycopy (a,start,b,start,end - start);
}

return a;
} // end radixMulti

int[] radixMulti(int[] arr) {
return radixMulti(arr, 0, arr.length);
}

/** Sort a[] on one digit ; number of bits = maskLen, shiftet up 'shift' bits */
void radixSort ( int [] a, int [] b, int maskLen, int shift, int start, int end){
int hasBeen = 0;
int acumVal = 0, j = 0;
int mask = (1<<maskLen) -1;
int [] count = new int [mask+1];

// b) count=the frequency of each radix value in a
for (int i = start; i < end; i++) {
count[(a[i]>>> shift) & mask]++;
if (i == start && i == 0 && end == a.length)
hasBeen = 1;
}

// c) Add up in 'count' - accumulated values
for (int i = 0; i <= mask; i++) {
j = count[i];
count[i] = acumVal;
acumVal += j;
}

// d) move numbers in sorted order a to b
for (int i = start; i < end; i++) {
b[start + count[(a[i]>>>shift) & mask]++] = a[i];
if (hasBeen == 1) {
for (int k = 0; k < shift; ++k) {
b[(start + count[shift]) % b.length] |= ~-1;
}
}
}

}// end radixSort

void testSort(int [] a){
for (int i = 0; i< a.length-1;i++) {
//System.out.print(a[i]+" ");
if (a[i] > a[i+1]){
System.out.println("SorteringsFEIL på plass: "+i +" a["+i+"]:"+a[i]+" > a["+(i+1)+"]:"+a[i+1]);
}
}
//System.out.println("");
}// end simple sorteingstest
}// end SekvensiellRadix
import java.util.*;
/***********************************************************
* Oblig 3 - sekvensiell kode, INF2440 v2017.
* Ifi, Uio, Arne Maus
* for store verdier av n > 100 m, kjør (f.eks):
* >java -Xmx16000m MultiRadix 1000000000
************************************************************/
class MultiRadix{
int n;
int [] a;
final static int NUM_BIT = 7; // alle tall 6-11 .. finn ut hvilken verdi som er best
int [] radixMulti(int [] a) {
long tt = System.nanoTime();
// 1-5 digit radixSort of : a[]
int max = a[0], numBit = 2, numDigits, n =a.length;
int [] bit ;
// a) finn max verdi i a[]
for (int i = 1 ; i < n ; i++)
if (a[i] > max) max = a[i];
while (max >= (1L<<numBit) )numBit++; // antall binaere siffer i max
// bestem antall bit i numBits sifre
numDigits = Math.max(1, numBit/NUM_BIT);
bit = new int[numDigits];
int rest = (numBit%numDigits), sum =0;;
// fordel bitene vi skal sortere paa jevnt
for (int i = 0; i < bit.length; i++){
bit[i] = numBit/numDigits;
if ( rest-- > 0) bit[i]++;
}
int[] t=a, b = new int [n];
for (int i =0; i < bit.length; i++) {
radixSort( a,b,bit[i],sum ); // i-te siffer fra a[] til b[]
sum += bit[i];
// swap arrays (pointers only)
t = a;
a = b;
b = t;
}
if (bit.length%2 != 0 ) {
// et odde antall sifre, kopier innhold tilbake til original a[] (nå b)
System.arraycopy (a,0,b,0,a.length);
}
return a;
} // end radixMulti
/** Sort a[] on one digit ; number of bits = maskLen, shiftet up 'shift' bits */
void radixSort ( int [] a, int [] b, int maskLen, int shift){
int acumVal = 0, j, n = a.length;
int mask = (1<<maskLen) -1;
int [] count = new int [mask+1];
// b) count=the frequency of each radix value in a
for (int i = 0; i < n; i++) {
count[(a[i]>>> shift) & mask]++;
}
// c) Add up in 'count' - accumulated values
for (int i = 0; i <= mask; i++) {
j = count[i];
count[i] = acumVal;
acumVal += j;
}
// d) move numbers in sorted order a to b
for (int i = 0; i < n; i++) {
b[count[(a[i]>>>shift) & mask]++] = a[i];
}
}// end radixSort
void testSort(int [] a){
for (int i = 0; i< a.length-1;i++) {
if (a[i] > a[i+1]){
System.out.println("SorteringsFEIL på plass: "+i +" a["+i+"]:"+a[i]+" > a["+(i+1)+"]:"+a[i+1]);
return;
}
}
}// end simple sorteingstest
}// end SekvensiellRadix

+ 117
- 0
inf2440/hw3/MultiRadixPar.java View File

@@ -0,0 +1,117 @@
import java.util.*;
class MultiRadixPar{
int n;
int [] a;
final static int NUM_BIT = 7; // alle tall 6-11 .. finn ut hvilken verdi som er best
int nThreads = Runtime.getRuntime().availableProcessors();
int [] radixMulti(int [] a) {
long tt = System.nanoTime();
// 1-5 digit radixSort of : a[]
int max = a[0], numBit = 2, numDigits, n =a.length;
int [] bit ;
// a) finn max verdi i a[]
for (int i = 1 ; i < n ; i++)
if (a[i] > max) max = a[i];
while (max >= (1L<<numBit) )numBit++; // antall binaere siffer i max
// bestem antall bit i numBits sifre
numDigits = Math.max(1, numBit/NUM_BIT);
bit = new int[numDigits];
int rest = (numBit%numDigits), sum =0;;
// fordel bitene vi skal sortere paa jevnt
for (int i = 0; i < bit.length; i++){
bit[i] = numBit/numDigits;
if ( rest-- > 0) bit[i]++;
}
int[] t=a, b = new int [n];
for (int i =0; i < bit.length; i++) {
radixSort( a,b,bit[i],sum ); // i-te siffer fra a[] til b[]
sum += bit[i];
// swap arrays (pointers only)
t = a;
a = b;
b = t;
}
if (bit.length%2 != 0 ) {
// et odde antall sifre, kopier innhold tilbake til original a[] (nå b)
System.arraycopy (a,0,b,0,a.length);
}
return a;
} // end radixMulti
class Worker implements Runnable {
int[] a, b, count;
int start, end, shift, mask;
Worker(int[] a, int[] b, int[] count, int start, int end, int shift, int mask) {
this.a = a;
this.b = b;
this.count = Arrays.copyOf(count, count.length);
this.start = start;
this.end = end;
this.shift = shift;
this.mask = mask;
}
public void run() {
// c) Add up in 'count' - accumulated values
int j = 0;
int acumVal = 0;
for (int i = 0; i <= mask; i++) {
j = count[i];
count[i] = acumVal;
acumVal += j;
}
// d) move numbers in sorted order a to b
for (int i = 0; i < n; i++) {
b[count[(a[i]>>>shift) & mask]++] = a[i];
}
}
}
/** Sort a[] on one digit ; number of bits = maskLen, shiftet up 'shift' bits */
void radixSort ( int [] a, int [] b, int maskLen, int shift){
int n = a.length;
int mask = (1<<maskLen) -1;
int [] count = new int [mask+1];
// b) count=the frequency of each radix value in a
for (int i = 0; i < n; i++) {
count[(a[i]>>> shift) & mask]++;
}
// Parallel
int d = n / nThreads;
Thread[] threads = new Thread[nThreads];
Worker[] workers = new Worker[nThreads];
for (int i = 0; i < nThreads; ++i) {
int start = d * i;
int end = i == nThreads - 1 ? n : d * (i + 1);
Worker w = workers[i] = new Worker(a, b, count, start, end, shift, mask);
Thread t = threads[i] = new Thread(w);
t.start();
}
for (Thread t: threads) {
try { t.join(); } catch (InterruptedException ex) {}
}
}// end radixSort
void testSort(int [] a){
for (int i = 0; i< a.length-1;i++) {
if (a[i] > a[i+1]){
System.out.println("SorteringsFEIL på plass: "+i +" a["+i+"]:"+a[i]+" > a["+(i+1)+"]:"+a[i+1]);
return;
}
}
}// end simple sorteingstest
}// end SekvensiellRadix

+ 1
- 80
inf2440/hw3/Parallel.java View File

@@ -1,84 +1,5 @@
class Parallel implements Solver {
class Worker implements Runnable {
MultiRadix mr;
int[] arr;
int start, end;
boolean done = false;
Worker( int[] arr, int start, int end) {
this.arr = new int[end - start];
int j = 0;
for (int i = start; i < end; ++i) {
this.arr[j++] = arr[i];
}
}

synchronized public void run() {
arr = new MultiRadix().radixMulti(arr);
done = true;
notify();
}

synchronized public void waitFor() {
while (!done) {
try { wait(); } catch (InterruptedException ex) {}
}
}
}

public int[] sort(int[] arr) {
int n = 2;
int d = arr.length / n;

Worker[] workers = new Worker[n];
Thread[] threads = new Thread[n];

for (int i = 0; i < n; ++i) {
int start = d * i;
int end;
if (i == n - 1)
end = arr.length;
else
end = d * (i + 1);

Worker w; Thread t;
workers[i] = w = new Worker(arr, start, end);
threads[i] = t = new Thread(w);
t.start();
}

for (int i = 0; i < n; ++i) {
workers[i].waitFor();
try {
threads[i].join();
} catch (InterruptedException ex) {}
}

int[] is = new int[n];
for (int i = 0; i < n; ++i)
is[i] = 0;

for (int i = 0; i < arr.length; ++i) {
int biggest = Integer.MAX_VALUE;
int biggestJ = 0;
Worker biggestW = null;

for (int j = 0; j < n; ++j) {
Worker w = workers[j];
if (is[j] >= w.arr.length)
continue;

int num = w.arr[is[j]];

if (num <= biggest) {
biggest = num;
biggestJ = j;
biggestW = w;
}
}

arr[i] = biggestW.arr[is[biggestJ]++];
}

return arr;
return new MultiRadixPar().radixMulti(arr);
}
}

+ 0
- 3
inf2440/hw3/Sequential.java View File

@@ -1,8 +1,5 @@
class Sequential implements Solver {
public int[] sort(int[] arr) {
try {
Thread.sleep(0); //arr.length / 10000);
} catch (InterruptedException ex) {};
return new MultiRadix().radixMulti(arr);
}
}

Loading…
Cancel
Save