Commit 4468b403 authored by Samuel King's avatar Samuel King
Browse files

Upload New File

parent 306a710e
import SBR
import math
import random
import timeit
def GDC_ATBS(perm):
"""
Sorts the given permutation by using a version of Tripartite Binary Sort using dynamic programming. Returns
the cost of sorting the permutation.
"""
revs = sequential_permutation_sort_parallelized(perm, 0, len(perm) - 1)
return SBR.compress_reversals(revs, len(perm)) / 3
def beginning_index_of_weight(w, v, i):
"""
Calculates and returns the first index of weight i.
"""
return v[i] + v[i - 1] - w[i]
def end_index_of_weight(w, v, j):
"""
Calculates and returns the last index of weight j.
"""
return v[j + 1] + v[j] - w[j + 1] - 1
def binary_to_weights(b):
"""
Converts the binary sequence into a sequence of weights starting with a 0-weight and ending with a 1-weight.
Returns a list of integers corresponding to this weight sequence.
"""
w = []
weight = 0
finding = 0
for ind in range(len(b)):
if b[ind] != finding:
finding = 1 - finding
w.append(weight)
weight = 1
else:
weight += 1
w.append(weight)
if finding == 0:
w.append(0)
return w
def weights_to_cumulative(w):
"""
Converts the given weight sequence into a cumulative weight sequence.
Returns a list of integers corresponding to this cumulative weight sequence.
"""
evensum = 0
oddsum = 0
v = []
for ind in range(len(w)):
if ind % 2 == 0:
evensum += w[ind]
v.append(evensum)
else:
oddsum += w[ind]
v.append(oddsum)
return v
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 binary_sort_parallel(b):
"""
Returns the reversals required to sort the given binary sequence using a parallelized version of the sequential
binary sort algorithm found in Bender et al.'s paper "Improved Bounds on Sorting by Length-Weighted Reversals".
The changes made to parallelize are made in equation (6).
"""
w = binary_to_weights(b)
v = weights_to_cumulative(w)
A = []
for i in range(len(w)):
A.append([])
for j in range(len(w)):
A[i].append([[0, []], [0, []]])
for j in range(1, len(w) - 1):
for i in range(j - 1, 0, -1):
fill_4_parallel(w, v, A, i, j, i % 2)
fill_4_parallel(w, v, A, i, j, (i + 1) % 2)
return A[1][len(w) - 2][0][1]
def fill_4_parallel(w, v, A, i, j, b):
"""
Fills the matrix A[i,j,b] according to equation (4) in the paper. The parallelizations are made in equation (6).
"""
if j == i + 1 and b == i % 2:
A[i][j][b] = [0, []]
elif j == i + 1 and b == (i + 1) % 2:
leftind = beginning_index_of_weight(w, v, i)
rightind = end_index_of_weight(w, v, j)
r = SBR.Reversal(leftind, rightind)
A[i][j][b] = [w[i] + w[j] + 1, [r]]
elif j > i + 1 and b == i % 2:
A[i][j][b] = A[i + 1][j][b]
elif j > i + 1 and b == (j + 1) % 2:
A[i][j][b] = A[i][j - 1][b]
else:
fill_6_parallel(w, v, A, i, j, b)
def fill_6_parallel(w, v, A, i, j, b):
"""
Fills the matrix A[i,j,b] according to a parallelized version of equation (6) in the paper. Instead of adding the
times to sort the three subsections, this algorithm simply takes the maximum.
"""
minval = math.inf
minrevs = []
for t in range(i, j):
for k in range(t + 1, j + 1):
revcost = v[k - 1 - ((k - 1 - i) % 2)] - v[i] + w[i] + v[j] - v[t + 1 + ((j - (t + 1)) % 2)] + w[t + 1 + ((j - (t + 1)) % 2)] + 1
val = max(A[i][t][b][0], A[t + 1][k - 1][1 - b][0], A[k][j][b][0]) + revcost
if val < minval:
minval = val
leftind = beginning_index_of_weight(w, v, t + 1) - (v[t - ((t - i) % 2)] - v[i] + w[i])
rightind = end_index_of_weight(w, v, k - 1) + (v[j] - v[k + ((j - k) % 2)] + w[k + ((j - k) % 2)])
r = SBR.Reversal(leftind, rightind)
minrevs = A[i][t][b][1] + A[t + 1][k - 1][1 - b][1] + A[k][j][b][1] + [r]
A[i][j][b] = [minval, minrevs]
def sequential_permutation_sort_parallelized(perm, i, j):
"""
Sorts the given permutation from index i to j (inclusive) by using a parallelized version of the optimal sequential
sorting search for 0/1 strings. The method of parallelization is dictated by the version number. Returns a list of
reversals used to sort the permutation.
"""
if i == j:
return []
b = perm_to_01(perm, i, j)
revs = binary_sort_parallel(b[i:j + 1])
offsetrevs = [SBR.Reversal(i + r.beg, i + r.end) for r in revs]
m = (i + j) // 2
SBR.apply_revs(offsetrevs, perm)
return offsetrevs + sequential_permutation_sort_parallelized(perm, i, m) + \
sequential_permutation_sort_parallelized(perm, m + 1, j)
if __name__ == '__main__':
print(GDC_ATBS([8,7,6,5,4,3,2,1]))
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