Find all (shortest) paths - python

For school i need to make an assignment. we have to find all paths.
This is the input
1->5
1, 2, 3; 2, 3; 3, 4; 4, 5; 5,
And this the output
1->2->3->4->5
1->3->4->5
However i am not even at this point yet, i am still trying to make my find path function work. I am trying to find my mistakes through print debugging, but i just do not understand why "graph[start]" gives me [2,3] instead of 1. Could anyone help me? I have provided my code below!
from typing import List
from collections import defaultdict
def stringify_path(path: List):
'''
Build string to print
'''
ret = ''
for id in path[:-1]:
ret = f'{ret}{id}->'
try:
ret = f'{ret}{path[-1]}'
except IndexError:
pass
return ret
def output(paths: List[List]):
'''
Prints all paths from the list in param
'''
paths_string = []
for p in paths:
paths_string.append(stringify_path(p))
print(*paths_string, sep='\n')
'''
DO NOT CHANGE ABOVE
'''
def find_paths(graph, start, target, visited, path):
print(graph)
# Mark the current node as visited and store in path
visited[start-1] = True
print(visited)
path.append(start)
print(path)
# If current vertex is same as destination, then print
# current path[]
if start == target:
print(path)
else:
# If current vertex is not destination
# Recur for all the vertices adjacent to this vertex
print(graph[start])
for i in graph[start]: #should start from 1??
if len(graph[start]) >= 1:
if visited[i] == False:
find_paths(graph, i, target, visited, path)
# Remove current vertex from path[] and mark it as unvisited
path.pop()
visited[start] = False
if __name__ == '__main__':
'''
Fetch starting and target node.
'''
start, target = [int(x) for x in input().split('->')]
'''
Fetch `;` separated twitter data. <id-1: str>, <follower_1-2: str>, ..<follower_1-2: str>; ...
i.e: 1, 2, 3; 2, 3, 1; 3, 2
'''
data = input()
data = data.split('; ')
#print(data)
graph = dict()
for d in data:
parts = d.split(',')
if len(parts) > 1:
id = parts[0]
id = id.strip()
followers = parts[1:]
followers = [x.strip() for x in followers if x.strip()]
# for f in followers:
# edges = [int(id), int(f)]
# print(edges)
#for i in followers:
#print(i)
if followers:
graph[int(id)] = ([int(x) for x in followers])
print('graph:', graph[start])
vertices = 5
visited = [False] * vertices
print(visited)
path = []
'''
TODO: Step 3: Call your 'find_paths` function with the parameters you defined.
'''
paths = find_paths(graph, start, target, visited, path)
print(paths)
'''
Print the paths.
'''
# output(paths)

Related

There is 8 puzzle game using a* algo. i want to set traversal limit of 2000 traversal in python

this is sample code of 8 puzzle game which take two matrix initial and goal state .
class Node:
def __init__(self,data,level,fval):
""" Initialize the node with the data, level of the node and the calculated fvalue """
self.data = data
self.level = level
self.fval = fval
def generate_child(self):
""" Generate child nodes from the given node by moving the blank space
either in the four directions {up,down,left,right} """
x,y = self.find(self.data,'_')
""" val_list contains position values for moving the blank space in either of
the 4 directions [up,down,left,right] respectively. """
val_list = [[x,y-1],[x,y+1],[x-1,y],[x+1,y]]
children = []
for i in val_list:
child = self.shuffle(self.data,x,y,i[0],i[1])
if child is not None:
child_node = Node(child,self.level+1,0)
children.append(child_node)
return children
def shuffle(self,puz,x1,y1,x2,y2):
""" Move the blank space in the given direction and if the position value are out
of limits the return None """
if x2 >= 0 and x2 < len(self.data) and y2 >= 0 and y2 < len(self.data):
temp_puz = []
temp_puz = self.copy(puz)
temp = temp_puz[x2][y2]
temp_puz[x2][y2] = temp_puz[x1][y1]
temp_puz[x1][y1] = temp
return temp_puz
else:
return None
def copy(self,root):
""" Copy function to create a similar matrix of the given node"""
temp = []
for i in root:
t = []
for j in i:
t.append(j)
temp.append(t)
return temp
def find(self,puz,x):
""" Specifically used to find the position of the blank space """
for i in range(0,len(self.data)):
for j in range(0,len(self.data)):
if puz[i][j] == x:
return i,j
class Puzzle:
def __init__(self,size):
""" Initialize the puzzle size by the specified size,open and closed lists to empty """
self.n = size
self.open = []
self.closed = []
def accept(self):
""" Accepts the puzzle from the user """
puz = []
for i in range(0,self.n):
temp = input().split(" ")
puz.append(temp)
return puz
def f(self,start,goal):
""" Heuristic Function to calculate hueristic value f(x) = h(x) + g(x) """
return self.h(start.data,goal)+start.level
def h(self,start,goal):
""" Calculates the different between the given puzzles """
temp = 0
for i in range(0,self.n):
for j in range(0,self.n):
if start[i][j] != goal[i][j] and start[i][j] != '_':
temp += 1
return temp
def process(self):
""" Accept Start and Goal Puzzle state"""
print("Enter the start state matrix \n")
start = self.accept()
print("Enter the goal state matrix \n")
goal = self.accept()
start = Node(start,0,0)
start.fval = self.f(start,goal)
""" Put the start node in the open list"""
self.open.append(start)
print("\n")
count=0
while True:
cur = self.open[0]
count=count+1
print("This Node number = \n", count)
print("")
print(" | ")
print(" | ")
print(" \\\'/ \n")
for i in cur.data:
for j in i:
print(j,end=" ")
print("")
""" If the difference between current and goal node is 0 we have reached the goal node"""
if(self.h(cur.data,goal) == 0):
break
for i in cur.generate_child():
i.fval = self.f(i,goal)
self.open.append(i)
self.closed.append(cur)
del self.open[0]
""" sort the opne list based on f value """
self.open.sort(key = lambda x:x.fval,reverse=False)
puz = Puzzle(3)
puz.process()
this code take initial state and goal state and start traversal and stop until
specific or reached goal state
i want to add limit of traversal to this code.so it itterate in
specific boundary either reached goal state or not

Trying to implement breadth first search from text file in python

So I was able to implement breadth first search like this. But Now I am trying to implement breadth first search from a text file that looks like this.
Textfile:
1,1
1,1
4,1
4,5
5,1
This is the code:
from collections import defaultdict
class Graph:
def __init__(self):
self.graph = defaultdict(list)
def addEdge(self,u,v):
self.graph[u].append(v)
def BFS(self, s):
visited = [False] * (max(self.graph) + 1)
queue = []
queue.append(s)
visited[s] = True
while queue:
s = queue.pop(0)
print (s, end = " ")
for i in self.graph[s]:
if visited[i] == False:
queue.append(i)
visited[i] = True
g = Graph()
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(1, 2)
g.addEdge(2, 0)
g.addEdge(2, 3)
g.addEdge(3, 3)
Output: 2 0 3 1
This is how I adjusted the text file, but i still cant figure out how to implement it:
data = open("ajd.txt", "r")
list_of_lists = []
for line in data.readlines():
stripped_line = line.strip('\n')
line_list = list(map(int, stripped_line.split(',')))
list_of_lists.append(line_list)
data.close()
print(list_of_lists)
adjLists = list_of_lists
def convert(a):
adjList = defaultdict(list)
for i in range(len(a)):
for j in range(len(a[I])):
if a[i][j]== 1:
adjList[i].append(j)
return adjList
Output:
[[1, 1], [1, 1], [4, 1], [4, 5], [5, 1]]
Hi I think this is what you want, but I don't know if it's right.
There was no exact description of the ajd.txt file, so I put a value arbitrarily. Maybe adj.txt has an explanation of the starting value.
If you tell me that part, I can give you the exact details.
from collections import defaultdict
class Graph:
def __init__(self):
self.graph = defaultdict(list)
def addEdge(self, u, v):
self.graph[u].append(v)
def BFS(self, s):
visited = [False] * (max(self.graph) + 1)
queue = []
queue.append(s)
visited[s] = True
while queue:
s = queue.pop(0)
print(s, end=" ")
for i in self.graph[s]:
if visited[i] == False:
queue.append(i)
visited[i] = True
g = Graph()
g.addEdge(0, 1)
g.addEdge(0, 2)
g.addEdge(1, 2)
g.addEdge(2, 0)
g.addEdge(2, 3)
g.addEdge(3, 3)
g.BFS(2)
def convert(a):
adjList = defaultdict(list)
for i in range(len(a)):
for j in range(len(a[i])):
if a[i][j] == 1:
adjList[i].append(j)
return adjList
print('')
data = open("ajd.txt", "r")
list_of_lists = []
for line in data.readlines():
stripped_line = line.strip('\n')
line_list = list(map(int, stripped_line.split(',')))
list_of_lists.append(line_list)
data.close()
print(list_of_lists)
adjLists = list_of_lists
new_g = Graph()
for line in list_of_lists:
new_g.addEdge(line[0], line[1])
# I'm not sure the starting point, so i set it 3 randomly
new_g.BFS(3)

<__main__.Find_Adj_node object at 0x0DE643E8> , class called under def function

I have following code where the class and def is defined.
Here we are reading a file which has start node, end node and distance between two nodes.
Example:
1 3 100
2 4 200
..so on..
import numpy as np
import pandas as pd
# STEP 1: Get the inout options to choose between shortest path and all configuration
path_type = int(input("Choose the option1 or option2 "))
if path_type == 1:
st_nd = int(input("Enter the start node: "))
ed_nd = int(input("Enter the end node: "))
# STEP 2: Import the data file
def import_data():
global data_points_df # Data_points
global data_points_max # NN
global Dist # Dist
global data_points_arr # NData_points
# Read the data as data frame
data_points_df = pd.read_csv('./Exercises/dp.txt', delimiter="\t")
data_points_arr = np.array(data_points_df)
data_points_max = np.max(data_points_arr[:, 0:2])
print(data_points_df)
print(data_points_arr)
print(data_points_max)
def Find_Adjacent_Nodes():
global K
global data_points_max # NN
K = np.array([]) # Empty Array
for i in range(data_points_max + 1):
result = np.where(data_points_arr[:, 0:2] == i)
print(i, result)
temp = data_points_arr[result[0], (result[1] + 1) % 2]
print(temp)
dst = data_points_arr[result[0], (result[1]) % 1 + 2]
print(dst)
print(Find_Adj_node(temp, dst))
K = np.append(K, Find_Adj_node(temp, dst))
return K
class Find_Adj_node:
Adj_nod = []
Nod_dist = []
def __init__(self, M, N):
self.Adj_nod = M
self.Nod_dist = N
if path_type == 1:
import_data()
Find_Adjacent_Nodes()
'''
when I run the command I see the following message.
9 (array([5, 7], dtype=int32), array([1, 1], dtype=int32))
[7 6]
[ 200 2000]
<__main__.Find_Adj_node object at 0x0DE643E8>
I would like to check what is inside K and how it is assigned. Logically I understand the it has [7,6] and the corresponding distance value as [200 2000]. The thing is how to print it and see.
Tried with k.* some options, but could not figure out.
BR,
SemiCode

Create a linked list function without creating another class

I am working on some practice exercises with linked lists and I got stuck with one function.
My program should create a Node class, take user input with create() function (number n and then takes in n number of elements), and has a function printLinkedList(p) to print it out. So far this works well but then I should create another function where I am going to be deleting the max element (if it occurs more than once, delete the first occurrence).
I found a function findMaxElement(p) that looks for the max, however, it doesn't work along my code (for example I get AttributeError: 'Node' object has no attribute 'head' error)
class Node:
def __init__(self, x = None):
self.data = x
self.next = None
def create():
n = int(input())
if n == 0:
return None
s = input().split()
p = Node(int(s[0]))
k = p
for i in range(1, n):
t = Node(int(s[i]))
k.next = t
k = t
return p
def printLinkedList(p):
if p == None:
print('Empty')
return
s = p
while s != None:
print(s.data, end = " ")
s = s.next
print()
def findMaxElement(p):
current = p.head
#Initializing max to initial node info
maximum = p.head.data
if(p.head == None):
print("List is empty")
else:
while(True):
#If current node's info is greater than max
#Then replace value of max with current node's info
if(maximum < current.info):
maximum = current.info
current= current.next
if(current == p.head):
break
return "Maximum value node in the list: "+ str(maximum)
#Driver code
a = create()
printLinkedList(a)
Input:
6
1 7 4 2 6 7
Expected result:
1 7 4 2 6 7
1 4 2 6 7
You could just define a findMaxElement() that traverses the linked-list in the same way that the printLinkedList() function is doing it (and finds the maximum value while doing so):
def findMaxElement(p):
if p == None:
return 'Empty List!'
current = p
maximum = p.data
while current != None: # Not end of list.
if current.data > maximum:
maximum = current.data
current = current.next
return "Maximum value node in the list: " + str(maximum)

How do I create a Set method for a class with a variable-dimension container?

If I have a list class that can be initialized with a variable number of dimensions, how do I set an entry at the lowest level of the list with an element? (Also would like to know if my get method should work in theory)
I'm trying to simulate board games that use multiple dimensions (Can you even imagine 5-th dimensional chess? How about 17th?)
class Board():
DIMENSIONS = [8, 8]
#board and pieces have their respective rules.
def __init__(self, D=[8,8]):
if len(D) <= 0:
board = [None for i in range(D)]
else:
board = [None for i in range(D[0])]
for j in range(1,len(D)):
board = [board for i in range(D[j])]
def get(self, location):
try:
for coordinate in location:
result = board[coordinate]
return result
except:
print('Error: Cannot get coordinate')
return None
def set(self, location, piece):
try:
for coordinate in location:
result = self.board[coordinate]
result = piece
except:
print('Error: Cannot set coordinate')
def move(self, start, end):
x = self.get(start)
if x is not None:
for m, r in x.moves, x.rules:
if self.get(is_legitimate(self, start, m, r)) == end:
= x
pass
#Check alignment and position, if it's transformable react according to board rules.
#returns false if not, but returns location if legit.
def is_legitimate(self, start, move, rule):
location = start
forwardback = True
while move != 1:
primes = [2]
while move % primes[-1] == 0:
if forwardback:
location[len(primes) // 2]+=1
else:
location[len(primes) // 2]-=1
move = move % primes[-1]
if not self.bounds(location):
return False
primes.append(next_prime(primes))
forwardback = not forwardback
def bounds(self, location):
for coordinate, d in location, self.DIMENSIONS:
if coordinate < 0 or coordinate > d:
return False
return True
#using prime numbers?
def next_prime(primes):
if len(primes) == 0:
return 2
prev_result = 1
result = 2
while prev_result != result:
prev_result = result
for x in primes:
if result == x or result % x == 0:
result += 1
break
return result
Code is mostly rough draft, don't play just look.

Categories