Browse Source

sortingalgoswithit'scomputingtime

pull/5/head
Sunny Pate 5 years ago
parent
commit
71301f2178
1 changed files with 439 additions and 0 deletions
  1. +439
    -0
      sorting/Sortingalgoswithcomputing time.py

+ 439
- 0
sorting/Sortingalgoswithcomputing time.py View File

@ -0,0 +1,439 @@
# coding: utf-8
# # 1 Best cases
# **1.1** Bubble sort
# The short version of Bubble sort is given in the online book:
# https://runestone.academy/runestone/static/FIT5211/SortSearch/TheBubbleSort.html
# At every iteration, it detects whether an exchange has been made, and only continues iteration if that is the case. Given a sorted list, the first iteration will make no exchange, thus no other iteration will be performed, and only the inner loop will actually iterate over the entire list. The running time in that case is thus $O(n)$.
# **1.2** Selection sort
# After every pass of selection sort, the only thing we know is that one more item is now in place. The algorithm has no way of knowing and thus using the fact that the list is already sorted. The algorithm will thus perform the whole $O(n^2)$ operations, as in the worst case.
# **1.3** Merge sort
# Merge splits the input list into two, without looking at its contents. the contents are only looked at upon merging, after every item in the list has been split into a sublist of size 1. At this point, all merging operations still need to happen. In this case, the running time is thus also $O(n \log{n})$.
# # 2 Merge sort without slicing
# In[1]:
#start is the index of the first item
#end is the index past the the last item
def indexMergeSort(alist, start = None, end = None):
if start == None:
start = 0
if end == None:
end = len(alist)
#note that the print operations still use slicing for convenience
#print("Input: ",alist[start:end])
length = end - start
if length > 1:
#print("Splitting ",alist[start:end])
mid = start + length//2
indexMergeSort(alist, start, mid)
indexMergeSort(alist, mid, end)
i=start # index for the left part of the list
j=mid # index for the right part of the list
#we use a temporary list
templist = [None] * (length)
k = 0 #index for the temp list
while i < mid and j < end:
if alist[i] < alist[j]:
templist[k] = alist[i]
i=i+1
else:
#we swap
templist[k] = alist[j]
j=j+1
k=k+1
while i < mid:
templist[k] = alist[i]
i=i+1
k=k+1
while j < end:
templist[k]=alist[j]
j=j+1
k=k+1
#we copy the results
for k in range(length):
alist[start+k] = templist[k]
#print("Merging ",alist[start:mid], alist[mid:end])
alist = [54,26,93,17,77,31,44,55,20]
indexMergeSort(alist)
print(alist)
# # 3 Benchmarking sorting algorithms
# In[2]:
import random
def generatelist(n, lower = 0, upper = 1000, seed = 0):
#https://docs.python.org/3/library/random.html
random.seed(seed)
l = [None] * n
for i in range(0,n):
l[i] = random.randrange(lower, upper)
return l
# In[3]:
print(generatelist(10))
# Below we have copied the sorting functions from the online book:
# In[4]:
def bubbleSort(alist):
for passnum in range(len(alist)-1,0,-1):
for i in range(passnum):
if alist[i]>alist[i+1]:
temp = alist[i]
alist[i] = alist[i+1]
alist[i+1] = temp
# In[5]:
def shortBubbleSort(alist):
exchanges = True
passnum = len(alist)-1
while passnum > 0 and exchanges:
exchanges = False
for i in range(passnum):
if alist[i]>alist[i+1]:
exchanges = True
temp = alist[i]
alist[i] = alist[i+1]
alist[i+1] = temp
passnum = passnum-1
# In[6]:
def selectionSort(alist):
for fillslot in range(len(alist)-1,0,-1):
positionOfMax=0
for location in range(1,fillslot+1):
if alist[location]>alist[positionOfMax]:
positionOfMax = location
temp = alist[fillslot]
alist[fillslot] = alist[positionOfMax]
alist[positionOfMax] = temp
# In[7]:
def insertionSort(alist):
for index in range(1,len(alist)):
currentvalue = alist[index]
position = index
while position>0 and alist[position-1]>currentvalue:
alist[position]=alist[position-1]
position = position-1
alist[position]=currentvalue
# In[8]:
def shellSort(alist):
sublistcount = len(alist)//2
while sublistcount > 0:
for startposition in range(sublistcount):
gapInsertionSort(alist,startposition,sublistcount)
#print("After increments of size",sublistcount,
# "The list is",alist)
sublistcount = sublistcount // 2
def gapInsertionSort(alist,start,gap):
for i in range(start+gap,len(alist),gap):
currentvalue = alist[i]
position = i
while position>=gap and alist[position-gap]>currentvalue:
alist[position]=alist[position-gap]
position = position-gap
alist[position]=currentvalue
# In[9]:
def mergeSort(alist):
#print("Splitting ",alist)
if len(alist)>1:
mid = len(alist)//2
lefthalf = alist[:mid]
righthalf = alist[mid:]
mergeSort(lefthalf)
mergeSort(righthalf)
i=0
j=0
k=0
while i < len(lefthalf) and j < len(righthalf):
if lefthalf[i] < righthalf[j]:
alist[k]=lefthalf[i]
i=i+1
else:
alist[k]=righthalf[j]
j=j+1
k=k+1
while i < len(lefthalf):
alist[k]=lefthalf[i]
i=i+1
k=k+1
while j < len(righthalf):
alist[k]=righthalf[j]
j=j+1
k=k+1
#print("Merging ",alist)
# In[10]:
def quickSort(alist):
quickSortHelper(alist,0,len(alist)-1)
def quickSortHelper(alist,first,last):
if first<last:
splitpoint = partition(alist,first,last)
quickSortHelper(alist,first,splitpoint-1)
quickSortHelper(alist,splitpoint+1,last)
def partition(alist,first,last):
pivotvalue = alist[first]
leftmark = first+1
rightmark = last
done = False
while not done:
while leftmark <= rightmark and alist[leftmark] <= pivotvalue:
leftmark = leftmark + 1
while alist[rightmark] >= pivotvalue and rightmark >= leftmark:
rightmark = rightmark -1
if rightmark < leftmark:
done = True
else:
temp = alist[leftmark]
alist[leftmark] = alist[rightmark]
alist[rightmark] = temp
temp = alist[first]
alist[first] = alist[rightmark]
alist[rightmark] = temp
return rightmark
# Now we benchmark them:
# In[11]:
sorting_algorithms = [bubbleSort, shortBubbleSort, selectionSort, insertionSort, shellSort, mergeSort, indexMergeSort, quickSort]
#matplotlib.org/gallery/lines_bars_and_markers/line_styles_reference.html
styles = {}
styles[bubbleSort] = "r-"
styles[shortBubbleSort] = "r:"
styles[selectionSort] = "y-"
styles[insertionSort] = "g-"
styles[shellSort] = "g:"
styles[mergeSort] = "b--"
styles[indexMergeSort] = "b:"
styles[quickSort] = "y--"
# In[19]:
from timeit import default_timer as timer
import datetime
# matplotlib may need to be installed separately
import matplotlib.pyplot as plt
def computeandplot(sorting_algorithms):
step = 100
nsamples = 100
samples = range(0, nsamples)
timelimit = 0.05 #seconds, per run
totaltime = 0
print("Maximum computing time:", str(datetime.timedelta(seconds= timelimit*nsamples*len(sorting_algorithms))))
for sortalgo in sorting_algorithms:
attimelimit = False
times = [timelimit for _ in samples]
for i in samples:
if i == 0:
times[i] = 0
continue
n = step * i
if attimelimit == False:
l = generatelist(n)
start = timer()
sortalgo(l)
end = timer()
times[i] = end - start
totaltime += times[i]
if times[i] > timelimit:
times[i] = timelimit
attimelimit = True
plt.plot(samples, times, styles[sortalgo], label=sortalgo.__name__)
print("Actual computing time:", str(datetime.timedelta(seconds=int(totaltime))))
plt.legend(bbox_to_anchor=(1.05, 1), loc=2, borderaxespad=0.)
plt.xlabel("list size / {}".format(step))
plt.ylabel("time in seconds")
plt.show()
computeandplot(sorting_algorithms)
# # 4 Sorting small integers
# **4.1**
# In[13]:
def countsort(alist):
maxv = max(alist)
l = [0]*(maxv+1)
for i in alist:
l[i] += 1
k = 0
for i in range(0, len(alist)):
while l[k] == 0:
k += 1 # we count the number of values = k in alist
alist[i] = k
l[k] -= 1
# In[14]:
alist = [54,26,93,17,77,31,44,55,20]
countsort(alist)
print(alist)
# **4.2**
# In[15]:
import math
DEFAULT_BUCKET_SIZE = 5
def bucketsort(array=alist, bucketSize=DEFAULT_BUCKET_SIZE):
if len(array) == 0:
return array
# Determine minimum and maximum values
minValue = array[0]
maxValue = array[0]
for i in range(1, len(array)):
if array[i] < minValue:
minValue = array[i]
elif array[i] > maxValue:
maxValue = array[i]
# Initialize buckets
bucketCount = math.floor((maxValue - minValue) / bucketSize) + 1
buckets = []
for i in range(0, bucketCount):
buckets.append([])
# Distribute input array values into buckets
for i in range(0, len(array)):
buckets[math.floor((array[i] - minValue) / bucketSize)].append(array[i])
# Sort buckets and place back into input array
array = []
for i in range(0, len(buckets)):
insertion_sort(buckets[i])
for j in range(0, len(buckets[i])):
array.append(buckets[i][j])
return array
# In[16]:
def default_compare(a, b):
if a < b:
return -1
elif a > b:
return 1
return 0
# In[17]:
def insertion_sort(array):
for i in range(1, len(array)):
item = array[i]
indexHole = i
while indexHole > 0 and default_compare(array[indexHole - 1], item) > 0:
array[indexHole] = array[indexHole - 1]
indexHole -= 1
array[indexHole] = item
return array
# In[18]:
new_sorting_algorithms = [bucketsort, indexMergeSort, quickSort]
styles[bucketsort] = "g--"
computeandplot(new_sorting_algorithms)

Loading…
Cancel
Save