Commit 25818f59 by Laurent David

Upload New File

parent 8360289b
import random
def makePermutation(n):
""" generates a random permuation of the numbers 1..n-1 sandwiched between 0 and n """
seq = range(1,n)
random.shuffle(seq)
return [0] + seq + [n]
def hasBreakpoints(seq):
""" returns True if sequnces in not strictly increasing by 1 """
for i in xrange(1, len(seq)):
if (seq[i] != seq[i-1] + 1):
return True
return False
def getStrips(seq):
""" find contained intervals where sequence is ordered, and return intervals
in as lists, increasing and decreasing. Single elements are considered
decreasing. "Contained" excludes the first and last interval. """
deltas = [seq[i+1] - seq[i] for i in xrange(len(seq)-1)]
increasing = list()
decreasing = list()
start = 0
for i, diff in enumerate(deltas):
if (abs(diff) == 1) and (diff == deltas[start]):
continue
if (start > 0):
if deltas[start] == 1:
increasing.append((start, i+1))
else:
decreasing.append((start, i+1))
start = i+1
return increasing, decreasing
def pickReversal(seq, strips):
""" test each decreasing interval to see if it leads to a reversal that
removes two breakpoints, otherwise, return a reversal that removes only one """
reversal = (-1, None)
left = [i for i, j in strips]
right = [j for i, j in strips]
for i in left:
for j in right:
if (i >= j-1):
# skip invalid intervals and
# those with only one element
continue
breakpointsRemoved = 0
if (abs(seq[j-1] - seq[i-1]) == 1):
# reversal will remove left breakpoint
breakpointsRemoved += 1
if (abs(seq[j] - seq[i]) == 1):
# reversal will remove right breakpoint
breakpointsRemoved += 1
if (breakpointsRemoved > reversal[0]):
reversal = (breakpointsRemoved, (i,j))
print "%d:" % reversal[0],
return reversal[1]
def doReversal(seq,(i,j)):
return seq[:i] + [element for element in reversed(seq[i:j])] + seq[j:]
def improvedBreakpointReversalSort(seq):
while hasBreakpoints(seq):
increasing, decreasing = getStrips(seq)
if len(decreasing) > 0:
reversal = pickReversal(seq, increasing+decreasing)
else:
print "0:",
reversal = increasing[0]
print seq, "reversal", reversal
seq = doReversal(seq,reversal)
print seq, "Sorted"
return
if __name__ == "__main__":
print "Python implementation of breakpoint reversal sort on page 135"
while True:
input = raw_input('Enter a list, the size of list, or 0 to exit:')
if (input.find(',') > 0):
L = [int(v) for v in input.split(',')]
else:
n = int(input)
if (n == 0):
break
L = makePermutation(n)
improvedBreakpointReversalSort(L)
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