Why does the runtime seems too long? - python

I am trying to run my code below in Jupyter notebook, but the run time seems endless and then my laptop suddenly hangs. Could you please tell me what is wrong with my code? (here, for better understanding, I made the data very smaller)
customers = [1,2,3]
nodes = [3,5,6,8,10,14,18]
edges = [(3,6),(8,18),(8,3),(8,10),(8,7),(14,3),(14,5),(14,7),(18,3),(18,8),(18,14)]
demands = {1:200, 2:300, 3:500}
origins = {1:18, 2:8, 3:14}
destinations = {1:6, 2:10, 3:5}
prio_start = {1: [3, 7, 1, 2, 5, 4, 6], 2: [6, 4, 2, 3, 7, 1, 5], 3: [1, 2, 3, 4, 6, 7, 5]}
y_set_init = []
dict_path_nodes = {}
for k in customers:
currentnode = origins[k]
path_nodes = [currentnode]
path_edges = []
prio_init = prio_start[k]
stop = False
while not stop:
for (e, g) in edges:
if e == currentnode:
max_value = max(prio_init)
max_index = prio_init.index(max_value) + 1
nextnode = max_index
path_nodes.append(nextnode)
path_edges.append((currentnode, nextnode))
if (currentnode, nextnode) not in y_set_init:
y_set_init.append((currentnode, nextnode))
currentnode = nextnode
if currentnode == destinations[k]:
stop = True
dict_path_nodes[k]= path_nodes
print(dict_path_nodes)
Is it possible that I miss some "break" for the loops?

If currentnode = 2, the loop becomes infinite (because e never equals 2). And currentnode may be 2, because it is set as an index of prios, not as they value? Please verify your logic, probably you wanted to get value of this list somewhere.

Related

Why is my RLE encoder working for some inputs but not others?

'''
def encode_rle(flat_data):
rle_complete = []
run_length = 0
num_variables = count_runs(flat_data)
# goes through each value in flat_data
for item in flat_data:
if item not in rle_complete: # if item is not in blank list then it is added
rle_complete.append(item)
x = 0
# current item in rle_complete is the first value
current = rle_complete[x]
rle_final = []
for item in rle_complete: # for each value in rle_complete
for item in flat_data: # for each value in original data
if current == item:
run_length += 1 # add a value to count
else: # when current value in rle_complete stops being
# the same as the current value in flat_data the rle_final is updated
rle_final.extend([run_length, current])
current = rle_complete[x + 1]
run_length = 1
num_variables -= 1
if num_variables == 0:
break
return rle_final
'''
I am using the latest version of python and pycharm. When it comes to my code the function works if I use the input [15, 15, 15, 4, 4, 4, 4, 4, 4] I get the correct output [3, 15, 6, 4]. However when I change the input to anything else like [15, 15, 15, 4, 4, 4, 4, 4, 5] the output is completely wrong and different. Any help would be appreciated. The count_runs function that you see in my code simply counts the amount of unique variables within the input.

Debug of Nuts & Bolts Problem python code

I tried to write the code to solve Nuts & Bolts Problem by using quicksort(?), but it does not work well. The most confusing part for me is the returning point of recursion. How can I modify it and is there any tip to considering the returning point of recursion?
Nuts & Bolts Problem:
Given a set of n nuts of different sizes and n bolts of different sizes. There is a one-one mapping between nuts and bolts. Match nuts and bolts efficiently.
Constraint: Comparison of a nut to another nut or a bolt to another bolt is not allowed. It means nut can only be compared with bolt and bolt can only be compared with nut to see which one is bigger/smaller.
Other way of asking this problem is, given a box with locks and keys where one lock can be opened by one key in the box. We need to match the pair.
def smallerThanPartition(nuts, p):
lowN = []
for i in range(0, len(nuts)):
if p > nuts[i]:
lowN.append(nuts[i])
return lowN
def largerThanPartition(nuts, p):
highN = []
for i in range(0, len(nuts)):
if p < nuts[i]:
highN.append(nuts[i])
return highN
def ALG5(nuts, bolts, partition):
if(len(bolts) <= 1):
print('nuts + bolts = '+ str(nuts + bolts))
return nuts + bolts
else:
lowB = []
highB = []
a = []
b = []
lowN = []
highN = []
for i in range(0, len(nuts)):
if nuts[partition] > bolts[i]:
lowB.append(bolts[i])
lowN = smallerThanPartition(nuts, nuts[partition])
else:
highB.append(bolts[i])
highN = largerThanPartition(nuts, nuts[partition])
a = ALG5(lowN, lowB, len(lowN) / 2)
b = ALG5(highN, highB, len(highN) / 2)
return a + nuts[partition] + b
if __name__ == "__main__":
nuts = [1, 3, 5, 2, 44, 6]
bolts = [5, 2, 6, 44, 1, 3]
n = len(nuts)
partition = n / 2
print(ALG5(nuts, bolts, partition))
the result of the above code is
[1, 1, 2, 3, 2, 5, 5, 6, 44, 44]
[1, 3, 5, 2, 44, 6]
[5, 2, 6, 44, 1, 3]
the ideal result is
[1, 2, 3, 5, 6, 44]
[1, 3, 5, 2, 44, 6]
[5, 2, 6, 44, 1, 3]

How to rearrange list in python

I want to rearrange my list in python but there are some rules about it. These next few pictures describe how beavers jump into a hole, while others go accross and the ones in the hole go out.
Original array
Beavers fill in the hole
Others go accross
Everyone else come out
Now there's where it gets complicated. What if i have more than 1 hole. I've managed to figure out everything myself up to this point. Now all i'm asking is how would any of you approach this and if there's any tricks i could use for sorting the list. This is my code so far:
bobri = "54321"
luknje = [4, 2, 4]
bobri_original = bobri
bobri_original_list = list(bobri_original)
bobri_list = list(bobri)
i = 1
gli = 0
for st in range(len(luknje)):
i = 1
globina = luknje[st]
# Prvega zapisem in zbrisem iz glavnega seznama
last_bober = bobri_list[-1]
bobri_list.remove(str(last_bober))
bobri_luknja = [last_bober]
if globina == 1:
for n in range(len(bobri_list)):
bobri_luknja.append(bobri_list[n])
bobri_list = bobri_luknja
else:
while i <= globina - 1:
last_bober = bobri_list[-1]
bobri_list.remove(str(last_bober))
bobri_luknja.append(last_bober)
if i == globina - 1:
for n in range(len(bobri_list)):
bobri_luknja.append(bobri_list[n])
bobri_list = bobri_luknja
i += 1
gli += 1
Zdravo (:
def cross_all_holes(initial_list, hole_depths=[]):
# Crossing single hole function.
def cross_the_hole(current_list, hole_depth):
hole_is_filled = False
list_len = len(current_list)
result_list = []
hole = []
# While not result list contain all the items
while len(result_list) < list_len:
# Filling the hole
if not hole_is_filled:
element = current_list.pop()
hole.append(element)
# Checking if it's filled
hole_is_filled = len(hole) == hole_depth
else:
# Crossing the filled hole
if len(current_list):
element = current_list.pop()
# Emptying hole
elif len(hole):
element = hole.pop()
result_list = [element] + result_list
return result_list
# Repeat as much as needed.
current_list = initial_list
for hole_depth in hole_depths:
current_list = cross_the_hole(current_list, hole_depth)
return current_list
Thanks for the task, it was funny (:
In [20]: cross_all_holes([1,2,3,4,5,6,7,8,9,10], [1,3])
Out[20]: [9, 8, 7, 10, 1, 2, 3, 4, 5, 6]
Never thought I would write a function with inputs as 'beavers' and 'holes', but thanks for this moment. The beavers is simply the list of the number of each beaver, and holes is the list with each hole, and the amount of beavers getting into each:
def rearrange(beavers, holes):
l = len(beavers)
for n in range(len(holes)):
back = beavers[-holes[n]:][::-1]
front = beavers[:l - holes[n]]
beavers = back + front
return(beavers)
rearrange([7,6,5,4,3,2,1], [3])
Out: [1, 2, 3, 7, 6, 5, 4]
rearrange([7,6,5,4,3,2,1], [3,4])
Out: [4, 5, 6, 7, 1, 2, 3]

Median of the medians of a list

I need a vector that stores the median values of the medians of the main list "v". I have tried something with the following code but I am only able to write some values in the correct way.
v=[1,2,3,4,5,6,7,8,9,10]
final=[]
nfac=0
for j in range (0,4):
nfac=j+1
for k in range (0,nfac):
if k%2==0:
final.append(v[10/2**(nfac)-1])
else:
final.append(v[9-10/2**(nfac)])
The first median in v=[1,2,3,4,5,6,7,8,9,10] is 5
Then I want the medians of the remaining sublists [1,2,3,4] and [6,7,8,9,10]. I.e. 2 and 8 respectively. And so on.
The list "final" must be in the following form:
final=[5,2,8,1,3,6,9,4,7,10]
Please take a note that the task as you defined it is basically equivalent to constructing a binary heap from an array.
Definitely start by defining a helper function for finding the median:
def split_by_median(l):
median_ind = (len(l)-1) // 2
median = l[median_ind]
left = l[:median_ind]
right = l[median_ind+1:] if len(l) > 1 else []
return median, left, right
Following the example you give, you want to process the resulting sublists in a breadth-first manner, so we need a queue to remember the following tasks:
from collections import deque
def construct_heap(v):
lists_to_process = deque([sorted(v)])
nodes = []
while lists_to_process:
head = lists_to_process.popleft()
if len(head) == 0:
continue
median, left, right = split_by_median(head)
nodes.append(median)
lists_to_process.append(left)
lists_to_process.append(right)
return nodes
So calling the function finally:
print(construct_heap([1, 2, 3, 4, 5, 6, 7, 8, 9, 10])) # [5, 2, 8, 1, 3, 6, 9, 4, 7, 10]
print(construct_heap([5, 1, 2])) # [2, 1, 5]
print(construct_heap([1, 0, 0.5, -1])) # [0, -1, 0.5, 1]
print(construct_heap([])) # []

quicksort divide-and-conquer returns incorrect partial answer

My program does not return the correct question in the end but it shows correct ones in the intermediate results. I needs help, thanks.
Output sample:
sort begin: A,start,end [3, 5, 2, 1, 7, 6, 8, 4] 0 7
sort begin: A,start,end [2, 1, 3, 5, 7, 6, 8, 4] 0 1
sort begin: A,start,end [1, 2, 3, 5, 7, 6, 8, 4] 3 7
sort begin: A,start,end [1, 2, 3, 4, 5, 6, 8, 7] 3 3
sort begin: A,start,end [1, 2, 3, 4, 5, 6, 8, 7] 5 7
sort begin: A,start,end [1, 2, 3, 4, 5, 6, 8, 7] 5 4
sort begin: A,start,end [1, 2, 3, 4, 5, 6, 8, 7] 6 7
####################################################
final result [1, 2, 3, 5, 4, 6, 8, 7]
My code:
def qSort(A,start,end):
print "sort begin: A,start,end",A,start,end
if start >= end:
return A
elif end == start + 1:
if A[start] > A[end]:
A[start],A[end] = A[end],A[start]
return A
else:
i = start + 1
j = i
p = A[start]
while j < end:
j = j + 1
if p > A[j]:
A[i],A[j] = A[j],A[i]
i = i + 1
A = A[0:start] + A[start+1:i]+ [p] + A[i:end+1]
qSort(A,start,i-2)
qSort(A,i,end)
return A
print "###################"
myarray = [3,5,2,1,7,6,8,4]
result = qSort(myarray,0,7)
print "final result",result
Sorry for my lack luster comments. I reviewed your code and realized it was correct! You have one minor coding mistake which I will point out and then explain. In your else block you currently have:
else:
# Bunch of correct stuff
# ...
# Stuff that is ALMOST correct
qSort(A,start,i-2)
qSort(A,i,end)
return A
you need to change this to:
else:
# Bunch of correct stuff
# ...
# Stuff that is definitely correct
A = qSort(A,start,i-2)
A = qSort(A,i,end)
return A
Without going too deeply into this, your function does not discriminate between list references and newly created lists. If you put print A in you elif block right before return A you will notice that on the final iteration, your sort, as is, does everything correctly, and produces the correct list!
Unfortunately, the call that produced this change was one of the lines I've mentioned above which calls the sort but doesn't store the resulting list returned by the recursive function call!
My simple change just takes the modified list returned from secondary function calls to qSort and reassigns the variable A.
Weirdly, this behavior actually worked ok for you sometimes for reasons I cannot fully explain (like the first time you enter your `elif' block which does the right thing and modifies the list correctly). I am sure someone smarter than I surely can explain the odd behavior.
Alternatively, you could come up with a simple way to count recursion depth (number of times your function calls itself) and print that out while debugging with some breakpoints in your favorite IDE.
Heres how you could do that with global variables:
recursion_depth = -1
def qSort(A,start,end):
global recursion_depth
recursion_depth += 1
print "sort begin: A,start,end,level",A,start,end,recursion_depth
# bunch of code edited out for brevity
# ...
result = qSort(myarray,0,7)
print "final result",result

Categories