我试图将此类的实例存储在来自heapq模块的堆中。但是,当我尝试推送节点时,我得到了TypeError: '<' not supported between instances of 'Node' and 'Node'
,并且添加了__gt__
并且
total_ordering
给出错误ValueError: must define at least one ordering operation: < > <= >=
。比较实现有什么不对吗?
@total_ordering
class Node:
def __init__(self, name, edgeCost=0, parent=None):
self.name = name
self.cost = edgeCost
self.parent = parent
def __gt__(self, other):
return self.cost > other.cost
def __lt__(self, other):
return self.cost < other.cost
def __eq__(self, other):
return isinstance(other, Node) and self.cost == other.cost
def path(self):
path = []
node = self
while node:
path.append(node.name)
return reversed(path)
def addNode(self, name, edgeCost=0):
return Node(name, edgeCost + self.cost, self)
编辑:
class Vertex:
def __init__(self, name, neighbors={}, heuristic=0):
self.name = name
self.neighbors = neighbors
self.heuristic = heuristic
self.node = None
def getWeight(self, neighbor):
return self.neighbors[neighbor]
def neighbors(self):
return iter(self.neighbors)
def getName(self):
return self.name
def searchNode(self, cost, parent):
self.node = Node(self.name, cost, parent)
return self.node
class Graph:
def __init__(self, graph={}):
self.vertices = graph
def addVertex(self, name, neighbors={}, heuristic=0):
vertex = Vertex(name, neighbors, heuristic)
self.vertices.update({name: vertex})
def getVertex(self, name):
return self.vertices[name]
def getVertices(self):
return self.vertices
这是我认为可能唯一相关的其他事情。但是导入文件时total_ordering会引发ValueError。
def greedy(graph, start, end):
fringe = []
visited = set()
node = mylib.Node(start)
heapq.heappush(fringe, node)
while fringe:
if node.name == end:
return node.path
node = heapq.heappop(fringe)
current = graph.getVertex(node.name)
visited.add(current)
for neighbor in current.neighbors:
vertex = graph.getVertex(neighbor)
if vertex not in visited and vertex.node not in fringe:
newNode = vertex.searchNode(current.neighbors[vertex.name], current.node)
heapq.heappush(fringe, newNode)
elif vertex.node in fringe:
tmp = fringe[fringe.index(vertex.node)]
if tmp.cost < vertex.node.cost:
newNode = vertex.searchNode(vertex.name, current.neighbor[vertex.name], current.node)
fringe.remove(vertex.node)
heapq.heappush(fringe, newNode)
主文件
import mylib
def main():
graph = mylib.Graph()
graph.addVertex("a", {"b": 2, "c": 2}, 5)
graph.addVertex("b", {"a": 2, "d": 1}, 7)
graph.addVertex("c", dict(zip(("a", "d", "f"), (2, 8, 3))), 4)
graph.addVertex("d", dict(zip(("s", "b", "c", "e"), (3, 1, 8, 2))), 7)
graph.addVertex("e", dict(zip(("s", "d", "h", "r"), (9, 2, 8, 2))), 5)
graph.addVertex("f", dict(zip(("c", "r", "g"), (3, 2, 2))), 2)
graph.addVertex("g", {"f": 2}, 2)
graph.addVertex("h", dict(zip(("e", "p", "q"), (8, 4, 4))), 11)
graph.addVertex("p", dict(zip(("s", "h", "q"), (1, 4, 4))), 14)
graph.addVertex("q", dict(zip(("h", "p"), (4, 15))), 12)
graph.addVertex("r", dict(zip(("e", "f"), (2, 2))), 3)
graph.addVertex("s", dict(zip(("d", "e", "p"), (3, 9, 1))), 14)
print(mylib.greedy(graph, "s", "g"))
if __name__ == '__main__':
main()
(原件缩进正确)