Commit a48471b6 authored by Eddie Schoute's avatar Eddie Schoute
Browse files

Refactoring code

Move tests to test folder
Move source code to source folder (reversal_sort)
parent 0d0d0679
import csv import csv
import SBR
import AdaptiveTBS
import TripartiteBinarySort
from itertools import permutations from itertools import permutations
from math import factorial from math import factorial
import random import random
from reversal_sort import SBR, adaptive_tbs, tripartite_binary_sort
""" """
Collects routing time data for the algorithms GDC(TBS), GDC(ATBS), and OES. Collects routing time data for the algorithms GDC(TBS), GDC(ATBS), and OES.
Spits out the data into csv files in the "/data/" directory. Spits out the data into csv files in the "/data/" directory.
...@@ -118,7 +117,7 @@ def new_rand_perms_file(alglist, algnames, nlist, count): ...@@ -118,7 +117,7 @@ def new_rand_perms_file(alglist, algnames, nlist, count):
def main(NUM_PERMS_PER_LENGTH, LENGTH_FROM, LENGTH_TO): def main(NUM_PERMS_PER_LENGTH, LENGTH_FROM, LENGTH_TO):
algnames = ['OES', 'GDC(TBS)', 'GDC(ATBS)'] algnames = ['OES', 'GDC(TBS)', 'GDC(ATBS)']
algs = [SBR.odd_even_sort, TripartiteBinarySort.GDC_TBS, AdaptiveTBS.GDC_ATBS] algs = [SBR.odd_even_sort, tripartite_binary_sort.GDC_TBS, adaptive_tbs.GDC_ATBS]
new_rand_perms_file(algs, algnames, list(range(LENGTH_FROM,LENGTH_TO + 1)), NUM_PERMS_PER_LENGTH) new_rand_perms_file(algs, algnames, list(range(LENGTH_FROM,LENGTH_TO + 1)), NUM_PERMS_PER_LENGTH)
...@@ -127,5 +126,8 @@ if __name__ == "__main__": ...@@ -127,5 +126,8 @@ if __name__ == "__main__":
import sys import sys
for line in sys.stdin: for line in sys.stdin:
perm = [int(el) for el in line.split()] perm = [int(el) for el in line.split()]
reversals = TripartiteBinarySort.permutationsort_divideconquer_tbs(perm) # Check if is permutation
if set(range(0, len(perm))) != set(perm):
raise ValueError(f"Given permutation does not contain all elements in [0,{len(perm)-1}].")
reversals = tripartite_binary_sort.routing_divideconquer_tbs(perm)
print(reversals) # TODO: Implement pretty print print(reversals) # TODO: Implement pretty print
\ No newline at end of file
[[package]]
name = "autopep8"
version = "1.5.5"
description = "A tool that automatically formats Python code to conform to the PEP 8 style guide"
category = "dev"
optional = false
python-versions = "*"
[package.dependencies]
pycodestyle = ">=2.6.0"
toml = "*"
[[package]]
name = "pycodestyle"
version = "2.6.0"
description = "Python style guide checker"
category = "dev"
optional = false
python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
[[package]]
name = "toml"
version = "0.10.2"
description = "Python Library for Tom's Obvious, Minimal Language"
category = "dev"
optional = false
python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
[metadata]
lock-version = "1.1"
python-versions = "^3.8"
content-hash = "69f8da9bda3c52f2aeef6c0b305a37c17ebe7dbf3e7e7433d3c962a6fa6f07ed"
[metadata.files]
autopep8 = [
{file = "autopep8-1.5.5-py2.py3-none-any.whl", hash = "sha256:9e136c472c475f4ee4978b51a88a494bfcd4e3ed17950a44a988d9e434837bea"},
{file = "autopep8-1.5.5.tar.gz", hash = "sha256:cae4bc0fb616408191af41d062d7ec7ef8679c7f27b068875ca3a9e2878d5443"},
]
pycodestyle = [
{file = "pycodestyle-2.6.0-py2.py3-none-any.whl", hash = "sha256:2295e7b2f6b5bd100585ebcb1f616591b652db8a741695b3d8f5d28bdc934367"},
{file = "pycodestyle-2.6.0.tar.gz", hash = "sha256:c58a7d2815e0e8d7972bf1803331fb0152f867bd89adf8a01dfd55085434192e"},
]
toml = [
{file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
{file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
]
[tool.poetry]
name = "reversal-sort"
version = "0.1.0"
description = ""
authors = ["None"]
[tool.poetry.dependencies]
python = "^3.8"
[tool.poetry.dev-dependencies]
autopep8 = "^1.5.5"
[build-system]
requires = ["poetry-core>=1.0.0"]
build-backend = "poetry.core.masonry.api"
import SBR
import math import math
import random
import timeit from . import SBR
def GDC_ATBS(perm): def GDC_ATBS(perm):
...@@ -150,11 +149,4 @@ def sequential_permutation_sort_parallelized(perm, i, j): ...@@ -150,11 +149,4 @@ def sequential_permutation_sort_parallelized(perm, i, j):
m = (i + j) // 2 m = (i + j) // 2
SBR.apply_revs(offsetrevs, perm) SBR.apply_revs(offsetrevs, perm)
return offsetrevs + sequential_permutation_sort_parallelized(perm, i, m) + \ return offsetrevs + sequential_permutation_sort_parallelized(perm, i, m) + \
sequential_permutation_sort_parallelized(perm, m + 1, j) sequential_permutation_sort_parallelized(perm, m + 1, j)
\ No newline at end of file
if __name__ == '__main__':
print(GDC_ATBS([8,7,6,5,4,3,2,1]))
from . import SBR, tripartite_binary_sort
def GDC_TBS(perm):
"""
Returns the cost to sort perm using TBS as the binary sorting sequence.
(GenericDivideConquer_TripartiteBinarySort)
"""
revlist = routing_divideconquer_tbs(perm, 0, len(perm) - 1)
cost = SBR.compress_reversals(revlist, len(perm)) / 3
return cost
def perm_to_01(L, i, j):
"""
TUrns a permutation L[i:j] into a permutation of 0s and 1s, where L[i] is 0 if it is
less than the median and L[i] is 1 if it is greater than the median
"""
subseq = L[i:j + 1]
sorted_subseq = sorted(subseq)
median = (j - i) // 2
return L[:i] + [int(sorted_subseq.index(k) > median) for k in subseq] + L[j + 1:]
def routing_divideconquer_tbs(L, i=None, j=None):
"""
Sorts the given permutations L from index i to j (inclusive) using a divide and conquer approach. Returns a list of
reversals used to perform the sort.
"""
# Set default params
if i == None:
i = min(L)
if j == None:
j = max(L)
if i == j:
return []
T = perm_to_01(L, i, j)
revs = tripartite_binary_sort.tripartite_binary_sort(T, i, j)
m = (i + j) // 2
SBR.apply_revs(revs, L)
return revs + routing_divideconquer_tbs(L, i, m) + routing_divideconquer_tbs(L, m + 1, j)
import SBR
import math
import itertools
import random
from itertools import permutations
""" """
TripartiteBinarySort.py -- Implementation of the TBS algorithm for sorting bitstrings and permutations, Implementation of the TBS algorithm for sorting bitstrings and permutations,
along with a couple testing/analysis functions along with a couple testing/analysis functions
""" """
import math
def GDC_TBS(perm): from . import SBR
"""
Returns the cost to sort perm using TBS as the binary sorting sequence.
(GenericDivideConquer_TripartiteBinarySort)
"""
revlist = permutationsort_divideconquer_tbs(perm, 0, len(perm) - 1)
cost = SBR.compress_reversals(revlist, len(perm)) / 3
return cost
def tripartite_binary_sort(T, i, j): def tripartite_binary_sort(T, i, j):
""" """
...@@ -63,37 +50,6 @@ def zero_one_indices(T, i, j): ...@@ -63,37 +50,6 @@ def zero_one_indices(T, i, j):
break break
return oneind, zerind return oneind, zerind
def perm_to_01(L, i, j):
"""
TUrns a permutation L[i:j] into a permutation of 0s and 1s, where L[i] is 0 if it is
less than the median and L[i] is 1 if it is greater than the median
"""
subseq = L[i:j + 1]
sorted_subseq = sorted(subseq)
median = (j - i) // 2
return L[:i] + [int(sorted_subseq.index(k) > median) for k in subseq] + L[j + 1:]
def permutationsort_divideconquer_tbs(L, i=None, j=None):
"""
Sorts the given permutations L from index i to j (inclusive) using a divide and conquer approach. Returns a list of
reversals used to perform the sort.
"""
# Set default params
if i == None:
i = min(L)
if j == None:
j = max(L)
if i == j:
return []
T = perm_to_01(L, i, j)
revs = tripartite_binary_sort(T, i, j)
m = (i + j) // 2
SBR.apply_revs(revs, L)
return revs + permutationsort_divideconquer_tbs(L, i, m) + permutationsort_divideconquer_tbs(L, m + 1, j)
def all_binary_lists_equal(n): def all_binary_lists_equal(n):
""" """
generates list of lists, where each list is a binary sequence of length n, generates list of lists, where each list is a binary sequence of length n,
...@@ -116,40 +72,4 @@ def all_binary_lists_equal(n): ...@@ -116,40 +72,4 @@ def all_binary_lists_equal(n):
lis = [] lis = []
blep(n, [], 0, 0, lis) blep(n, [], 0, 0, lis)
return lis return lis
\ No newline at end of file
def test_binary_sort():
"""
Testing correctness of sorting bitstrings with TBS.
"""
wrong = 0
for i in range(1000):
l = [0]*random.randint(100,200) + [1]*random.randint(100,200)
random.shuffle(l)
before = l.copy()
#print(before)
tripartite_binary_sort(l, 0 , len(l)-1)
#print(l, '\n')
if l != sorted(before):
print("failed")
print("passed")
def test_perm_sort():
"""
Testing correctness of sorting permutations with TBS as
bitstring sorting subroutine.
Returns number
"""
wrong = 0
n = 1000
for ct in range(n):
L = list(range(1,random.randint(5, 200)))
random.shuffle(L)
before = L.copy()
permutationsort_divideconquer_tbs(L,0,len(L)-1)
#print(before, '\n', L, '\n')
if L != sorted(before):
print("failed")
return
print("passed")
import random
from reversal_sort import routing
from unittest import TestCase
class TestRourting(TestCase):
def test_perm_sort(self):
"""
Testing correctness of sorting permutations with TBS as
bitstring sorting subroutine.
Returns number
"""
n = 1000
for ct in range(n):
L = list(range(1,random.randint(5, 200)))
random.shuffle(L)
before = L.copy()
routing.routing_divideconquer_tbs(L,0,len(L)-1)
self.assertEqual(sorted(before), L)
\ No newline at end of file
import random
from reversal_sort import TripartiteBinarySort
from unittest import TestCase
class TestTBS(TestCase):
def test_binary_sort(self):
"""
Testing correctness of sorting bitstrings with TBS.
"""
for i in range(1000):
l = [0]*random.randint(100,200) + [1]*random.randint(100,200)
random.shuffle(l)
before = l.copy()
#print(before)
TripartiteBinarySort.tripartite_binary_sort(l, 0 , len(l)-1)
#print(l, '\n')
self.assertEqual(sorted(before), l)
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment