Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Sign in
Toggle navigation
Menu
Open sidebar
Andrew Childs
reversalsort
Commits
4468b403
Commit
4468b403
authored
Feb 23, 2021
by
Samuel King
Browse files
Upload New File
parent
306a710e
Changes
1
Hide whitespace changes
Inline
Sidebyside
AdaptiveTBS.py
0 → 100644
View file @
4468b403
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 0weight and ending with a 1weight.
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 LengthWeighted 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
]))
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment