From fde713cecf5c46ec1e2bf49b1f711bdfed373aab Mon Sep 17 00:00:00 2001 From: cdez Date: Wed, 26 Feb 2025 15:33:51 -0700 Subject: [PATCH] Started Routefinding Part 1. Framework is mostly setup for the assignment. --- RouteFinding/06_tests.py | 145 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 145 insertions(+) diff --git a/RouteFinding/06_tests.py b/RouteFinding/06_tests.py index afbb3b1..5bf2af4 100644 --- a/RouteFinding/06_tests.py +++ b/RouteFinding/06_tests.py @@ -1,4 +1,149 @@ # Define Searcher class here. +# Define Searcher, hSLD, SearchNode. +import DRDViz +import math + +def hSLD(node, search): + # take the node value in + # find the node value coordinates + coords = search.nodeLocs[node] + goalCoords = search.nodeLocs[search.endNode] + # calculate the distance between the two points + distance = math.sqrt((abs(int(coords[0]) - int(goalCoords[0])))**2 + abs(int(coords[1]) - int(goalCoords[1]))**2) + return distance + +class SearchNode: + def __init__(self, label, pathcost): + self.label = label + self.pathcost = pathcost + self.node = tuple((label, pathcost)) + def showBasic(self): + # print(self.node) # debugging purposes + return self.node + def __eq__(self, object): + return ((self.label) == (object.label)) + def __lt__(self, object): + return ((self.label) < (object.label)) + def __repr__(self): + return repr(self.node) + +class Searcher: + def __init__(self, mapfile, searchType, verbose=False): + self.mapfile = mapfile + self.searchType = searchType + # load the mapfile's structure + with open(self.mapfile) as mapper: + mapContents = mapper.read() + mapContents = mapContents.split("\n") + for mapIter in range(len(mapContents)): + mapContents[mapIter] = mapContents[mapIter].split(", ") + for firstDimMapIter in range(len(mapContents) - 1): + for secondDimMapIter in range(len(mapContents[firstDimMapIter])): + mapContents[firstDimMapIter][secondDimMapIter] = mapContents[firstDimMapIter][secondDimMapIter].strip("')(][") + mapContents.pop(len(mapContents) - 1) + for tupleIter in range(len(mapContents)): + mapContents[tupleIter] = tuple(mapContents[tupleIter]) + # print(mapContents) # list of tuples + # print(mapContents[0]) # tuple of strings (data) + # [first node, second node, path cost, first node x, first node y, second node x, second node y] + # 0 1 2 3 4 5 6 + # print(mapContents[0][0]) # data, string format + # make two dictionaries of nodes, iterating through list of tuples to make note of every node's paths and locations + nodeLoc = dict() + nodePaths = dict() + for nodeIter in range(len(mapContents)): + # these node locations are fine, because they should technically be in only one place. + nodeLoc[mapContents[nodeIter][0]] = tuple((mapContents[nodeIter][3], mapContents[nodeIter][4])) + nodeLoc[mapContents[nodeIter][1]] = tuple((mapContents[nodeIter][5], mapContents[nodeIter][6])) + # however, this is only taking the first node path it gets to... + # I probably need a list instead, that gets updated if the node is not in the node's child list. + # check if the key exists, if it does, then add the value to the internal dictionary, + # if the internal dictionary doesn't exist, then create it and add the node. + if mapContents[nodeIter][0] not in nodePaths.keys(): + nodePaths[mapContents[nodeIter][0]] = dict() + nodePaths[mapContents[nodeIter][0]][mapContents[nodeIter][1]] = mapContents[nodeIter][2] + else: + if nodePaths[mapContents[nodeIter][0]].values() not in nodePaths[mapContents[nodeIter][0]].keys(): + nodePaths[mapContents[nodeIter][0]][mapContents[nodeIter][1]] = dict() + nodePaths[mapContents[nodeIter][0]][mapContents[nodeIter][1]] = mapContents[nodeIter][2] + else: + nodePaths[mapContents[nodeIter][0]][mapContents[nodeIter][1]] = mapContents[nodeIter][2] + if mapContents[nodeIter][1] not in nodePaths.keys(): + nodePaths[mapContents[nodeIter][1]] = dict() + nodePaths[mapContents[nodeIter][1]][mapContents[nodeIter][0]] = mapContents[nodeIter][2] + else: + if nodePaths[mapContents[nodeIter][1]].values() not in nodePaths[mapContents[nodeIter][1]].keys(): + nodePaths[mapContents[nodeIter][1]][mapContents[nodeIter][0]] = dict() + nodePaths[mapContents[nodeIter][1]][mapContents[nodeIter][0]] = mapContents[nodeIter][2] + else: + nodePaths[mapContents[nodeIter][1]][mapContents[nodeIter][0]] = mapContents[nodeIter][2] + self.nodePaths = nodePaths + self.nodeLocs = nodeLoc + # need to get the myViz attribute by importing the DRDViz stuff. + self.myViz = DRDViz.DRDViz() + # now, start using the myViz thingy to 'display' a map. + self.myViz.loadGraphFromFile(mapfile) + self.myViz.plot() + # create an 'open' list + self.open = list() + def setStartGoal(self, startNode, endNode): + self.startNode = startNode + self.endNode = endNode + self.myViz.markStart(self.startNode) + self.myViz.markGoal(self.endNode) + # add the starting node to the 'open' list. + starting = SearchNode(startNode, 0) + self.open.append(starting) + def successors(self, parentNode): + childList = list() + # grab the nodes from the nested dictionary given that the parentNode is a tuple. + nodeChildren = self.nodePaths.get(parentNode.label) + # grab each value from the dictionary, turn it into a SearchNode. + for node in nodeChildren.keys(): + childList.append(SearchNode(node, int(nodeChildren[node]))) + # sort the child node list + childList.sort() + return (childList) + def reset(self): + # clear all the items from the open list + self.open.clear() + # add the start node back into the list. + self.open.append(SearchNode(self.startNode, 0)) + # do I need to reset the visualization too? + def insert_front(self, nodeList): + # backwards "sort" + # loop through each element, and apply it to the beginning of the open list. + for item in nodeList: + if item not in self.open: + self.open.insert(0, item) + def insert_end(self, nodeList): + # forwards "sort" + # loop through each element, and apply it to the end of the open list. + for item in nodeList: + if item not in self.open: + self.open.append(item) + def insert_ordered(self, nodeList): + # sort by the lowest cost after adding all the elements to the open list. + # add the nodes to the list + self.open.extend(nodeList) + # sort via a lambda function key, using the sorted function + sortedList = sorted(self.open, key=lambda item: item.pathcost) + # clear out the open list + self.open.clear() + # replace it with the sorted list by extending the blank list. + self.open.extend(sortedList) + def search(self): + print(f"Begin Searching with type {self.searchType}") + if self.searchType.lower() == "depth": + print() + elif self.searchType.lower() == "breadth": + print() + elif self.searchType.lower() == "best": + print() + elif self.searchType.lower() == "a*": + print() + else: + print("Invalid searchtype.") # 10test.txt map x=Searcher("10test.txt", searchType="DEPTH", verbose=True)