tuple index out of range in dfs - python

This is my code:
class solution:
lot = [[1,0,0], [1,0,0], [1,9,1]]
def move(lot):
if lot is None:
return -1
if (len(lot) <= 0 or len(lot[0]) <= 0):
return -1
q = []
visited = [len(lot)], [len(lot[0])]
direction= [(0,1), (0,-1), (1,0), (-1,0)]
q.append((0,0))
result = 0
while (len(q) > 0):
size = len(q)
for i in range(size):
node= q.pop(0)
x = node[0]
y = node[1]
visited[x][y]= True
if(lot[x][y] == 9):
return result
for dir in direction:
nx = x+ dir[0]
ny = y + dir[1]
r= len(lot[nx])
if (nx < 0 or nx >= len(lot) or ny < 0 or ny > r or lot[nx][ny] == 0 or visited[nx][ny] == True):
continue
q.append((nx,ny))
result += result
return result
print(move(lot))
It generates the following error:
File "prog.py", line 29, in move
if (nx < 0 or nx >= len(lot) or ny < 0 or ny > r or lot[nx][ny] == 0 or visited[nx][ny] == True):
IndexError: tuple index out of range

Your error is because of your visited variable. You're trying to access visited[nx][ny] which doesn't exist.
Separately, your DFS algorithm is incorrect. See here for how to implement DFS correctly.
Your function should be like this:
def move(lot):
if lot is None:
return -1
if (len(lot) <= 0 or len(lot[0]) <= 0):
return -1
q = []
visited = set()
q.append((0,0))
result = 0
while len(q)>0:
x,y = q.pop(0)
if(lot[x][y]==9):
return result
if (x,y) in visited:
continue
visited.add((x,y))
for d in [(0,1), (0,-1), (1,0), (-1,0)]:
nx = x + d[0]
ny = y + d[1]
if (nx<0 or nx>=len(lot) or ny<0 or ny>len(lot[0]) or lot[nx][ny]==0 or (nx,ny) in visited):
continue
q.append((nx,ny))
result += 1
return result

Related

Finding eulerian cycle: Turning recurrsion to iteration

I have this working code for finding eulerian cycle:
def eulerianCycle(node, graph):
cycle = [node]
for ih in range(len(graph)):
if graph[ih][node] == 1:
graph[node][ih] = 0
graph[ih][node] = 0
cycle = cycle[:1] + eulerianCycle(ih, graph) + cycle[1:]
return cycle
I want to convert it to iteration, but i cant figuire out how to do it.
My attempt
def eulerianCycle(node, graph):
stack = [node]
st = []
while len(stack) > 0:
node = stack.pop()
for ih in range(len(graph)):
if graph[ih][node] == 1:
graph[node][ih] = 0
graph[ih][node] = 0
stack.append(ih)
st.append(ih)
cycle = []
while len(st) > 0:
e = [st.pop()]
cycle = cycle[:1] + e + cycle[1:]
return cycle

k means algorithm python

Whenever k = 2, the code runs in a loop
if k > 2 it sets all, but one of the centroids location to 0,0
I've reviewed it a couple of times , and it doesn't seem like there are any errors probably some sort of logic flaw. The code starts by having a class and its methods which initiate the centroids, calculate the Euclidean distance, and reassign centroids to the average positions of the points that are in the cluster. It then runs a loop that consists of reassigning and calculating distance until a list of the assignments are equal and then plots it.
class Kmeans:
def __init__(self, K, dataset, centroids, sorting):
self.K = K
self.dataset = dataset
self.centroids = centroids
self.sorting = sorting
#sets starting position of centroids
def initializeCentroids(self):
bigX = 0
bigY = 0
self.centroids = []
for i in self.dataset:
if i[0] > bigX:
bigX = i[0]
if i[1] > bigY:
bigY = i[1]
for q in range(self.K):
self.centroids.append([random.randint(0, bigX), random.randint(0, bigY)])
plt.scatter((self.centroids[0][0], self.centroids[1][0]), (self.centroids[0][1], self.centroids[1][1]))
return self.centroids
#calculates euclidean distance
def calcDistance(self):
self.sorting = []
for w in self.dataset:
print(w)
distances = []
counter = 0
for centr in self.centroids:
distances.append(math.sqrt(abs((centr[0] - w[0] * centr[0] - w[0]) + (centr[1] - w[1] * centr[1] - w[1]))))
counter += 1
if counter > 0:
try:
if distances[0] > distances[1]:
distances.pop(0)
if distances[1] > distances[0]:
distances.pop(1)
counter -= 1
except IndexError:
pass
self.sorting.append([w, counter, distances[0]])
return self.sorting
def reassignCentroids(self):
counter3 = 1
for r in range(len(self.centroids)):
positionsX = []
positionsY = []
for t in self.sorting:
if t[1] == counter3:
positionsX.append(t[0][0])
positionsY.append(t[0][1])
population = len(positionsY)
if population == 0:
population = 1
self.centroids.append([sum(positionsX) / population, sum(positionsY) / population])
counter3 += 1
self.centroids.pop(0)
return
k = 4
dataSetSize = input("Enter the amount of tuples you want generated: ")
data_set = []
for o in range(int(dataSetSize)):
data_set.append((random.randint(0, 1000), random.randint(0, 1000)))
attempt = Kmeans(k, data_set, 0, 0)
attempt.initializeCentroids()
xvals = []
yvals = []
sortCompare = []
# plots
for p in data_set:
xvals.append(p[0])
yvals.append(p[1])
running = True
while running:
if len(sortCompare) > 1:
centroidChoice0 = []
centroidChoice1 = []
for p in sortCompare[0]:
centroidChoice0.append(p[1])
for d in sortCompare[1]:
centroidChoice1.append(d[1])
print(centroidChoice1)
print(attempt.centroids)
if centroidChoice1 == centroidChoice0:
running = False
for m in attempt.centroids:
plt.scatter((attempt.centroids[0][0], attempt.centroids[1][0]), (attempt.centroids[0][1], attempt.centroids[1][1]))
running = False
sortCompare.pop(0)
attempt.calcDistance()
sortCompare.append(attempt.sorting)
attempt.reassignCentroids()

All solutions for N-Queens problem prints empty board

As the title states, I've implemented the N-Queens problem for all soulutions but there is one problem, it prints an empty board. I saw a solution only where we put the printboard in an if statement but without a return in printboard i fail to see how it works`
#N Queens through Backtracking with all solutions
def initialize(n):
for key in ['queen','row','col','NWtoSE','SWtoNE']:
board[key] = {}
for i in range(n):
board['queen'][i] = -1
board['row'][i] = 0
board['col'][i] = 0
for i in range (2*n-1):
#Sum of NW to SE diagonal add to constant i.e (i+j) = const
board['SWtoNE'][i] = 0
for i in range (-(n-1), n):
#Difference of SW to NE diagonal is constant i.e (j-i) = const
board['NWtoSE'][i] = 0
def isAvailable(i, j):
return (board['row'][i] == 0 and board['col'][j] == 0 and
board['NWtoSE'][j-i] == 0 and board['SWtoNE'][j+i] == 0)
def addQueen(i, j):
board['queen'][i] = j
board['row'][i] = 1
board['col'][j] = 1
board['NWtoSE'][j-i] = 1
board['SWtoNE'][j+i] = 1
def undo(i, j):
board['queen'][i] = -1
board['row'][i] = 0
board['col'][j] = 0
board['NWtoSE'][j-i] = 0
board['SWtoNE'][j+i] = 0
def printboard():
for i in board['queen'].keys():
print((i, board['queen'][i]), end = " ")
print()
def placequeen(i):
n = len(board['queen'].keys())
for j in range(n):
if(isAvailable(i, j)):
addQueen(i, j)
if i == n-1:
printboard()
else:
placequeen(i+1)
undo(i,j)
board = {}
n = int(input("Enter number of queens : "))
initialize(n)
printboard()
The following is the solution which I don't understand
if placequeen(0): printboard()

Dijkstra's shortest path

I'm VERY new to Python (self learning) and am writing some code, and have read as much as possible (both on this website and youtube) to figure it out, and I'm perplexed as to why it's not working for me
I've generated this dictionary of dictionaries (may not be most efficient, please let me know how to improve, been doing this a couple weeks only):
graphx = []
all_locs = []
def graph(width, height):
for r in range(height):
row = []
for c in range(width):
t = (r, c)
row.append(t)
all_locs.append(t)
graphx.append(row)
graph(width, height)
# # Builds a dictionary of all nodes, and their weight
weighted_grid = {}
for node in graphx:
for c in node:
n = {}
s = {}
e = {}
w = {}
if (c[0] < height) and (c[0] > 0):
n[c[0] + 1, c[1]] = 1
s[c[0] - 1, c[1]] = 1
elif c[0] == 0:
n[c[0] + 1, c[1]] = 1
elif c[0] == height:
s[c[0] - 1, c[1]] = 1
if c[1] < width and c[1] > 0:
e[c[0], c[1] + 1] = 1
w[c[0], c[1] - 1] = 1
elif c[1] == 0:
e[c[0], c[1] + 1] = 1
elif c[1] == height:
w[c[0], c[1] - 1] = 1
temp = {}
blank = {}
if n != blank:
temp[c[0] + 1, c[1]] = 1
if e != blank:
temp[c[0], c[1] + 1] = 1
if s != blank:
temp[c[0] - 1, c[1]] = 1
if w != blank:
temp[c[0], c[1] - 1] = 1
weighted_grid[c[0],c[1]] = temp
When I run dijikstras, using the the tuples as start and destination, I get an error. Here's the version of dijkstras I'm running:
def dijkstra(graph, start, goal):
shortest_distance = {} # records the current cost to reach that node.
track_predecessor = {} # keeps track of the path that led to this node.
unseen_nodes = graph # Iterate through the graph to check all nodes.
infinity = 99999 # Make it any large number,greater than possible path weights.
track_path = [] # gives us the trace-back path of the optimal route
for node in unseen_nodes:
shortest_distance[node] = infinity
shortest_distance[start] = 0
while unseen_nodes:
min_distance_node = None
for node in unseen_nodes:
if min_distance_node is None:
min_distance_node = node
elif shortest_distance[node] < shortest_distance[min_distance_node]:
min_distance_node = node
path_options = graph[min_distance_node].items()
for child_node, weight in path_options:
if weight + shortest_distance[min_distance_node] < shortest_distance[child_node]:
shortest_distance[child_node] = weight + shortest_distance[min_distance_node]
track_predecessor[child_node] = min_distance_node
unseen_nodes.pop(min_distance_node)
current_node = goal
while current_node != start:
try:
track_path.insert(0, current_node)
current_node = track_predecessor[current_node]
except KeyError:
break
track_path.insert(0, start)
if shortest_distance[goal] != infinity:
pass
The error I get is:
Traceback (most recent call last):
File "C:/Users/Dave/Desktop/Important/PycharmProjects/DMT2/dungeonmasterstome/Main.py", line 318, in <module>
dijkstra(weighted_grid, (0, 0), (0,1))
File "C:/Users/Dave/Desktop/Important/PycharmProjects/DMT2/dungeonmasterstome/Main.py", line 300, in dijkstra
if weight + shortest_distance[min_distance_node] < shortest_distance[child_node]:
KeyError: (0, 30)
Thoughts and thanks for any help and constructive criticism.

Python: Point in polygon, boundary and vertex check (ray casting)

So I have written some code to check whether a point [(x,y)] lies within a polygon [(x,y), (x,y), (x,y), (x,y)] but the code fails if the point lies on a boundary or a vertex, I need this to be classed as lying within the polygon. This is the code:
def areasign(poly):
sumarea = 0
for i in range(0, len(poly)-1):
xi = poly[i][0]
yi = poly[i][1]
xj = poly[i+1][0]
yj = poly[i+1][1]
sumarea = sumarea + ((xi*yj)-(yi*xj))
if sumarea == 0: return 0
if sumarea < 0: return -1
if sumarea > 0: return 1
def lineintersection(xy, ij):
xyi = []
xyj = []
ijx = []
ijy = []
xyi.extend(xy)
xyj.extend(xy)
xyi.append(ij[0])
xyj.append(ij[1])
xyi.append(xy[0])
xyj.append(xy[0])
ijx.extend(ij)
ijy.extend(ij)
ijx.append(xy[0])
ijy.append(xy[1])
ijx.append(ij[0])
ijy.append(ij[0])
a = areasign(xyi)
b = areasign(xyj)
c = areasign(ijx)
d = areasign(ijy)
if (a!= b) and (c!=d):
return True
else:
return False
def openpointfile(fname):
p = []
f = open(fname)
for line in f:
line = line.replace('POINT(', '')
line = line.replace(')', '')
vals = line.split(' ')
res = map(float, vals)
ctuple = tuple(res)
p.append(ctuple)
print ctuple
f.close()
return p
points = openpointfile('C:/Users/Dan/Documents/Informatics/Data/Point_On_Line.txt')
def openpolygonfile(fname):
p = []
f = open(fname)
for line in f:
line = line.replace('POLYGON((', '')
line = line.replace('))', '')
s = line.split(',')
poly = []
for coord in s:
vals = coord.split(' ')
res = map(float, vals)
ctuple = tuple(res)
poly.append(ctuple)
p.append(poly)
f.close()
return p
polys = openpolygonfile('C:/Users/Dan/Documents/Informatics/Data/Polygon_On_Line.txt')
def pointinpoly(points, polys):
infinity = tuple([100000000.0, 100000010.0])
sum = 0
testline = (points, infinity)
for i in range(0, len(poly)-1):
start = poly[i]
end = poly[i+1]
line = (start, end)
l = lineintersection(line, testline)
if l == True:
sum = sum + 1
if sum % 2 == 0:
return False
else:
return True
pointcount = 0
for point in points:
pointcount = pointcount + 1
polycount = 0
for poly in polys:
polycount = polycount + 1
l = pointinpoly(point, poly)
res = 'Point ' + str(pointcount) + ' lies within Polygon ' + str(polycount) + ' = ' + str(l)
print l
print (res)
Like i said before this doesnt work if the point lies on a boundary or a vertex, i have this function that i found on here that seems to work but i can't find a way to get it my files into the correct format for the function and to get it to iterate oer a list of polygons.
def point_in_poly(x,y,poly):
# check if point is a vertex
if (x,y) in poly: return "IN"
# check if point is on a boundary
for i in range(len(poly)):
p1 = None
p2 = None
if i==0:
p1 = poly[0]
p2 = poly[1]
else:
p1 = poly[i-1]
p2 = poly[i]
if p1[1] == p2[1] and p1[1] == y and x > min(p1[0], p2[0]) and x < max(p1[0], p2[0]):
return "IN"
n = len(poly)
inside = False
p1x,p1y = poly[0]
for i in range(n+1):
p2x,p2y = poly[i % n]
if y > min(p1y,p2y):
if y <= max(p1y,p2y):
if x <= max(p1x,p2x):
if p1y != p2y:
xints = (y-p1y)*(p2x-p1x)/(p2y-p1y)+p1x
if p1x == p2x or x <= xints:
inside = not inside
p1x,p1y = p2x,p2y
if inside: return "IN"
else: return "OUT"
Any help on how to build that function into my existing code or any help on a new function that could be used to check if the point lies on the boundary of a polygon or on a vertex

Categories