我朋友写了一个BFS代码。它对她有用,但是当我在 python IDLE 中尝试时,它显示了这条消息: 这是完整的代码: 节点.py:
from enum import IntEnum
# You can get the enumeration based on integer value, or make comparison
# ex: d = Direction(1), then d would be Direction.NORTH
# ex: print(Direction.SOUTH == 1) should return False
class Direction(IntEnum):
NORTH = 1
SOUTH = 3
WEST = 2
EAST = 4
class Successor:
def __init__(self,successor ,direction, length=1):
self.SNode=successor
self.direction=Direction(direction)
self.length=length
# Construct class Node and its member functions
# You may add more member functions to meet your needs
class Node:
def __init__(self, index=0):
self.index = index
self.snumber=0
# store successor as (Node, index ,direction to node, distance)
self.Successors = []
self.OSuccessors = []
self.pathList=[]
self.nodecount=-1
def getIndex(self):
return self.index
def getSuccessors(self):
s=self.Successors
print("Successor list of ",self.getIndex(),": ")
for u in s:
if(u.SNode.nodecount>=0):
print(u.SNode.getIndex(),"is used")
s.remove(u)
else:
print("Node",u.SNode.getIndex(),":", "length:", u.length, "direction: ", u.direction,u.SNode.nodecount)
return s
def setSuccessor(self, successor, direction, length=1):
o= Successor(successor,direction)
self.OSuccessors.append(o)
a=self
i=1
while(i<length):
b=Node(self.getIndex()*10000+successor.getIndex()*100+i)
a.addSuccessor(b,direction)
a=b
i+=1
s= Successor(successor,direction,length)
a.Successors.append(s)
#print("For Node",a.getIndex(),", #",a.snumber," successor",s.SNode.getIndex(),"is set.")
return
def addSuccessor(self, successor,direction):
s= Successor(successor,direction)
self.Successors.append(s)
#print("For Node",self.getIndex(),", #",self.snumber," successor",s.SNode.getIndex(),"is set.")
return
def getDirection(self, nd):
for succ in self.OSuccessors:
if succ.SNode.getIndex() == nd.getIndex():
#print(nd.getIndex(),"is in the", succ.direction,"direction of ",self.getIndex())
return succ.direction
print("the given node is not adjacent")
return 0
def isSuccessor(self, nd):
for succ in self.OSuccessors:
if succ.SNode.getIndex()== nd.getIndex():
#print(nd.getIndex(),"is adjacent with", self.getIndex())
return True
#print(nd.getIndex(),"is not adjacent with", self.getIndex())
return False
TN=Node(1)
TN1=Node(0)
TN2=Node(2)
TN3=Node(3)
print("----------------------------")
TN.setSuccessor(TN2,Direction.EAST,5)
TN.setSuccessor(TN3,Direction.SOUTH,3)
TN.getSuccessors()
print("----------------------------")
TN.isSuccessor(TN1)
TN.getDirection(TN1)
#TN.getLength(TN1)
print("----------------------------")
TN.isSuccessor(TN2)
TN.getDirection(TN2)
#TN.getLength(TN2)
print("----------------------------")
TN.isSuccessor(TN3)
TN.getDirection(TN3)
print(TN.OSuccessors[1].direction)
#TN.getLength(TN3)
print("----------------------------")
迷宫.py:
from node import *
import numpy as np
import csv
import pandas
from enum import IntEnum
import math
class Action(IntEnum):
ADVANCE = 1
U_TURN = 2
TURN_RIGHT = 3
TURN_LEFT = 4
HALT = 5
class Maze:
def searchNode(self, ind):
for n in self.nodes:
if(n.getIndex()==ind):
return n
print("there is no such node as: ",ind)
return None
def __init__(self, filepath):
# TODO : read file and implement a data structure you like
# For example, when parsing raw_data, you may create several Node objects.
# Then you can store these objects into self.nodes.
# Finally, add to nd_dict by {key(index): value(corresponding node)}
self.raw_data = pandas.read_csv(filepath).values
#print("-------------------------------------------")
#print("Raw data =\n",self.raw_data)
#print("-------------------------------------------")
self.nodeNumber = self.raw_data.__len__()
#print("-------------------------------------------")
#print("Node number =",self.nodeNumber)
#print("-------------------------------------------")
self.nodes = []
#print("-------------------------------------------")
#print("Nodes =",)
for N in self.raw_data:
n=Node(N[0])
self.nodes.append(n)
# print("-------------------------------------------")
for N in self.raw_data:
if(N[1]!=0):
a=self.searchNode(N[1])
self.nodes[N[0]-1].setSuccessor(a, Direction.NORTH, N[5])
if(N[2]!=0):
a=self.searchNode(N[2])
self.nodes[N[0]-1].setSuccessor(a, Direction.SOUTH, N[6])
if(N[3]!=0):
a=self.searchNode(N[3])
self.nodes[N[0]-1].setSuccessor(a, Direction.WEST, N[7])
if(N[4]!=0):
a=self.searchNode(N[4])
self.nodes[N[0]-1].setSuccessor(a, Direction.EAST, N[8])
self.nd_dict =[] # key: index, value: the correspond node
def getStartPoint(self):
if (len(self.nd_dict) < 2):
print("Error: the start point is not included.")
return 0
return self.nd_dict[1]
def getNodeDict(self):
return self.nd_dict
def BFS(self, nd):
print("----------------BFS----------------")
# TODO : design your data structure here for your algorithm
nd.nodecount=0
nd.pathList.append((0,nd,0))
Q=[]
Q.append(nd.getSuccessors())
for u in nd.getSuccessors():
u.SNode.nodecount=nd.nodecount+1
u.SNode.pathList.append(nd)
u.SNode.pathList.append(u.SNode)
# print("========================================")
print(nd.getIndex(),"to",u.SNode.getIndex(),"(",u.SNode.nodecount,")")
#print("========================================")
for x in Q:
for u in x:
Q.append(u.SNode.getSuccessors())
# print("origin: ",u.SNode.getIndex())
for v in u.SNode.getSuccessors():
#print("next node",v.SNode.getIndex())
if(v.SNode.nodecount<0):
v.SNode.nodecount=u.SNode.nodecount+1
for a in u.SNode.pathList:
v.SNode.pathList.append(a)
v.SNode.pathList.append(v.SNode)
# print("========================================")
print(u.SNode.getIndex(),"to",v.SNode.getIndex(),"(",u.SNode.nodecount,")")
# print("========================================")
# Tips : return a sequence of nodes from the node to the nearest unexplored deadend
return None
def BFS_2(self, nd_from, nd_to):
# TODO : similar to BFS but with fixed start point and end point
self.BFS(nd_from)
for a in nd_to.pathList:
if(a.getIndex()<100):
self.nd_dict.append(a.getIndex())
print("----------------result from",nd_from.getIndex(),"to",nd_to.getIndex(),"-----------------")
# Tips : return a sequence of nodes of the shortest path
return None
def getAction(self, car_dir, nd_from, nd_to):
# TODO : get the car action
# Tips : return an action and the next direction of the car if the nd_to is the Successor of nd_to
new_dir = nd_from.getDirection(nd_to)
print(((new_dir+4-car_dir)%4))
if(nd_from==nd_to):
A = Action.HALT
else:
if(new_dir==0):
return 0
if(((new_dir+4-car_dir)%4)==1):
A = Action.TURN_RIGHT
if(((new_dir+4-car_dir)%4)==3):
A = Action.TURN_LEFT
if(((new_dir+4-car_dir)%4)==2):
A = Action.U_TURN
if(((new_dir+4-car_dir)%4)==0):
A = Action.ADVANCE
# If not, print error message and return 0
print(A)
return A
def getActions(self, nodes):
# TODO : given a sequence of nodes, return the corresponding action sequence
# Tips : iterate through the nodes and use getAction() in each iteration
return None
def actions_to_str(self, actions):
# cmds should be a string sequence like "fbrl....", use it as the input of BFS checklist #1
cmd = "fbrls"
cmds = ""
for action in actions: cmds += cmd[action-1]
print(cmds)
return cmds
def strategy(self, nd):
return self.BFS(nd)
def strategy_2(self, nd_from, nd_to):
return self.BFS_2(nd_from, nd_to)
M=Maze('small_maze.csv')
#M.BFS_2(M.searchNode(3),M.searchNode(1))
M.getAction(Direction.EAST,M.searchNode(3),M.searchNode(2))
#M.getNodeDict()
#M.actions_to_str(Action(Action.TURN_LEFT))
这是我们的 csv 文件: "nan" 可能是 csv 文件中的空白空间
我怎样才能让它发挥作用?
node.py最后的代码可以,但是当我在maze.py中使用getIndex()或nodecount方法时,就不行了。我也尝试将 maze.py 的末尾更改为:
M=Maze('small_maze.csv')
M.searchNode(3.0)