I have problem with dict's method - copy(),
I make copy of the "tab_bin" - "HERE 02" in the code and then I modifi it - "HERE 01".
And when at the end of code it prints "tab_bin", it prints modyfied version of "tab_bin".
Also I know my code is a litte messy and names of variables look weird because they are in polish.
My code:
def setting(akcje,n,m):
def zmiana():
Zm_1 = []
Zm_2 = []
for x in range(akcje[1], akcje[3]+1):
Zm_1.append(x)
for y in range(akcje[0], akcje[2]+1):
Zm_2.append(y)
return Zm_1, Zm_2
def kreator_tab():
if bool(tab_bin) == False:
for x in range(1, n+1):
for y in range(m):
tab_bin.setdefault(x, []).append(0)
for key, value in tab_bin.items():
for x in Zm_2:
if key == x:
for y in Zm_1:
if value[y-1] == 0: value[y-1] = 1
else: value[y-1] = 0
def operacje_proste(akcje, liczba_operacji):
def kreator_zmian():
ZmX = []
ZmY = []
for x in range(1, akcje[1]+1):
ZmX.append(x)
for y in range(1, akcje[0]+1):
ZmY.append(y)
return ZmX, ZmY
def kreator_tab_prostych():
for keys, values in tab_operacyjna.items(): # <- HERE 01
for x in ZmY:
if keys == x:
for y in ZmX:
if values[y-1] == 0: values[y-1] = 1
else: values[y-1] = 0
return liczba_operacji+1
def d():
suma =0
for value in tab_operacyjna.values():
for x in value:
suma+=x
if suma == 0: return print(liczba_operacji)
else:
return operacje_proste([max(ZmY),max(ZmX)-1], liczba_operacji)
ZmX,ZmY= kreator_zmian()
liczba_operacji = kreator_tab_prostych()
d()
Zm_1, Zm_2 = zmiana()
kreator_tab()
tab_operacyjna = tab_bin.copy() # <- HERE 02
operacje_proste([max(Zm_2),max(Zm_1)], 0)
def wrapper():
n = 2
m = 3
q = 3
akcje = [1,2,2,2]
setting(akcje,n,m)
print(tab_bin)
wrapper()
[EDIT]:
Okey, to explain more clearly what I mean I will add print() to the code and show output.
Code:
tab_operacyjna = tab_bin.copy()
print(tab_bin, "- tab_bin ",tab_operacyjna,"- tab_operacyjna")
operacje_proste([max(Zm_2),max(Zm_1)], 0)
print(tab_bin, "- tab_bin ",tab_operacyjna,"- tab_operacyjna")
OutPut:
{1: [0, 1, 0], 2: [0, 1, 0]} - tab_bin {1: [0, 1, 0], 2: [0, 1, 0]} - tab_operacyjna
{1: [0, 0, 0], 2: [0, 0, 0]} - tab_bin {1: [0, 0, 0], 2: [0, 0, 0]} - tab_operacyjna
Even if in operacje_proste() I don't use tab_bin it changes just like tab_operacyja on which I make changes. I hope this edit will make it more clear.
As juanpa.arrivillaga wrote I thought that .copy works like .deepcopy(). For anyone who has problem like this one just check this.
Related
I want to optimise my model that finds the highest possible overlap (assignment) of items (probes) against a sequence (sequence). I have the starting and end positions of all items and can thus build up my model as follows:
import pyomo
import pyomo.environ as pe
import pyomo.opt as po
sequence = [0, 1, 2, 3, 4, 5]
probes = ["a", "b", "c"]
probe_starts = {"a": 0, "b": 2, "c": 3}
probe_ends = {"a": 2, "b": 4, "c": 5}
# Model definition
model = pe.ConcreteModel()
model.sequence = pe.Set(initialize=sequence)
model.probes = pe.Set(initialize=probes)
model.starts = pe.Param(model.probes, initialize=probe_starts)
model.ends = pe.Param(model.probes, initialize=probe_ends)
model.assignment = pe.Var(model.sequence, model.probes, domain=pe.Binary)
# Objective
expr = sum([model.assignment[j, i] for j in model.sequence for i in model.probes])
model.objective = pe.Objective(expr=expr, sense=pe.maximize)
I now have the following three constraints:
Items can only bind one at a time (no overlapping items)
Because items have a start and end position they are limited in only getting assigned after their respective starts and ends
If items are assigned, they have to bind in their entirety spanning from their start to their end
# One probe per sequence position
model.one_probe_bound = pe.ConstraintList()
for s in model.sequence:
model.one_probe_bound.add(sum(model.assignment[s, p] for p in model.probes) <= 1)
# No assignment before/after start/end
model.define_length = pe.ConstraintList()
for s in model.sequence:
for p in model.probes:
if s < model.starts[p]:
model.define_length.add(model.assignment[s, p] == 0)
if s > model.ends[p]:
model.define_length.add(model.assignment[s, p] == 0)
Both of the constraints above work without issue but I can't find a way to input the logical or from my third condition. I tried to use the disjunction as described in this stackoverflow answer:
# Only allow full assignment or none
def disjunct_rule(b, p, i):
m = b.model()
expr = sum(m.assignment[s, p] for s in m.sequence)
if i:
return expr == m.ends[p] - m.starts[p]
else:
return expr == 0
def disjunction_rule(m, p):
return [m.disjunct[p, i] for i in [True, False]]
def xfrm(m):
pe.TransformationFactory("gdp.bigm").apply_to(m)
model.disjunct = pyomo.gdp.Disjunct(model.probes, [True, False], rule=disjunct_rule)
model.disjunction = pyomo.gdp.Disjunction(model.probes, rule=disjunction_rule)
model.xfrm = pe.BuildAction(rule=xfrm)
Looking at the matrix representation of model.assignment with sequence along the columns and probes along the rows, I get the following:
array([[1, 1, 1, 0, 0, 0],
[0, 0, 0, 1, 1, 0],
[0, 0, 0, 0, 0, 1]])
As can be seen above, I get assignments that aren't spanning the entire length of the item (e.g. c / 3rd item is only assigned at the last position whereas it should have to bind at the two previous ones too. The only valid solution I can see in this toy example is the following:
array([[1, 1, 1, 0, 0, 0],
[0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 1, 1]])
Where items a and c are selected in their entirety and b isn't selected at all. This way we have all constraints matched. The solver I used was glpk. Thanks in advance for any suggestions.
Here is a cut at this....
The other way I mentioned would be to introduce another binary variable for each point in sequence and control that (somehow) via the assignment of probes. The method below should be much more efficient than that.
Try this out with a larger dataset... The current only has 1 feasible solution. Also, I assumed that better solutions would use fewer probes, so I re-wrote the objective to that.
The basis of this solution is the constraint that you must connect to the start once (constraint 1) and the end (constraint 2) once. And any intermediate connections must be consistent (constraint 3).
I used some sub-setting in a few spots where needed.
Code:
# model to make contiguous connections across a sequence
# using as few connections (probes) as possible
import pyomo
import pyomo.environ as pe
sequence = [0, 1, 2, 3, 4, 5]
probes = ["a", "b", "c"]
probe_starts = {"a": 0, "b": 2, "c": 3}
probe_ends = {"a": 2, "b": 4, "c": 5}
# Model definition
model = pe.ConcreteModel()
model.sequence = pe.Set(initialize=sequence)
model.probes = pe.Set(initialize=probes)
model.starts = pe.Param(model.probes, initialize=probe_starts)
model.ends = pe.Param(model.probes, initialize=probe_ends)
model.assign = pe.Var(model.probes, domain=pe.Binary) # 1 if probe p is used...
# Objective
obj = sum(model.assign[p] for p in model.probes) # use as few as possible...?
model.objective = pe.Objective(expr=obj, sense=pe.minimize)
# Constraints
# must connect start once
model.C1 = pe.Constraint(expr=sum(model.assign[p] for p in model.probes
if model.starts[p] == sequence[0]) == 1)
# must connect end once
model.C2 = pe.Constraint(expr=sum(model.assign[p] for p in model.probes
if model.ends[p] == sequence[-1]) == 1)
# must connect any intermediate connections...
# if probe p1 is selected, must select an eligible p2 follow on
def connect(model, p1):
# create subset on the fly of legal follow-on connections
# assumption here that sequence is a sequential list of ints by using the "+1"
p2s = [p for p in model.probes if model.starts[p] == model.ends[p1] + 1]
if not p2s:
return pe.Constraint.Skip
return sum(model.assign[p2] for p2 in p2s) == model.assign[p1]
non_completing_probes = [p for p in model.probes if model.ends[p] != sequence[-1]]
model.C3 = pe.Constraint(non_completing_probes, rule=connect)
solver = pe.SolverFactory('glpk')
result = solver.solve(model)
print(result)
model.display()
Yields:
Problem:
- Name: unknown
Lower bound: 2.0
Upper bound: 2.0
Number of objectives: 1
Number of constraints: 4
Number of variables: 4
Number of nonzeros: 5
Sense: minimize
Solver:
- Status: ok
Termination condition: optimal
Statistics:
Branch and bound:
Number of bounded subproblems: 0
Number of created subproblems: 0
Error rc: 0
Time: 0.006771087646484375
Solution:
- number of solutions: 0
number of solutions displayed: 0
Model unknown
Variables:
assign : Size=3, Index=probes
Key : Lower : Value : Upper : Fixed : Stale : Domain
a : 0 : 1.0 : 1 : False : False : Binary
b : 0 : 0.0 : 1 : False : False : Binary
c : 0 : 1.0 : 1 : False : False : Binary
Objectives:
objective : Size=1, Index=None, Active=True
Key : Active : Value
None : True : 2.0
Constraints:
C1 : Size=1
Key : Lower : Body : Upper
None : 1.0 : 1.0 : 1.0
C2 : Size=1
Key : Lower : Body : Upper
None : 1.0 : 1.0 : 1.0
C3 : Size=1
Key : Lower : Body : Upper
a : 0.0 : 0.0 : 0.0
I'm having issue with this function question:
x = [[0,0,0,0,0],[0,0,0,0,1],[0,1,0,0,0]]
Function: Book(seat) #assuming the seat is A5
The function assumes the seat is valid in the format A, B and C. the function needs to transform the letter part of seat to an integer A = 0, B = 1 and C = 2. The string digit also needs to be changed to "1" → 0, "2" → 1, "3" → 2, "4" → 3 and "5" → 4. These can be used to check if the chair in the x list-of-lists is already booked 1 or not 0. If it is not booked, then it should be changed to booked and the function should return True else it should return False.
My solution is
a = {"A":[0,0,0,0,0], "B":[0,0,0,0,1], "C":[0,1,0,0,],}
rowIndex = ["A","B","C"]
columnIndex = [1,2,3,4,5]
def book(seat):
row = seat[0]
column = seat[1]
while row in rowIndex and column in columnIndex:
if x[row][column-1] == 0:
return True
else: return False
It output False (seat already booked) in respective of the seat I book. I think there is an issue with my code but can't seems to figure it out.
There are a number of problems with your code for the function:
There is no x variable defined — you called it a in the
a = {"A":[0,0,0,0,0], "B":[0,0,0,0,1], "C":[0,1,0,0,],}
After the
row = seat[0]
column = seat[1]
you then test the values in the following:
while row in rowIndex and column in columnIndex:
which will prevent any of the rest of the code from executing unless it's True.
What you need inside of the while to iterate through all the possibilities would require two for loops, one nested inside the other. However…
You don't need to loop at all as illustrated below.
BOOKED = 1
x = [[0,0,0,0,0], [0,0,0,0,1], [0,1,0,0,0]]
letter_to_index = {"A": 0, "B": 1, "C": 2}
digit_to_index = {"1": 0, "2": 1, "3": 2, "4": 3, "5": 4}
def book(seat):
# Convert each seat character to integer.
row = letter_to_index[seat[0]]
col = digit_to_index[seat[1]]
if x[row][col] == BOOKED:
return False
else:
# Book the seat and return True
x[row][col] = BOOKED
return True
if __name__ == '__main__':
print(book('A5')) # -> True
# Try doing it again.
print(book('A5')) # -> False
Here is a simpler implementation of your code. You don't need to use loops. You have a dictionary. You can lookup the dictionary in a much simpler way.
a = {"A":[0,0,0,0,0], "B":[0,0,0,0,1], "C":[0,1,0,0,],}
def book(seat):
r,c = seat #this allows A to be r and 5 to be C
#check if value of r in keys of a
#also check if seat # is within length of seats for key
if r in a and int(c) <= len(a[r]):
#if valid request, then check if seat already booked
#if not, set seat to booked by setting value to 1
#return True
#if already booked, return False
if a[r][int(c)-1] == 0:
a[r][int(c)-1] = 1
return True
else:
return False
# if not a value request, send appropriate message
else:
return 'invalid request'
print ('A5', book('A5'))
print ('C2', book('C2'))
print ('A7', book('A7'))
print (a)
Output of this will be:
A5 True
C2 False
A7 invalid request
{'A': [0, 0, 0, 0, 1], 'B': [0, 0, 0, 0, 1], 'C': [0, 1, 0, 0]}
I am making new program in Python (Mastermind). I have a problem with references of variables:
def user_turn():
try_counter = 1
user_code = []
guessed_code = random_code()
print("Twoja kolej na zgadywanie!")
while try_counter <= max_tries and user_code != guessed_code:
good_number, good_number_and_position = 0, 0
appearance_types_guessing_code = [0 for i in range(types)]
appearance_types_user_code = [0 for i in range(types)]
user_code = input("Próba nr {}: ".format(try_counter))
user_code = list(map(int, str(user_code)))
count_xos()
print_xos()
try_counter += 1
print_result_user_turn()
Body of the function print_xos():
def print_xos():
for i in range(good_number_and_position):
print("x", end='')
for i in range(good_number):
print("o", end='')
print("")
And my problem is that in function print_xos() variables good_number and good_number_and_position are unknown, despite of fact I declared this variables in the while loop in the body of the function user_turn(). How can I solve this problem? I don't want to send the reference as an argument of the function. In my opinion it isn't elegant. Is it possible to do it in another way?
EDIT:
OK, I changed a code a little bit then:
def user_turn():
try_counter = 1
user_code = []
guessed_code = random_code()
appearance_types_guessed_code = [0] * types
how_many_appearance(guessed_code, appearance_types_guessed_code)
print("Twoja kolej na zgadywanie!")
while try_counter <= max_tries and user_code != guessed_code:
good_number, good_number_and_position = 0, 0
appearance_types_user_code = [0] * types
user_code = input("Próba nr {}: ".format(try_counter))
user_code = list(map(int, str(user_code)))
how_many_appearance(user_code, appearance_types_user_code)
print(appearance_types_guessed_code, appearance_types_user_code)
count_xos(guessed_code, appearance_types_guessed_code, user_code, appearance_types_user_code, good_number, good_number_and_position)
print(good_number_and_position, good_number)
print_xos(good_number_and_position, good_number)
try_counter += 1
print_result_user_turn(guessed_code, user_code)
And the body of function count_xos:
def count_xos(guessed_code, appearance_types_guessed_code, user_code, appearance_types_user_code, good_number, good_number_and_position):
for i in range(len(appearance_types_guessed_code)):
good_number += np.min([appearance_types_guessed_code[i], appearance_types_user_code[i]])
for i in range(code_size):
if guessed_code[i] == user_code[i]:
good_number_and_position += 1
good_number -= 1
print(good_number_and_position, good_number)
And I got this output:
RUNDA 1
Twoja kolej na zgadywanie!
Próba nr 1: 0011
[0, 2, 0, 1, 0, 0, 0, 1, 0, 0] [2, 2, 0, 0, 0, 0, 0, 0, 0, 0]
1 1
0 0
You can be certain that function count_xos counts good_number, good_number_and_position counts properly. It should be 1 1, but I don't know why after running the method count_xos, variables good_number_and_position, good_number are not changed?
Your last attempt does not return the numbers so the provided numbers do not carry out into your calling function.
Your code does the equivalent of:
def one(aa,bb):
aa *= 2
bb *= 3
print("In function", aa, bb)
return aa, bb
a = 5
b = 11
one(a,b) # does not reassign returned values - similar to not return anything like yours
print(a,b)
Output:
In function 10 33
5 11
You need to return and reassign the values:
a,b = one(a,b) # reassign returns
print(a,b)
Output:
In function 10 33
10 33
Have a look at Scoping rules - it it best to keep the scope as small as possible and provide data to the function they need.
If you modify things inside function return its new values and reassign them - this is not deeded if you pass a list, they are mutable references and "autoupdate" because you operate through the ref on the data:
# same function used as above
a = 5
b = [11]
one(a,b)
print(a,b)
Output:
In function 10 [11, 11, 11]
5 [11, 11, 11]
If you take a look at the id()s of the variables you can see that altering aa will repoint the name aa to some other id - but a on the outside still points to the original one. Altering the list does not alter the reference-id - it alters the data the ref "points" to:
def one_ids(aa,bb):
print(id(aa),id(bb))
aa *= 3 # modify an integer
bb *= 3 # modify the list
print(id(aa),id(bb))
a = 5
b = [11]
print(id(a),id(b))
one_ids(a,b)
print(id(a),id(b))
Output:
139647789732288 139647790644808 # id of a,b
139647789732288 139647790644808 # id of aa,bb before changing
139647789732**6**08 139647790644808 # id of aa,bb after changing
139647789732288 139647790644808 # id of a,b
You can read further in Function changes list values and not variable values in Python - see if those explanaitions fit you better.
In the code below, I got the optimal value of a recursive function that I set.
Now I want to get the values that helped build it - I mean, know which choice (or a "ride" (this is my decision)) was used in each step, and return that also as a string/array/somehow.
thestory : i have 6 rides, in every step i need to choose whether to go on the ride im on again, or switch. every ride has a fun rate for each time i go on it and i want to maximize the fun. right now i have the optimal value but not the rides that i went on that led me to it
The function F is the main focus here.
import math
import numpy as np
#fun rate for each ride,per loop
def funPerRide(rideNum,loopsNum):
if rideNum==1:
return 0
if rideNum==2:
return 100-np.power((4*loopsNum-10),2)
if rideNum==3:
return 50-(1000*np.power(np.e,(-loopsNum/2))/(5*loopsNum+20))
if rideNum==4:
return 4*loopsNum
if rideNum==5:
return 2.5*np.power(loopsNum,2)
if rideNum==6:
return 50*np.power(np.e,(-2*loopsNum+4))
def F(totalTime,timeLeft,rideNum,loopOnCurrRide):
#time of line+operation of ride
totalTimePerRide={1:0,2:40,3:15,4:20,5:23,6:11}
#time of operation of rides
operationTimePerRide={1:0,2:4,3:5,4:8,5:3,6:6}
#unfeasable conditions:
if timeLeft<0:
return -np.inf
if timeLeft+loopOnCurrRide*operationTimePerRide[rideNum]>totalTime:
return -np.inf
if loopOnCurrRide>3:
return -np.inf
#edge condition
if timeLeft == 0:
return 0
#fun if i stay on the ride im on right now
staying = funPerRide(rideNum,loopOnCurrRide+1)-funPerRide(rideNum,loopOnCurrRide)+F(totalTime,timeLeft-operationTimePerRide[rideNum],rideNum,loopOnCurrRide+1)
#calculating fun if i switch to the maximum-fun-ride, that is not the ride im currently at
switching = -1
whichRide=-1
for i in range(1,7):
if i>rideNum:
switchOption = funPerRide(i,loopOnCurrRide)+F(totalTime,timeLeft-4.5-totalTimePerRide[i],i,1)
if switchOption>switching:
switching, whichRide=switchOption,i
#calculating maximum fun between switching and staying
maxval,maxride=max((staying,rideNum),(switching,whichRide))
path.append(maxride)
maxval=float(maxval)
return float(maxval)
path = []
print(F(120,120,1,0),path)
Your function F can return a pair of two values: first - optimal answer, second - optimal path as a list of indexes.
def F(totalTime, timeLeft, rideNum, loopOnCurrRide):
# time of line+operation of ride
totalTimePerRide = {1: 0, 2: 40, 3: 15, 4: 20, 5: 23, 6: 11}
# time of operation of rides
operationTimePerRide = {1: 0, 2: 4, 3: 5, 4: 8, 5: 3, 6: 6}
if timeLeft + loopOnCurrRide * operationTimePerRide[rideNum] > totalTime:
return -10, []
if loopOnCurrRide > 3:
return -10, []
if timeLeft == 0:
return 0, []
staying, staying_path = F(totalTime, timeLeft - operationTimePerRide[rideNum], rideNum, loopOnCurrRide + 1)
staying += funPerRide(rideNum, loopOnCurrRide + 1) - funPerRide(rideNum, loopOnCurrRide)
staying_path = [-1] + staying_path
switching = -1
switching_path = []
for i in range(1, 7):
if i > rideNum:
switchOption, switchOption_path = F(totalTime, timeLeft - 4.5 - totalTimePerRide[i], i, 1)
switchOption += funPerRide(i, loopOnCurrRide)
if switchOption > switching:
switching = switchOption
switching_path = [i] + switchOption_path
return max((staying, staying_path), (switching, switching_path))
answer, path = F(120, 120, 1, 0)
Like a previous problem I had earlier, I am trying to create a breadth-first search algorithm that takes a graph and outputs the vertex visit order. It takes an adjacency matrix (representing the graph) as its input and here is what I have so far.
import sys
import Queue
# Input has to be adjacency matrix or list
graphAL2 = {0 : [1,2,3],
1 : [0,3,4],
2 : [0,4,5],
3 : [0,1,5],
4 : [1,2],
5 : [2,3] }
# NEED TO FIX:
# - Final graphAL2v print is only displaying key values as 1, not iterating
# through graph and visiting each vertex
def main():
count = 0
graphAL2v = {}
for key, value in graphAL2.items():
graphAL2v[key] = 0
print(graphAL2v)
for key in graphAL2v: # each vertex v in V
if graphAL2v[key] == 0: # is marked with 0
bfs(key, count, graphAL2, graphAL2v)
print(graphAL2v)
def bfs(v, count, graphal, graphv):
count = count + 1
print('Visiting', v)
# Mark v with count and initialize queue with v
graphv[v] = count
visited = Queue.Queue()
while not visited.empty(): #queue not empty:
print('queue is not empty')
for element in graphal[v]: # each vertex w in V adjacent to front vertex
if element == 0:
count = count + 1
# mark w with count
graphal[v] = count
visited.put()
visited.get()
if __name__ == '__main__':
sys.exit(main())
The problem that I am running into is that my output
{0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0}
('Visiting', 0)
('Visiting', 1)
('Visiting', 2)
('Visiting', 3)
('Visiting', 4)
('Visiting', 5)
{0: 1, 1: 1, 2: 1, 3: 1, 4: 1, 5: 1}
displays the visit order as 1 for all vertices in the list when it should be displaying the visit order as a different number for each vertex as it traverses the "graph." I believe that this error is stemming from within the while loop of the bfs() function. Any suggestions for trying to fix the code so I can achieve the desired output? I'm also not that familiar with queues in Python so any help is appreciated.
There are lots of issues in your code -
First of all, you are never putting anything in the Queue that you create, so its always empty, you need to put the v inside the queue before the while loop , that is the starting point.
Secondly, in the for loop, you are checking element == 0 , which is wrong, you need to check if graphv[element] == 0 , that is whether the element has been already visited or not.
Thirdly, in the for loop, you need to set graphv[element] = count , that signifies that you vivisted element .
You are not putting anything inside the queue with - visited.put() , you need to pass the element to put inside the Queue as parameter.
When getting back the element from the Queue, you need to assign it back to v, otherwise v would never change, v signifies the current element being iterated.
Example code -
import sys
import Queue
# Input has to be adjacency matrix or list
graphAL2 = {0 : [1,2,3],
1 : [0,3,4],
2 : [0,4,5],
3 : [0,1,5],
4 : [1,2],
5 : [2,3] }
# NEED TO FIX:
# - Final graphAL2v print is only displaying key values as 1, not iterating
# through graph and visiting each vertex
def main():
count = 0
graphAL2v = {}
for key, value in graphAL2.items():
graphAL2v[key] = 0
print(graphAL2v)
for key in graphAL2v: # each vertex v in V
if graphAL2v[key] == 0: # is marked with 0
bfs(key, count, graphAL2, graphAL2v)
print(graphAL2v)
def bfs(v, count, graphal, graphv):
count = count + 1
print('Visiting', v)
# Mark v with count and initialize queue with v
graphv[v] = count
visited = Queue.Queue()
visited.put(v)
while not visited.empty(): #queue not empty:
print('queue is not empty')
for element in graphal[v]: # each vertex w in V adjacent to front vertex
if graphv[element] == 0:
count = count + 1
# mark w with count
graphv[element] = count
visited.put(element)
v = visited.get()
return count
if __name__ == '__main__':
sys.exit(main())
Demo (after above changes) -
{0: 0, 1: 0, 2: 0, 3: 0, 4: 0, 5: 0}
Visiting 0
queue is not empty
queue is not empty
queue is not empty
queue is not empty
queue is not empty
queue is not empty
{0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6}
You can use one of the graph libraries that provide search algorithms, such as NetworkX:
from networkx import *
graphAL2 = {0 : [1,2,3],
1 : [0,3,4],
2 : [0,4,5],
3 : [0,1,5],
4 : [1,2],
5 : [2,3] }
g = Graph()
# create graph
for node in graphAL2:
g.add_node(node)
for target_node in graphAL2[node]:
g.add_edge(node, target_node)
print bfs_successors(g, 0)
This will get the successors of each node, exporting the search order from that should be a piece of cake.
Output:
{0: [1, 2, 3], 1: [4], 2: [5]}