Printing Paths in Dijkstra's shortest path Python3 - python-3.x

I'm having issues with the code below where it's not displaying any paths for each vertex. Vertex and Distance from the source is displaying correctly, but for the path section of the output is blank. What am I missing? I would love to get some feedbacks or suggestions or even answer to this nightmare. I just can't seem to figure out what is causing the paths from displaying anything. I'm still fairly new to Python and I could really use some help!
Output of my current code
class Graph:
def minDistance(self, dist, queue):
# Initialize min value and min_index as -1
minimum = float("Inf")
min_index = -1
# from the dist array,pick one which
# has min value and is till in queue
for i in range(len(dist)):
if dist[i] < minimum and i in queue:
minimum = dist[i]
min_index = i
return min_index
def printPath(self, parent, j):
# Base Case : If j is source
if parent[j] == -1:
print()
j,
return
self.printPath(parent, parent[j])
print()
j,
def printSolution(self, dist, parent):
src = 0
print("Vertex \t\tDistance from Source\tPath")
for i in range(1, len(dist)):
print(("\n%d --> %d \t\t%d \t\t\t\t\t" % (src, i, dist[i])), end=' ')
self.printPath(parent, i)
def dijkstra(self, graph, src):
row = len(graph)
col = len(graph[0])
dist = [float("Inf")] * row
parent = [-1] * row
dist[src] = 0
queue = []
for i in range(row):
queue.append(i)
while queue:
u = self.minDistance(dist, queue)
queue.remove(u)
for i in range(col):
if graph[u][i] and i in queue:
if dist[u] + graph[u][i] < dist[i]:
dist[i] = dist[u] + graph[u][i]
parent[i] = u
self.printSolution(dist, parent)
g = Graph()
graph = [[0, 4, 0, 0, 0, 0, 0, 8, 0],
[4, 0, 8, 0, 0, 0, 0, 11, 0],
[0, 8, 0, 7, 0, 4, 0, 0, 2],
[0, 0, 7, 0, 9, 14, 0, 0, 0],
[0, 0, 0, 9, 0, 10, 0, 0, 0],
[0, 0, 4, 14, 10, 0, 2, 0, 0],
[0, 0, 0, 0, 0, 2, 0, 1, 6],
[8, 11, 0, 0, 0, 0, 1, 0, 7],
[0, 0, 2, 0, 0, 0, 6, 7, 0]
]
g.dijkstra(graph, 0)

The basic issue with your code is that the printPath method is only outputting blanks and secondly, the printSolution method is not including the results of the printPath method. To fix these problems:
1 rewrite the printPath function as below:
def printPath(self, parent, j, l):
# Returns a list from destination to source
# Base case when j = source
if parent[j] == -1:
return l
else:
l.append(j)
return self.printPath(parent, parent[j], l)
Then rewrite the printSolution method as follows:
Note: I used the f format structure to simplify my print statement
def printSolution(self, dist, parent):
src = 0
print("Vertex \t\tDistance from Source\tPath")
for i in range(1, len(dist)):
st = f"\n{src} --> {i}\t\t{dist[i]}\t\t\t\t\t{self.printPath(parent,i,[])[::-1]}"
#print(("\n%d --> %d \t\t%d \t\t\t\t\t" % (src, i, dist[i])), end=' ')
#self.printPath(parent, i)
print (st)

Related

Global variables and multiprocessing pools

In the python multiprocessing library, do processes spawned via Pool only have access to global variables bound at the time of Pool construction?
Why is this?
This appears to be the case, based on this experiment.
This code:
from multiprocessing import Pool
x = 0
class MyClass:
def get_x(self, i):
global x
return x
def foo():
global x
p = Pool(5)
for i in range(3):
x = i
c = MyClass()
print(list(p.imap(c.get_x, range(10*i, 10*i+10))))
foo()
produces the output
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Whereas moving the Pool construction inside the loop, i.e.
from multiprocessing import Pool
x = 0
class MyClass:
def get_x(self, i):
global x
return x
def foo():
global x
for i in range(3):
p = Pool(5)
x = i
c = MyClass()
print(list(p.imap(c.get_x, range(10*i, 10*i+10))))
foo()
produces the output
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
(Note that my motivation for wanting to do this is that x is a large pandas DataFrame in my real application, that needs to be read, but not modified, by several processes.)
My two questions are:
Is it merely impossible to rebind x once the processes are created?
Or do the processes each make a copy of x, and modification is impossible?

How to initialize an 3D array variable in Gekko?

I'm trying to solve a step from a three-dimensional master timetabling model, which involvs periods(5), courses(19) and locations(8).
So I have a problem to initialize these variables with an 3D array in Gekko. Without this initialization the algorithm doesn't converge, after more than 15 minutes run and 1000 iterations.
When I try initialize, this error appears:
"
raise Exception(response)
Exception: #error: Equation Definition
Equation without an equality (=) or inequality (>,<)
true
STOPPING...
"
How can I fix this problem? Follows a version of my code:
import numpy as np
from gekko import GEKKO
# Input data
# Schedule of periods and courses
sched = np.array([ [0, 1, 0, 0, 1], [0, 0, 1, 1, 0], [0, 0, 1, 1, 0], \
[0, 0, 0, 0, 1], [1, 0, 0, 0, 1], [0, 0, 0, 1, 1], [0, 1, 1, 0, 0], \
[1, 0, 0, 1, 0], [0, 1, 0, 0, 1], [1, 1, 0, 0, 0], [0, 1, 1, 0, 0], \
[0, 1, 1, 0, 0], [1, 0, 0, 1, 0], [1, 0, 0, 1, 0], [0, 0, 1, 0, 1], \
[1, 0, 1, 0, 0], [0, 1, 0, 1, 0], [0, 0, 1, 1, 0], [0, 1, 0, 0, 1] ], dtype=np.int64)
# Initial allocation of all periods, courses and locations
alloc=np.array([0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,\
0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], dtype=np.int64)
# Number of students enrolled in each course
enrol = np.array([ 60, 60, 60, 40, 40, 110, 120, 50, 60, 55, 50, \
55, 40, 64, 72, 50, 50, 55, 55], dtype=np.float64)
# Capacity of each location (classroom)
capac = np.array([ 60, 60, 120, 60, 80, 60, 60, 65], dtype=np.float64)
# Total costs of using each location
costs = np.array([ 9017.12, 9017.12, 12050.24, 9017.12, 9413.68, 9017.12, \
9017.12, 9188.96 ])
# Estimated cost of each location by period and student
ecost = np.repeat(np.array([[costs[i]*pow(enrol[j]*5,-1) for j in range(19)] for i in range(8)]), 5)
# The model construction
m = GEKKO()
# Constant arrays
x = m.Array(m.Const,(19,5))
y = m.Array(m.Const,(8,19,5))
N = m.Array(m.Const,(19))
C = m.Array(m.Const,(8))
Ec = m.Array(m.Const,(8,19,5))
Ecy = m.Array(m.Const,(8,19,5))
Alt = m.Array(m.Const,(8,19,5))
for k in range(5):
for j in range(19):
N[j] = enrol[j]
x[j,k] = sched[j,k]
for i in range(8):
C[i] = capac[i]
Ec[i,j,k] = ecost[k+j*5+i*19*5]
y[i,j,k] = alloc[k+j*5+i*19*5]
Ecy[i,j,k] = Ec[i,j,k]*y[i,j,k]
if sched[j,k]==1:
Alt[i,j,np.where(sched[j,:]==1)[0][0]]=-sched[j,k]*(1-sum(sched[j,:]))
if sum(sched[j,:])==2:
Alt[i,j,np.where(sched[j,:]==1)[0][1]]=sched[j,k]*(1-sum(sched[j,:]))
else:
Alt[i,j,k]=0
# Initialize the variable z with the initial value y:
# These commented approaches produce the error.
z = m.Array(m.Var,(8,19,5),lb=0,ub=1,integer=True)
#for i in range(8):
# for j in range(19):
# for k in range(5):
# z[i,j,k] = y[i,j,k]
# nor
#z = m.Array(m.Var,(8,19,5),value=y,lb=0,ub=1,integer=True)
# Intermediate equations
Ecz = m.Array(m.Var,(8,19,5),lb=0)
Altz = m.Array(m.Var,(8,19))
for i in range(8):
for j in range(19):
Altz[i,j]=m.Intermediate(m.sum(Alt[i,j,:]*z[i,j,:]))
for k in range(5):
Ecz[i,j,k]=m.Intermediate(Ec[i,j,k]*z[i,j,k])
# Constraints
m.Equation(m.sum(m.sum(m.sum(Ecz)))<=m.sum(m.sum(m.sum(Ecy))))
for j in range(19):
for k in range(5):
m.Equation(m.sum(z[:,j,k])==x[j,k])
for i in range(8):
for k in range(5):
m.Equation(m.sum(z[i,:,k])==m.sum(y[i,:,k]))
for i in range(8):
for j in range(19):
m.Equation(m.sum((C[i]/N[j]-x[j,:])*z[i,j,:])>=0)
# Objective: to minimize the quantity of courses allocated in different locations
# Example: with the solution y, I have 12 courses in different locations in the periods
# print(sum([sum(Alt[i,j,:]*y[i,j,:])**2 for j in range(19) for i in range(8)])/2)
for i in range(8):
for j in range(19):
m.Obj(Altz[i,j]**2/2)
# Options and final results
m.options.SOLVER=1
m.options.IMODE=2
m.solve()
print(z)
print(m.options.OBJFCNVAL)
Note: My original problem has 20 periods, 171 courses, and 18 locations.
Use z[i,j,k].value = y[i,j,k] to give an initial guess for z. Using z[i,j,k] = y[i,j,k] redefines z entries as floating point numbers instead of gekko variable types.
One other issue is that the variables Ecz and Altz are defined as Variables as m.Var and then overridden as Intermediates. Instead, try allocating them and assigning them as intermediates:
Ecz = np.empty((8,19,5),dtype=object)
Altz = np.empty((8,19),dtype=object)
Use flatten() to simplify the summation of all elements of the 3 dimensional array.
m.Equation(m.sum(Ecz.flatten())<=sum(Ecy.flatten()))
The constant arrays can be defined as numpy arrays to avoid additional symbolic processing by Gekko. This speeds up the model compile time but has no effect on the final solution.
x = np.empty((19,5))
y = np.empty((8,19,5))
N = np.empty((19))
C = np.empty((8))
Ec = np.empty((8,19,5))
Ecy = np.empty((8,19,5))
Alt = np.empty((8,19,5))
The IMODE should be 3 for optimization. IMODE=2 is for parameter regression. IMODE=2 should also work for this problem but 3 is the correct option because you aren't trying to fit to data.
m.options.IMODE=3
Try using IPOPT to obtain an initial non-integer solution and then use APOPT to find an integer solution.
m.solver_options = ['minlp_gap_tol 1.0e-2',\
'minlp_maximum_iterations 10000',\
'minlp_max_iter_with_int_sol 500',\
'minlp_branch_method 1']
Mixed Integer Nonlinear Programming (MINLP) problems can be challenging to solve so you may need to use some of the solver options to speed up the solution. Try minlp_branch_method 1 to help the solver find an initial integer solution to do better pruning. The gap tolerance can also help to speed up the solution if a sub-optimal solution is okay. Below is the complete script. Consider using remote=False to run locally instead of using the public servers, especially for large optimization problems.
import numpy as np
from gekko import GEKKO
# Input data
# Schedule of periods and courses
sched = np.array([ [0, 1, 0, 0, 1], [0, 0, 1, 1, 0], [0, 0, 1, 1, 0], \
[0, 0, 0, 0, 1], [1, 0, 0, 0, 1], [0, 0, 0, 1, 1], [0, 1, 1, 0, 0], \
[1, 0, 0, 1, 0], [0, 1, 0, 0, 1], [1, 1, 0, 0, 0], [0, 1, 1, 0, 0], \
[0, 1, 1, 0, 0], [1, 0, 0, 1, 0], [1, 0, 0, 1, 0], [0, 0, 1, 0, 1], \
[1, 0, 1, 0, 0], [0, 1, 0, 1, 0], [0, 0, 1, 1, 0], [0, 1, 0, 0, 1] ], dtype=np.int64)
# Initial allocation of all periods, courses and locations
alloc=np.array([0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,1,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,1,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,1,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,\
0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,1,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,\
0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0], dtype=np.int64)
# Number of students enrolled in each course
enrol = np.array([ 60, 60, 60, 40, 40, 110, 120, 50, 60, 55, 50, \
55, 40, 64, 72, 50, 50, 55, 55], dtype=np.float64)
# Capacity of each location (classroom)
capac = np.array([ 60, 60, 120, 60, 80, 60, 60, 65], dtype=np.float64)
# Total costs of using each location
costs = np.array([ 9017.12, 9017.12, 12050.24, 9017.12, 9413.68, 9017.12, \
9017.12, 9188.96 ])
# Estimated cost of each location by period and student
ecost = np.repeat(np.array([[costs[i]*pow(enrol[j]*5,-1) for j in range(19)] for i in range(8)]), 5)
# The model construction
m = GEKKO(remote=True)
# Constant arrays
x = np.empty((19,5))
y = np.empty((8,19,5))
N = np.empty((19))
C = np.empty((8))
Ec = np.empty((8,19,5))
Ecy = np.empty((8,19,5))
Alt = np.empty((8,19,5))
for k in range(5):
for j in range(19):
N[j] = enrol[j]
x[j,k] = sched[j,k]
for i in range(8):
C[i] = capac[i]
Ec[i,j,k] = ecost[k+j*5+i*19*5]
y[i,j,k] = alloc[k+j*5+i*19*5]
Ecy[i,j,k] = Ec[i,j,k]*y[i,j,k]
if sched[j,k]==1:
Alt[i,j,np.where(sched[j,:]==1)[0][0]]=-sched[j,k]*(1-sum(sched[j,:]))
if sum(sched[j,:])==2:
Alt[i,j,np.where(sched[j,:]==1)[0][1]]=sched[j,k]*(1-sum(sched[j,:]))
else:
Alt[i,j,k]=0
# Initialize the variable z with the initial value y:
# These commented approaches produce the error.
z = m.Array(m.Var,(8,19,5),lb=0,ub=1,integer=True)
for i in range(8):
for j in range(19):
for k in range(5):
z[i,j,k].value = y[i,j,k]
# nor
#z = m.Array(m.Var,(8,19,5),value=y,lb=0,ub=1,integer=True)
# Intermediate equations
Ecz = np.empty((8,19,5),dtype=object)
Altz = np.empty((8,19),dtype=object)
for i in range(8):
for j in range(19):
Altz[i,j]=m.Intermediate(m.sum(Alt[i,j,:]*z[i,j,:]))
for k in range(5):
Ecz[i,j,k]=m.Intermediate(Ec[i,j,k]*z[i,j,k])
# Constraints
m.Equation(m.sum(Ecz.flatten())<=sum(Ecy.flatten()))
for j in range(19):
for k in range(5):
m.Equation(m.sum(z[:,j,k])==x[j,k])
for i in range(8):
for k in range(5):
m.Equation(m.sum(z[i,:,k])==m.sum(y[i,:,k]))
for i in range(8):
for j in range(19):
m.Equation(m.sum((C[i]/N[j]-x[j,:])*z[i,j,:])>=0)
# Objective: to minimize the quantity of courses allocated in different locations
# Example: with the solution y, I have 12 courses in different locations in the periods
# print(sum([sum(Alt[i,j,:]*y[i,j,:])**2 for j in range(19) for i in range(8)])/2)
for i in range(8):
for j in range(19):
m.Obj(Altz[i,j]**2/2)
# Options and final results
m.options.IMODE=3
# Initialize with IPOPT
m.options.SOLVER=3
m.solve()
# Integer solution with APOPT
m.options.SOLVER=1
m.solver_options = ['minlp_gap_tol 1.0e-2',\
'minlp_maximum_iterations 10000',\
'minlp_max_iter_with_int_sol 500',\
'minlp_branch_method 1']
m.solve()
print(z)
print(m.options.OBJFCNVAL)

How to check the distance between a specific element an index? Python3

A = [1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0]
B = 9
I want to find out the distances between the index[9] (B) and each of it's closest's 1's. For example, If we look at list A, we see that index 9 is this:
A = [1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0]
^
I would like to figure out the distances between B(index 9) and it's nearest 1's. For example, the nearest 1's in this case would be this:
A = [1, 0, 0, 0, 1, 0, 0, 1, 0, B, 0, 0, 1, 0]
^ ^
So in this case the output would be:
>> [2, 3] ##Since the distance between 1, 0, B is 2 and the distance between B, 0, 0, 1 is 3.
So far I've come up with the following code:
def checkDistance(A, B):
for i in A:
if i == 1:
#Check if it is the closest to B
#Check distance
Sadly I'm a beginner in python and I am struggling to finish. Any help would be much appreciated :)
def distance(lst,index):
c=[i for i,j in enumerate(lst) if j==1]
for k,l in zip(c[:-1],c[1:]):
if k < index < l:
return [index-k, l-index]
a = [1, 0, 0, 0, 1, 0, 0, 1, 0, B, 0, 0, 1, 0]
b = 9
distance(a, b)
Out: [2, 3]
You could use the following function. In this case, to make the function more abstract, you needn't force the value for the comparison to be 1 in the function.
In the function below, you do a for loop starting at the position you specified (in Python indexes start at 0, not at 1) and finishing when the list finishes.
The if statement compares element with the value of the list at a given position i
def checkDistance(lst,index,element):
counter = 0
results = []
for i in range(index,len(lst)):
if lst[i] == element:
print("Detected element at distance: " + str(counter))
results.append(counter)
counter += 1
return results

I want to learn how to implement a* path finding in Python3

I found this code online and would really like for someone to explain it simply. I understand most of the initialisation of nodes, but don't understand as much once I get further down. If someone can explain the code near line by line, I would be grateful. The areas I find the most confusing are the calculation sections.
Thanks for any/all responses
class Node():
def __init__(self, parent=None, position=None):
self.parent = parent
self.position = position
self.g = 0
self.h = 0
self.f = 0
def __eq__(self, other):
return self.position == other.position
def astar(maze, start, end):
"""Returns a list of tuples as a path from the given start to the given end in the given maze"""
# Create start and end node
start_node = Node(None, start)
start_node.g = start_node.h = start_node.f = 0
end_node = Node(None, end)
end_node.g = end_node.h = end_node.f = 0
# Initialize both open and closed list
open_list = []
closed_list = []
# Add the start node
open_list.append(start_node)
# Loop until you find the end
while len(open_list) > 0:
# Get the current node
current_node = open_list[0]
current_index = 0
for index, item in enumerate(open_list):
if item.f < current_node.f:
current_node = item
current_index = index
# Pop current off open list, add to closed list
open_list.pop(current_index)
closed_list.append(current_node)
# Found the goal
if current_node == end_node:
path = []
current = current_node
while current is not None:
path.append(current.position)
current = current.parent
return path[::-1] # Return reversed path
# Generate children
children = []
for new_position in [(0, -1), (0, 1), (-1, 0), (1, 0), (-1, -1), (-1, 1), (1, -1), (1, 1)]: # Adjacent squares
# Get node position
node_position = (current_node.position[0] + new_position[0], current_node.position[1] + new_position[1])
# Make sure within range
if node_position[0] > (len(maze) - 1) or node_position[0] < 0 or node_position[1] > (len(maze[len(maze)-1]) -1) or node_position[1] < 0:
continue
# Make sure walkable terrain
if maze[node_position[0]][node_position[1]] != 0:
continue
# Create new node
new_node = Node(current_node, node_position)
# Append
children.append(new_node)
# Loop through children
for child in children:
# Child is on the closed list
for closed_child in closed_list:
if child == closed_child:
continue
# Create the f, g, and h values
child.g = current_node.g + 1
child.h = ((child.position[0] - end_node.position[0]) ** 2) + ((child.position[1] - end_node.position[1]) ** 2)
child.f = child.g + child.h
# Child is already in the open list
for open_node in open_list:
if child == open_node and child.g > open_node.g:
continue
# Add the child to the open list
open_list.append(child)
def main():
maze = [[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]]
start = (0, 0)
end = (7, 6)
path = astar(maze, start, end)
print(path)
if __name__ == '__main__':
main()
I suggest you first understand the A* algorithm itself, here is a good video i found, check here. After understanding this, try to code it yourself in whatever language you want and then if you can't understand something ask about that stuff on SO.

Finding a sequence of numbers in a multi dimensional list

How do I find if a sequence of numbers exists in a two-dimensional list? i.e.
matrix: [[1, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0], [0,
0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0]]
if [1,1,1] in matrix:
print("It's in there")
else: print("It's not there")
I guess I could turn every int into a string but is there a slicker way?
Using an iterator over each cell of the matrix, I've managed to get a basic idea of what you wanted to achieve in Python script.
matrix = [[1, 1, 1, 0, 0, 0], [0, 0, 0, 0, 0, 0], [1, 0, 0, 0, 0, 0], [0, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0], [0, 0, 1, 0, 0, 0]]
matchCount = 0
lastNumber = None
for cell in matrix:
for number in cell:
if number == 1 and lastNumber == 1 or lastNumber == None:
matchCount += 1
if matchCount >= 3:
print("MATCH in cell " + str(cell))
lastNumber = number
matchCount = 0
lastNumber = None
What happens is, it steps into the cell. It it's the first iteration then allow entry into our iterator. We don't know if it's a match list yet, so push it back in our little list.
Stepping over and over, if we get enough matches in a row, then wonderful! Print we found a match in our matrix's cell!

Resources