![]() |
|
![]() |
|
|
Thread Tools | Display Modes |
|
|
#1 |
|
Programmer
Join Date: Dec 2005
Posts: 67
Rep Power: 0
![]() |
Sorting algorithms problem.......
aight my assignment is to implement both quick sort and bubble sort, time them and make a graph of the change in time it takes both according to size of array/list of elements........... I have it done and it works on lists upto but not incuding lists with 100,000 elements..... it freezes up when trying to sort them with both algorithms at 100,000........
heres the code I have........ import time
import random
import sys
sys.setrecursionlimit(1000000)
##Main function call to run tests on 2 equal arrays of size num_elements
##time arrays through both algorithms
##and print both time of execution and sorted array to screen
def run_sort_tests(num_elements):
num_elements=num_elements
num_array=[]
num_array2=[]
num_array,num_array2=create_arrays(num_array,num_array2,num_elements)
print "\nUnsorted Array:\n",num_array,"\nend unsorted\n\n"
######Time Bubble and print array/time
start = time.clock()
bubbleSort(num_array, num_elements)
end = time.clock()
total_time = end - start
#uncomment to see sorted array
print num_array
print "\nBubbleSort time for ",num_elements," elements: ",total_time,"\n"
######Time Quick Sort print array/time
start = time.clock()
quickSort(num_array2,0,num_elements-1)
end = time.clock()
total_time = end - start
#uncomment to see sorted array
print num_array2
print "\nQuickSort time for ",num_elements," elements: ",total_time,"\n"
##Function to create 2 equal arrays of size num_elements
def create_arrays(array1,array2,num_elements):
array1=[0]*num_elements
for i in range(0,num_elements):
array1[i] = random.randint(0,1000)
array2=array1
return array1,array2
##Bubble sort algorithm
def bubbleSort(nums,elements):
i=elements-1
j=1
while i>=0:
j=1
while j<=i:
if nums[(j-1)]>nums[j]:
temp=nums[j-1]
nums[j-1]=nums[j]
nums[j]=temp
j+=1
i-=1
#Partition Function for use within quick sort algorithm
def partition(nums, L, R):
pivot = nums[R]
pivot_index=R
j = L
i = R+1
loop=1
while loop:
j+=1
while nums[j]<pivot:
if j == i:
loop = 0
break
j +=1
i -=1
while nums[i]>pivot:
if i == j:
loop=0
break
i -=1
temp=nums[j]
nums[j]=nums[i]
nums[i]=temp
if i>=j:
break
temp=nums[j]
nums[j]=nums[i]
nums[i]=temp
nums[pivot_index]=nums[i]
nums[i]=pivot
return i
##Quick Sort Function algorithm
def quickSort(nums, L, R):
if L < R:
piv = partition(nums, L, R)
quickSort(nums, L, piv-1)
quickSort(nums, piv+1, R)
return
##run 3 tests
run_sort_tests(10)
run_sort_tests(100)
run_sort_tests(1000)
run_sort_tests(10000)
run_sort_tests(100000)
raw_input("")any help is greatly appreciated.................. |
|
|
|
|
|
#2 |
|
Professional Programmer
Join Date: Feb 2005
Posts: 434
Rep Power: 4
![]() |
When you use
array2=array1 To make a true copy of a simple list you can use array2=array1[:] There are a lot of strange things in your code, is this a direct translation from C?
__________________
I looked it up on the Intergnats! |
|
|
|
|
|
#3 |
|
Professional Programmer
Join Date: Feb 2005
Posts: 434
Rep Power: 4
![]() |
One more thing, don't even attempt to display an array/list of 100,000 elements on your console, that will take forever!!!
Just to test if it's sorted limit it to maybe the first 100 elements with this little trick: print num_array[:100]
__________________
I looked it up on the Intergnats! |
|
|
|
|
|
#4 |
|
Programming Guru
![]() Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 4
![]() |
Presumably it freezes up because sorting 100'000 numbers takes up a good amount of processing time. Remember that Bubblesort is O(n^2) time, so a list of 100'000 would need around 10'000'000'000 iterations. Have you tried leaving it for a while and seeing if it comes back with anything? (Although you might have a long time to wait!)
The other option is to make your program a little more efficient. Your algorithms would suit a language like C fine, but you don't need to write so much code for a language like Python. Take your create_arrays function. You've made a little mistake here, though it's a classic one beginners make: array2=array1 It's the same with objects in Python. You have a variable, or reference, to an object (for instance, array1 points to an array), but copying the reference (into array2) is not the same as copying the array itself. So array1 and array2 point to exactly the same array! Fortunately, creating arrays (or rather lists) in Python is made a lot easier through the use of list comprehensions. I'll give you a few examples. # The range function outputs a sequence of incremented numbers range(5) # Outputs [0, 1, 2, 3, 4] # We can use list comprehensions to double all the numbers in the list [x * 2 for x in range(5)] # Outputs [0, 2, 4, 6, 8] def random_list(n, lower = 0, upper = 1000):
return [random.randint(lower, upper) for i in xrange(n)]To create a copy of a list, an easy trick is to use a slice. There's lots of information about slices on the Python homepage and elsewhere. For now, just remember that array1[:] is a quick way of copying a list: array1 = random_list(1000) array2 = array1[:] def bubblesort(list):
for i in xrange(len(list) - 1, 0, -1):
for j in xrange(1, i + 1):
if list[j - 1] > list[j]:
temp = list[j - 1]
list[j - 1] = list[j]
list[j] = temp
return listdef quicksort(list):
if len(list) > 1:
pivot = list.pop(len(list) / 2)
less_than = [x for x in list if x <= pivot]
greater_than = [x for x in list if x > pivot]
return quicksort(less_than) + [pivot] + quicksort(greater_than)
else:
return listdef quicksort(x):
list = x[:]
if len(list) > 1:
pivot = list.pop(len(list) / 2)
less_than = [x for x in list if x <= pivot]
greater_than = [x for x in list if x > pivot]
return quicksort(less_than) + [pivot] + quicksort(greater_than)
else:
return listThe above quicksort is very Python-efficient. For 100'000 list entries, it took the quicksort function a mere 2.68 seconds to sort. The bubblesort is taking a lot longer, so long that even after 5 minutes it was still going. At first this seemed surprising, but I did some quick sums and the result I get is that bubblesort with 100'000 random elements should be on the order of 20'000 times slower than quicksort on the same. O(n^2) is a lot bigger than O(n log n) for large numbers. More knowledgable forum members should feel free to correct me ![]() Last edited by Arevos; Apr 18th, 2006 at 4:41 PM. |
|
|
|
|
|
#5 |
|
Professional Programmer
Join Date: Feb 2005
Posts: 434
Rep Power: 4
![]() |
Arevos,
just a question, I see you are using "list" as a variable name. Is that good practice, since "list" is a Python keyword? I tested out your wonderfully coded sorts (using xrange is a good idea!), bubblesort does change the original list, your first quicksort does not!
__________________
I looked it up on the Intergnats! Last edited by Dietrich; Apr 18th, 2006 at 5:14 PM. |
|
|
|
|
|
#6 | ||
|
Programming Guru
![]() Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 4
![]() |
Quote:
Quote:
|
||
|
|
|
|
|
#7 | |
|
Newbie
Join Date: Feb 2006
Posts: 9
Rep Power: 0
![]() |
I have been reading the Python Cookbook and in the 4.1 Recipe the recommended technique to copy a list is to use the list function:
Quote:
__________________
Programming Tutorial for Absolute Beginners |
|
|
|
|
|
|
#8 |
|
Professional Programmer
Join Date: Feb 2005
Posts: 434
Rep Power: 4
![]() |
Thanks Arevos,
tested the len() of the list and low and behold there is an item missing! The bubblesort with 100,000 x 100,000 iterations would be very slow, particularly if the disk as to be used for memory too! At least my disk light flickers a lot!
__________________
I looked it up on the Intergnats! |
|
|
|
|
|
#9 |
|
Programmer
Join Date: Dec 2005
Posts: 67
Rep Power: 0
![]() |
I talked to my proffessor after posting this and he said everything that you guys said..... he explained how pythons virtual machine has massive overhead and that will make it run longer because it eventually starts writing back and forth from disk ......So I took out the print statements except for printing the times.........I commented out bubblesort all together....I copied the array..... Im only running the test on 100,000 now..... and Im waiting.......... welll......... now after like a 1/2 hour/hour python just shuts down...... if I run it in Idle it just quits and closes everything......... If I run it in a command prompt it shuts down the command prompt window........ now this is just confusing the shit out of me.......
|
|
|
|
|
|
#10 |
|
Programming Guru
![]() Join Date: Aug 2005
Location: England
Posts: 1,499
Rep Power: 4
![]() |
For some reason your implementation of quicksort segfaults on my machine for large numbers if I whack up the recursion limit, and fails due to a recursion overload exception otherwise.
Your code is recursing to a greater depth than is necessary, even for a list of 100'000. Could it be that you're code isn't ending correctly and gets stuck in an infinite recusion? Python runs slower because it's a bytecode interpreted language, rather than a compiled one. I shouldn't think that writing back and forth from disk would have any effect, and Python doesn't do that significantly more than any other language. The only time I can think of it writing to disk is to cache libraries. Regardless, Python is slower for a computer to execute. Generally speaking, it's around 10 times slower than C (less so with optimisation modules like psycho). The advantage of Python that it also takes less time to program. It's somewhat of a trade-off between developer efficiency and computational efficiency. |
|
|
|
![]() |
| Bookmarks |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
| Display Modes | |
|
|