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)
Here is my brief: 'Nimsticks is a turn-taking zero-sum game for two players. The game state consists of one or more piles of sticks. On their turn, a player may take 1, 2 or 3 sticks from any one pile. The player who takes the last stick is the loser of the game.
The problem is my code works fine when there is only one pile ([4], 1) but if I run it with multiple piles ([2, 3], 1) the if statements maxValue < v and minValue > v aren’t triggered (which they always should be due to inf) and are causing an error. Please help!
import copy
import math
def minimax_value(state):
if (state[0] == []):
return(result(state))
else:
if (state[1] == 1):
v, path = (max_value(state))
else:
v, path = (min_value(state))
optimalPath = path
optimalPath.append(state)
optimalPath.reverse()
print('Example play: ' + str(optimalPath))
return str(v)
def terminal(state):
if (state[0] == []):
return True
else:
return False
def utility(state):
if (state[1] == 1):
return(1, [])
else:
return(-1, [])
def max_value(state):
if terminal(state):
return(utility(state))
else:
v = -1 * math.inf
for c in next_states(state):
minValue, minPath = min_value(c)
if (minValue > v):
v = minValue
bestPath = minPath.copy()
bestSucc = c
bestPath.append(bestSucc)
return(v, bestPath)
def min_value(state):
if terminal(state):
return(utility(state))
else:
v = 1 * math.inf
for c in next_states(state):
maxValue, maxPath = max_value(c)
if (maxValue < v):
v = maxValue
bestPath = maxPath.copy()
bestSucc = c
bestPath.append(bestSucc)
return(v, bestPath)
def next_states(state):
player = state[1]
piles = copy.deepcopy(state[0])
pilesSave = copy.deepcopy(piles)
temp = []
newList = []
for x in range(0, len(piles)):
for y in range(1, 4):
piles[x] = piles[x] - y
if (piles[x] >= 0):
temp = copy.deepcopy(piles)
if (piles[x] == 0):
del temp[x]
newList.append(temp)
break
newList.append(temp)
piles[x] = pilesSave[x]
newList2 = []
for item in newList:
if (player == 1):
toAdd = (item, 2)
else:
toAdd = (item, 1)
newList2.append(toAdd)
return(newList2)
print(minimax_value(([2, 3], 1)))
I have been working on a task where I validate a already completed Sudoku puzzle and see if it has been done properly. I have been able to define the functions and able to section the code to different segments to allow the code to flow properly. I checked the rows,columns and the sub-matrix squares. The Sudoku puzzle is provided through a text file which is able to be read when running the program. When I run the program the only thing that displays is the Sudoku board. What do I have to do to show that the puzzle is
valid ?
def main():
fl =('sudoku board.txt')
grids =(is_puzzle(fl))
def is_Puzzle(fl):
with open(fl,'r') as files:
grids = []
lines = files.readlines()
for line in lines:
board = line.split()
wholenums = [int(items) for items in board]
print (wholenums)
grids.append(wholenums)
return grids
def is_puzzle(fl):
if check_rows(fl) and check_columns(fl) and check_squares(fl):
return True
else:
return False
def compare_all(fl):
compare = [1,2,3,4,5,6,7,8,9]
return sorted(lst) `== compare
def check_rows(fl):
for i in grids:
if not grids.compare_all(i):
return False
return True
def check_columns(fl):
for i in range(len(fl)):
contain = []
for j in range(len(fl[0])):
contain.append(fl[j][i])
if not grids.compare_all(hold):
return False
def check_squares(fl):
for i in range(0, 9, 3):
for j in range(0, 9, 3):
nums = fl[i][j:j+3]+fl[i+1][j:j+3]+fl[i+2][j:j+3]
if not grids.compare_all(nums):
return False
return True
main()
Here is your code fixed, and performs as expected. Besides a few tweaks, you have to check for the return value of is_puzzle() function.
def main():
fl = 'sudoku board.txt'
grids = (is_Puzzle(fl))
print()
if is_puzzle(grids):
print('The sudoku is correct!')
else:
print('The sudoku is wrong...')
def is_Puzzle(fl):
with open(fl, 'r') as files:
grids = []
lines = files.readlines()
for line in lines:
board = line.split()
wholenums = [int(items) for items in board]
print(wholenums)
grids.append(wholenums)
return grids
def is_puzzle(fl):
if check_rows(fl) and check_columns(fl) and check_squares(fl):
return True
else:
return False
def compare_all(fl):
compare = [1, 2, 3, 4, 5, 6, 7, 8, 9]
return sorted(fl) == compare
def check_rows(fl):
for i in fl:
if not compare_all(i):
return False
return True
def check_columns(fl):
for i in range(len(fl)):
contain = []
for j in range(len(fl[0])):
contain.append(fl[j][i])
if not compare_all(contain):
return False
return True
def check_squares(fl):
for i in range(0, 9, 3):
for j in range(0, 9, 3):
nums = fl[i][j:j + 3] + fl[i + 1][j:j + 3] + fl[i + 2][j:j + 3]
if not compare_all(nums):
return False
return True
main()
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
I am making a n-puzzle solver for my Artificial Intelligence class using A* in Python. The problem I have with my solution is , that the solve_puzzle() is not working as it should. While searching through the nodes it gets just deeper and deeper, but it never ends, the depth goes into really high numbers (depth of some child node is 5k for example).
I think it gets stuck in some loop and it keeps just looping through the same nodes (That is just what I think, I am not sure about that). I don't really know, I tried 3 different A* solutions, but the result is the same - the search loop never ends and never reaches the Goal.
I can solve very primitive puzzle like
start -> 0, 1, 2, 3, 4, 5, 6, 7, 8 goal -> 1, 2, 0, 3, 4, 5, 6, 7, 8 (just two moves to left are made)
but for just a little more complex puzzle like
start = 0, 1, 2, 3, 4, 5, 6, 7, 8
goal = 1, 2, 5, 0, 3, 4, 6, 7, 8 it is a never ending search.
I move the tile with number, not the blank tile.
Below is the whole code:
'''
class Node():
def __init__(self, n_size, m_size, current_state, goal_state, choosen_heuristic, parent):
self.n_size = n_size
self.m_size = m_size
self.dimension = self.n_size * self.m_size
self.current_state = current_state
self.goal_state = goal_state
self.choosen_heuristic = choosen_heuristic
self.parent = parent
self.child = [None, None, None, None]
self.last_operator = None
self.heuristic_cost = 0
self.depth = 0
self.priority = self.depth + self.heuristic_cost
def check_if_goal_is_reached(self):
if (self.heuristic_cost == 0):
print("GOAL IS REACHED!")
exit(1) #for now
#return
def get_blank_tile_position(self):
blank_position = 0
for i in range(self.dimension):
if (self.current_state[i] == 0):
blank_position = i
return blank_position
def misplaced_tiles_heuristic(self):
misplaced_sum = 0
for i in range(self.dimension):
if self.current_state[i] != self.goal_state[i]:
misplaced_sum += 1
#print("Count of misplaced tiless in this node is : ", misplaced_sum)
self.heuristic_cost = "misplaced"
self.heuristic_cost = misplaced_sum
self.check_if_goal_is_reached()
return misplaced_sum
def manhattan_distance(self):
distance_sum = 0
for i in range(self.dimension):
current_x = self.current_state[i] % self.n_size
goal_x = self.goal_state[i] % self.n_size
current_y = self.current_state[i] // self.m_size
goal_y = self.goal_state[i] // self.m_size
distance_sum += abs(current_x - goal_x) + abs(current_y - goal_y)
#print("Sum of Manhattan distance for this node is : ", distance_sum)
self.heuristic_cost = "manhattan"
#print("Hĺbka tohto uzla : ", self.depth)
self.check_if_goal_is_reached()
return distance_sum
def generate_children(self, choosen_heuristic):
possible_directions = []
current_node_blank_position = self.get_blank_tile_position()
# UP - I move a tile with number on it, not the blank tile
if current_node_blank_position < (self.dimension - self.n_size):
self.child[0] = Node(self.n_size, self.m_size, self.current_state, self.goal_state, self.choosen_heuristic, self.current_state)
self.child[0] = copy.deepcopy(self)
self.child[0].parent = self.current_state
self.child[0].last_operator = "UP"
self.child[0].depth = self.depth + 1
new_blank_position = current_node_blank_position + self.m_size
temp = self.child[0].current_state[current_node_blank_position]
self.child[0].current_state[current_node_blank_position] = self.child[0].current_state[new_blank_position]
self.child[0].current_state[new_blank_position] = temp
if choosen_heuristic == "misplaced":
self.child[0].misplaced_tiles_heuristic()
if choosen_heuristic == "manhattan":
self.child[0].manhattan_distance()
possible_directions.append("UP")
print("Depth of this node is : : ", self.child[0].depth)
else:
self.child[0] = None
# DOWN - I move a tile with number on it, not the blank tile
if current_node_blank_position > (self.n_size - 1):
self.child[1] = Node(self.n_size, self.m_size, self.current_state, self.goal_state, self.choosen_heuristic, self.current_state)
self.child[1] = copy.deepcopy(self)
self.child[1].parent = self.current_state
self.child[1].last_operator = "DOWN"
self.child[1].depth = self.depth + 1
new_blank_position = current_node_blank_position - self.m_size
temp = self.child[1].current_state[current_node_blank_position]
self.child[1].current_state[current_node_blank_position] = self.child[1].current_state[new_blank_position]
self.child[1].current_state[new_blank_position] = temp
if choosen_heuristic == "misplaced":
self.child[1].misplaced_tiles_heuristic()
if choosen_heuristic == "manhattan":
self.child[1].manhattan_distance()
possible_directions.append("DOWN")
#print("Depth of this node is : : ", self.child[1].depth)
else:
self.child[1] = None
# RIGHT - I move a tile with number on it, not the blank tile
if (current_node_blank_position + self.n_size) % self.m_size:
self.child[2] = Node(self.n_size, self.m_size, self.current_state, self.goal_state, self.choosen_heuristic, self.current_state)
self.child[2] = copy.deepcopy(self)
self.child[2].parent = self.current_state
self.child[2].last_operator = "RIGHT"
self.child[2].depth = self.depth + 1
new_blank_position = current_node_blank_position - 1
temp = self.child[2].current_state[current_node_blank_position]
self.child[2].current_state[current_node_blank_position] = self.child[2].current_state[new_blank_position]
self.child[2].current_state[new_blank_position] = temp
if choosen_heuristic == "misplaced":
self.child[2].misplaced_tiles_heuristic()
if choosen_heuristic == "manhattan":
self.child[2].manhattan_distance()
possible_directions.append("RIGHT")
#print("Depth of this node is : : ", self.child[2].depth)
else:
self.child[2] = None
# LEFT - I move a tile with number on it, not the blank tile
if (current_node_blank_position + 1) % self.m_size:
self.child[3] = Node(self.n_size, self.m_size, self.current_state, self.goal_state, self.choosen_heuristic, self.current_state)
self.child[3] = copy.deepcopy(self)
self.child[3].parent = self.current_state
self.child[3].last_operator = "LEFT"
self.child[3].depth = self.depth + 1
new_blank_position = current_node_blank_position + 1
temp = self.child[3].current_state[current_node_blank_position]
self.child[3].current_state[current_node_blank_position] = self.child[3].current_state[new_blank_position]
self.child[3].current_state[new_blank_position] = temp
if choosen_heuristic == "misplaced":
self.child[3].misplaced_tiles_heuristic()
if choosen_heuristic == "manhattan":
self.child[3].manhattan_distance()
possible_directions.append("LEFT")
#print("Depth of this node is : ", self.child[3].depth)
else:
self.child[3] = None
#print("From this node (the parent node) I can move to -> ", possible_directions)
def get_node_priority(node):
return node.priority
def solve_puzzle(n_size, m_size, current_state, goal_state, choosen_heuristic):
open_list = []
closed_list = []
init_node_parent = None
init_node = Node(n_size, m_size, current_state, goal_state, choosen_heuristic, init_node_parent)
open_list.append(init_node)
while len(open_list) != 0:
if (len(open_list) == 0):
print("Fail - solution not found !")
else:
node = open_list.pop(0)
if (node.parent != None):
node.check_if_goal_is_reached()
node.generate_children(choosen_heuristic)
closed_list.append(node)
temp_list = []
for i in range(4):
if node.child[i] != None:
temp_list.insert(0, node.child[i])
sorted_temp_list = sorted(temp_list, key=get_node_priority, reverse=True)
for x in range(len(sorted_temp_list)):
if sorted_temp_list[x] != None:
open_list.insert(0, sorted_temp_list[x])
def print_current_node(current_node):
puzzle = ""
if current_node is None:
puzzle = ""
print(puzzle)
else:
puzzle = ""
count_lines = 0
for i in range(current_node.dimension):
puzzle += (str(current_node.current_state[i]) + " ")
count_lines += 1
if (count_lines % current_node.m_size == 0):
puzzle += "\n"
print(puzzle)
def main():
###################
# Static Data #
###################
# static for now, later I will let user to choose
n_size = 3
m_size = 3
current_state = [0, 1, 2, 3, 4, 5, 6, 7, 8]
goal_state = [8, 0, 6, 5, 4, 7, 2, 3, 1]
choosen_heuristic = "manhattan"
start_time = time.process_time()
solve_puzzle(n_size, m_size, current_state, goal_state, choosen_heuristic)
end_time = time.process_time()
search_time = end_time - start_time
print("Solved in : ", search_time, "seconds.")
main()
'''
Make sure you test with a solvable puzzle.
Here are some solvable tests:
goal: {1,2,3,4,5,6,7,8,0}
6 steps: {1,3,5,4,0,2,7,8,6}
18 steps: {1,4,0,5,2,8,7,6,3}
26 steps: {2,1,7,5,0,8,3,4,6}
27 steps: {8,5,3,4,7,0,6,1,2}
28 steps: {0,6,7,3,8,5,4,2,1}
30 steps: {5,7,0,4,6,8,1,2,3}
31 steps: {8,6,7,2,5,4,3,0,1} (highest number of steps possible for 3x3 )