From f86111a466ce3d83de1e1f99246475af350c8839 Mon Sep 17 00:00:00 2001 From: Apollyon094 <51381090+Apollyon094@users.noreply.github.com> Date: Fri, 18 Oct 2019 14:47:58 -0700 Subject: [PATCH 1/7] Add files via upload --- src/sorts/ApollyonSort.java | 99 +++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 src/sorts/ApollyonSort.java diff --git a/src/sorts/ApollyonSort.java b/src/sorts/ApollyonSort.java new file mode 100644 index 00000000..dcc7a0ce --- /dev/null +++ b/src/sorts/ApollyonSort.java @@ -0,0 +1,99 @@ +package sorts; + +import templates.Sort; +import templates.CircleSorting; +import utils.Delays; +import utils.Highlights; +import utils.Reads; +import utils.Writes; + +/* + * This version of Bitonic Sort was taken from here, written by H.W. Lang: + * http://www.inf.fh-flensburg.de/lang/algorithmen/sortieren/bitonic/oddn.htm + */ + +final public class ApollyonSort extends CircleSorting { + private boolean direction = true; + + public ApollyonSort(Delays delayOps, Highlights markOps, Reads readOps, Writes writeOps) { + super(delayOps, markOps, readOps, writeOps); + + this.setSortPromptID("Apollyon"); + this.setRunAllID("Apollyon's Bitonic Sort"); + this.setReportSortID("Apollyon's Bitonic Sort"); + this.setCategory("Hybrid Sorts"); + this.isComparisonBased(true); + this.isBucketSort(false); + this.isRadixSort(false); + this.isUnreasonablySlow(false); + this.setUnreasonableLimit(0); + this.isBogoSort(false); + } + + private static int greatestPowerOfTwoLessThan(int n){ + int k = 1; + while (k < n) { + k = k << 1; + } + return k >> 1; + } + + private void compare(int[] A, int i, int j, boolean dir) + { + Highlights.markArray(1, i); + Highlights.markArray(2, j); + + Delays.sleep(0.5); + + int cmp = Reads.compare(A[i], A[j]); + + if (dir == (cmp == 1)) Writes.swap(A, i, j, 1, true, false); + } + + private void bitonicMerge(int[] A, int lo, int n, boolean dir) + { + if (n > 1) + { + int m = ApollyonSort.greatestPowerOfTwoLessThan(n); + + for (int i = lo; i < lo + n - m; i++) { + this.compare(A, i, i+m, dir); + } + + this.bitonicMerge(A, lo, m, dir); + } + } + + private void bitonicSort(int[] A, int lo, int n, boolean dir) + { + if (n > 1) + { + int m = n / 2; + this.bitonicSort(A, lo, m, !dir); + this.bitonicMerge(A, lo, n, dir); + } + } + + public void changeDirection(String choice) throws Exception { + if(choice.equals("forward")) this.direction = true; + else if(choice.equals("backward")) this.direction = false; + else throw new Exception("Invalid direction for Bitonic Sort!"); + } + + @Override + public void runSort(int[] array, int currentLength, int bucketCount) { + int iterations = 0; + int threshold = (int) (Math.log(currentLength) / Math.log(3)) / 2; + + this.bitonicSort(array, 0, currentLength, this.direction); + do { + iterations++; + + if(iterations >= threshold) { + BinaryInsertionSort binaryInserter = new BinaryInsertionSort(this.Delays, this.Highlights, this.Reads, this.Writes); + binaryInserter.customBinaryInsert(array, 0, currentLength, 0.1); + break; + } + } while (this.circleSortRoutine(array, 0, currentLength - 1, 0) != 0); + } +} \ No newline at end of file From 006e04b8316202c918e837615469da78ac53a857 Mon Sep 17 00:00:00 2001 From: Apollyon094 <51381090+Apollyon094@users.noreply.github.com> Date: Fri, 18 Oct 2019 15:17:13 -0700 Subject: [PATCH 2/7] Update ApollyonSort.java --- src/sorts/ApollyonSort.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/sorts/ApollyonSort.java b/src/sorts/ApollyonSort.java index dcc7a0ce..f4f59355 100644 --- a/src/sorts/ApollyonSort.java +++ b/src/sorts/ApollyonSort.java @@ -61,6 +61,7 @@ private void bitonicMerge(int[] A, int lo, int n, boolean dir) } this.bitonicMerge(A, lo, m, dir); + this.bitonicMerge(A, lo + m, n - m, dir); } } @@ -96,4 +97,4 @@ public void runSort(int[] array, int currentLength, int bucketCount) { } } while (this.circleSortRoutine(array, 0, currentLength - 1, 0) != 0); } -} \ No newline at end of file +} From 39d0f4793ea68c98b7771b5ea5b76b97d87a9a02 Mon Sep 17 00:00:00 2001 From: Apollyon094 <51381090+Apollyon094@users.noreply.github.com> Date: Mon, 28 Oct 2019 18:12:59 -0700 Subject: [PATCH 3/7] Update ApollyonSort.java --- src/sorts/ApollyonSort.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sorts/ApollyonSort.java b/src/sorts/ApollyonSort.java index f4f59355..fc45c3ef 100644 --- a/src/sorts/ApollyonSort.java +++ b/src/sorts/ApollyonSort.java @@ -59,7 +59,6 @@ private void bitonicMerge(int[] A, int lo, int n, boolean dir) for (int i = lo; i < lo + n - m; i++) { this.compare(A, i, i+m, dir); } - this.bitonicMerge(A, lo, m, dir); this.bitonicMerge(A, lo + m, n - m, dir); } @@ -84,7 +83,7 @@ public void changeDirection(String choice) throws Exception { @Override public void runSort(int[] array, int currentLength, int bucketCount) { int iterations = 0; - int threshold = (int) (Math.log(currentLength) / Math.log(3)) / 2; + int threshold = (int) (Math.log(currentLength) / Math.log(2)) / 2; this.bitonicSort(array, 0, currentLength, this.direction); do { From 56b287a36c32bedcc0792a56e31aafc90252a895 Mon Sep 17 00:00:00 2001 From: Apollyon094 <51381090+Apollyon094@users.noreply.github.com> Date: Mon, 28 Oct 2019 18:13:53 -0700 Subject: [PATCH 4/7] Add files via upload stupid bitonic sort --- src/sorts/STBSort.java | 101 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) create mode 100644 src/sorts/STBSort.java diff --git a/src/sorts/STBSort.java b/src/sorts/STBSort.java new file mode 100644 index 00000000..2d78fd28 --- /dev/null +++ b/src/sorts/STBSort.java @@ -0,0 +1,101 @@ +package sorts; + +import templates.Sort; +import templates.CircleSorting; +import utils.Delays; +import utils.Highlights; +import utils.Reads; +import utils.Writes; + +/* + * This version of Bitonic Sort was taken from here, written by H.W. Lang: + * http://www.inf.fh-flensburg.de/lang/algorithmen/sortieren/bitonic/oddn.htm + */ + +final public class STBSort extends CircleSorting { + private boolean direction = true; + + public STBSort(Delays delayOps, Highlights markOps, Reads readOps, Writes writeOps) { + super(delayOps, markOps, readOps, writeOps); + + this.setSortPromptID("Stupid Bitonic"); + this.setRunAllID("Stupid Bitonic Sort"); + this.setReportSortID("Stupid Bitonic Sort"); + this.setCategory("Concurrent Sorts"); + this.isComparisonBased(true); + this.isBucketSort(false); + this.isRadixSort(false); + this.isUnreasonablySlow(false); + this.setUnreasonableLimit(0); + this.isBogoSort(false); + } + + private static int greatestPowerOfTwoLessThan(int n){ + int k = 1; + while (k < n) { + k = k << 1; + } + return k >> 1; + } + + private void compare(int[] A, int i, int j, boolean dir) + { + Highlights.markArray(1, i); + Highlights.markArray(2, j); + + Delays.sleep(0.5); + + int cmp = Reads.compare(A[i], A[j]); + + if (dir == (cmp == 1)) Writes.swap(A, i, j, 1, true, false); + } + + private void bitonicMerge(int[] A, int lo, int n, boolean dir) + { + if (n > 1) + { + int m = STBSort.greatestPowerOfTwoLessThan(n); + + for (int i = lo; i < lo + n - m; i++) { + this.compare(A, i, i+m, dir); + } + + this.bitonicSort(A, lo + m, n - m, dir); + this.bitonicMerge(A, lo, m, dir); + this.bitonicMerge(A, lo + m, n - m, dir); + } + } + + private void bitonicSort(int[] A, int lo, int n, boolean dir) + { + if (n > 1) + { + int m = n / 2; + this.bitonicSort(A, lo, m, !dir); + this.bitonicMerge(A, lo, n, dir); + } + } + + public void changeDirection(String choice) throws Exception { + if(choice.equals("forward")) this.direction = true; + else if(choice.equals("backward")) this.direction = false; + else throw new Exception("Invalid direction for Bitonic Sort!"); + } + + @Override + public void runSort(int[] array, int currentLength, int bucketCount) { + int iterations = 0; + int threshold = (int) (Math.log(currentLength) / Math.log(3)) / 2; + + this.bitonicSort(array, 0, currentLength, this.direction); + do { + iterations++; + + if(iterations >= threshold) { + BinaryInsertionSort binaryInserter = new BinaryInsertionSort(this.Delays, this.Highlights, this.Reads, this.Writes); + binaryInserter.customBinaryInsert(array, 0, currentLength, 0.1); + break; + } + } while (this.circleSortRoutine(array, 0, currentLength - 1, 0) != 0); + } +} From 5b61831193b36dce53f6a307aacadbfbe0b2ff35 Mon Sep 17 00:00:00 2001 From: Apollyon094 <51381090+Apollyon094@users.noreply.github.com> Date: Mon, 28 Oct 2019 19:11:55 -0700 Subject: [PATCH 5/7] Update STBSort.java --- src/sorts/STBSort.java | 33 +++++++++++---------------------- 1 file changed, 11 insertions(+), 22 deletions(-) diff --git a/src/sorts/STBSort.java b/src/sorts/STBSort.java index 2d78fd28..50a1e72b 100644 --- a/src/sorts/STBSort.java +++ b/src/sorts/STBSort.java @@ -1,7 +1,6 @@ package sorts; import templates.Sort; -import templates.CircleSorting; import utils.Delays; import utils.Highlights; import utils.Reads; @@ -12,15 +11,15 @@ * http://www.inf.fh-flensburg.de/lang/algorithmen/sortieren/bitonic/oddn.htm */ -final public class STBSort extends CircleSorting { +final public class STBSort extends Sort { private boolean direction = true; public STBSort(Delays delayOps, Highlights markOps, Reads readOps, Writes writeOps) { super(delayOps, markOps, readOps, writeOps); - this.setSortPromptID("Stupid Bitonic"); - this.setRunAllID("Stupid Bitonic Sort"); - this.setReportSortID("Stupid Bitonic Sort"); + this.setSortPromptID("STB"); + this.setRunAllID("STB Sort"); + this.setReportSortID("STB Sort"); this.setCategory("Concurrent Sorts"); this.isComparisonBased(true); this.isBucketSort(false); @@ -60,9 +59,8 @@ private void bitonicMerge(int[] A, int lo, int n, boolean dir) this.compare(A, i, i+m, dir); } - this.bitonicSort(A, lo + m, n - m, dir); - this.bitonicMerge(A, lo, m, dir); - this.bitonicMerge(A, lo + m, n - m, dir); + this.bitonicSort(A, lo, m, dir); + this.bitonicMerge(A, lo + m, n - m, dir); } } @@ -72,7 +70,9 @@ private void bitonicSort(int[] A, int lo, int n, boolean dir) { int m = n / 2; this.bitonicSort(A, lo, m, !dir); - this.bitonicMerge(A, lo, n, dir); + this.bitonicSort(A, lo + m, n - m, dir); + this.bitonicMerge(A, lo, n, dir); + this.bitonicSort(A, lo, m, dir); } } @@ -81,21 +81,10 @@ public void changeDirection(String choice) throws Exception { else if(choice.equals("backward")) this.direction = false; else throw new Exception("Invalid direction for Bitonic Sort!"); } + @Override public void runSort(int[] array, int currentLength, int bucketCount) { - int iterations = 0; - int threshold = (int) (Math.log(currentLength) / Math.log(3)) / 2; - - this.bitonicSort(array, 0, currentLength, this.direction); - do { - iterations++; - - if(iterations >= threshold) { - BinaryInsertionSort binaryInserter = new BinaryInsertionSort(this.Delays, this.Highlights, this.Reads, this.Writes); - binaryInserter.customBinaryInsert(array, 0, currentLength, 0.1); - break; - } - } while (this.circleSortRoutine(array, 0, currentLength - 1, 0) != 0); + this.bitonicSort(array, 0, currentLength, this.direction); } } From 25687390b97f47f0849b3da36e8f2cf0f0e10478 Mon Sep 17 00:00:00 2001 From: Apollyon094 <51381090+Apollyon094@users.noreply.github.com> Date: Tue, 29 Oct 2019 15:05:34 -0700 Subject: [PATCH 6/7] Update ApollyonSort.java --- src/sorts/ApollyonSort.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sorts/ApollyonSort.java b/src/sorts/ApollyonSort.java index fc45c3ef..7b02c7f0 100644 --- a/src/sorts/ApollyonSort.java +++ b/src/sorts/ApollyonSort.java @@ -1,3 +1,6 @@ +///ApollyonSort is a modification of BitonicSort that replaces one operation with CircleSort, and then once the array is almost sorted to an extent, it uses an InsertionSort with a LinearSearch +///It is usually just as fast as BitonicSort, if not 1 ms slower. It is made for real world data such as almost sorted arrays and backwards arrays. On these types of arrays ApollyonSort outperforms BitonicSort +///Features: In-Place, Parallel, Recursive (can be modified to iterative), Unstable, Uses comparisons. package sorts; import templates.Sort; @@ -90,8 +93,8 @@ public void runSort(int[] array, int currentLength, int bucketCount) { iterations++; if(iterations >= threshold) { - BinaryInsertionSort binaryInserter = new BinaryInsertionSort(this.Delays, this.Highlights, this.Reads, this.Writes); - binaryInserter.customBinaryInsert(array, 0, currentLength, 0.1); + InsertionSort linearInserter = new InsertionSort(this.Delays, this.Highlights, this.Reads, this.Writes); + linearInserter.customInsertSort(array, 0, currentLength, 0.1, false); break; } } while (this.circleSortRoutine(array, 0, currentLength - 1, 0) != 0); From 101d840f5abd93af457caed2b75822ad89a349a4 Mon Sep 17 00:00:00 2001 From: Apollyon094 <51381090+Apollyon094@users.noreply.github.com> Date: Tue, 29 Oct 2019 15:20:27 -0700 Subject: [PATCH 7/7] Create DrunkMergeSort --- src/sorts/DrunkMergeSort | 106 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 src/sorts/DrunkMergeSort diff --git a/src/sorts/DrunkMergeSort b/src/sorts/DrunkMergeSort new file mode 100644 index 00000000..5e134d39 --- /dev/null +++ b/src/sorts/DrunkMergeSort @@ -0,0 +1,106 @@ +///Taken from https://github.com/PiotrGrochowski/ArrayVisualizer/blob/master/src/sorts/DrunkMergeSort.java. I also made this sort back on scratch. + +package sorts; + +import templates.Sort; +import utils.Delays; +import utils.Highlights; +import utils.Reads; +import utils.Writes; + +/* + * +MIT License + +Copyright (c) 2019 w0rthy + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + * + */ + +final public class DrunkMergeSort extends Sort { + public DrunkMergeSort(Delays delayOps, Highlights markOps, Reads readOps, Writes writeOps) { + super(delayOps, markOps, readOps, writeOps); + + this.setSortPromptID("Drunk Merge"); + this.setRunAllID("Drunk Merge Sort"); + this.setReportSortID("Drunk Mergesort"); + this.setCategory("Hybrid Sorts"); + this.isComparisonBased(true); + this.isBucketSort(false); + this.isRadixSort(false); + this.isUnreasonablySlow(false); + this.setUnreasonableLimit(0); + this.isBogoSort(false); + } + + private void drunkInsert(int[] arr, int start, int end) { + int pos; + + for(int j = start; j < end; j++){ + pos = j; + + Highlights.markArray(1, j); + Highlights.clearMark(2); + + while(pos > start && Reads.compare(arr[pos], arr[pos - 1]) < 1) { + Writes.swap(arr, pos, pos - 1, 0.2, true, false); + pos--; + } + } + } + + private void drunkMerge(int[] arr, int min, int max, int mid) { + int i = 1; + int target = (mid - min); + + while(i <= target) { + Writes.multiSwap(arr, mid + i, min + (i * 2) - 1, 0.05, true, false); + i++; + } + + this.drunkInsert(arr, min, max + 1); + } + + private void drunkMergeSort(int[] array, int min, int max) { + if(max - min == 0) { //only one element. + Delays.sleep(1); //no swap + } + else if(max - min == 1) { //only two elements and swaps them + if(Reads.compare(array[min], array[max]) == 1) { + Writes.swap(array, min, max, 0.01, true, false); + } + } + else { + int mid = (int) Math.floor((min + max) / 2); //The midpoint + + this.drunkMergeSort(array, min, mid); //sort the left side + this.drunkMergeSort(array, mid + 1, max); //sort the right side + this.drunkMerge(array, min, max, mid); //combines them + this.drunkMergeSort(array, min, mid); //sort the left side + this.drunkMergeSort(array, mid + 1, max); //sort the right side + this.drunkMerge(array, min, max, mid); //combines them + } + } + + @Override + public void runSort(int[] array, int currentLength, int bucketCount) { + this.drunkMergeSort(array, 0, currentLength - 1); + } +}