| @@ -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 | |||
| } | |||
| @@ -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 | |||
| @@ -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,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); | |||
| } | |||
| } | |||
| @@ -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); | |||
| } | |||
| } | |||