Поиск единой стоимости (TypeError: объект 'Graph' не подлежит подписке)
Я реализую функцию Uniform Cost Search в python, но когда я пытаюсь запустить свой код, появляется сообщение об ошибке "TypeError: объект 'Graph' не подлежит подписке". Вот мой код ниже. Я импортировал очередь и график в свою основную функцию. Я занимался этим некоторое время, но не смог найти проблему, может ли кто-нибудь помочь с этим? Благодаря:
from graph import Graph
from queue import PriorityQueue
def uniform_cost_search(graph, start_node, goal_node):
queue=PriorityQueue()
queue.insert([start_node],0)
while not queue.is_empty():
node=queue.remove()
current=node[1][len(node[1])-1]
if goal_node in node[1]:
print("Path found:"+str(node[1])+",Cost="+str(node[0]))
break
cost=node[0]
for i in graph[current]:# This line is causing the error
temp=node[1][:]
temp.append(i)
queue.insert(temp,cost+graph[current][i])
if __name__ == "__main__":
# Defining Graph
graph = Graph()
# setting up nodes and neighbours
graph.edges = {
'A': set(['B', 'D']),
'B': set(['A','E','C']),
'C': set(['B', 'E', 'G']),
'D': set(['A','E','F']),
'E': set(['B', 'C', 'D', 'G']),
'F': set(['D','G']),
'G': set(['F','E','C'])
}
# setting up connection costs
graph.weights = {
'AB': 5, 'AD': 3,
'BA': 5, 'BE': 4, 'BC': 1,
'CB': 1, 'CE': 6, 'CG': 8,
'DA': 3, 'DE': 2, 'DF': 2,
'EB': 4, 'EC': 6, 'ED': 2, 'EG': 4,
'FD': 2, 'FG': 3,
'GF': 3, 'GE': 4, 'GC': 8
}
uniform_cost_search(graph, 'A', 'G')
"""
the above statement should result in the following:
Shortest Path: A,D,F,G
Cost: 8
"""
Код для графика:
class Graph:
def __init__(self):
self.edges = {} # dictionary of edges NODE: NEIGHBOURS
self.weights = {} # dictionary of NODES and their COSTS
def neighbours(self, node):
"""
The function returns the neighbour of the node passed to it,
which is essentially the value of the key in the edges dictionary.
:params node: (string) a node in the graph
:return: (list) neighbouring nodes
"""
return self.edges[node]
def get_cost(self, from_node, to_node):
"""
Gets the cost of a connection between adjacent nodes.
:params from_node: (string) starting node
:params to_node: (string) ending node
:return: (int)
"""
return self.weights[(from_node + to_node)]
if __name__ == "__main__":
# testing out the graph class
graph = Graph()
# setting up nodes and neighbours
graph.edges = {
'A': set(['B', 'D']),
'B': set(['A','E','C']),
'C': set(['B', 'E', 'G']),
'D': set(['A','E','F']),
'E': set(['B', 'C', 'D', 'G']),
'F': set(['D','G']),
'G': set(['F','E','C'])
}
# setting up connection costs
graph.weights = {
'AB': 5, 'AD': 3,
'BA': 5, 'BE': 4, 'BC': 1,
'CB': 1, 'CE': 6, 'CG': 8,
'DA': 3, 'DE': 2, 'DF': 2,
'EB': 4, 'EC': 6, 'ED': 2, 'EG': 4,
'FD': 2, 'FG': 3,
'GF': 3, 'GE': 4, 'GC': 8
}
print("Neighbours of Node A are:",graph.neighbours('A'))
print("Cost going from A to D is:", graph.get_cost('A','D'))
Код очереди:
import heapq
class PriorityQueue:
def __init__(self):
self.__queue = []
self.__index = 0
def insert(self, item, priority):
"""
The function takes in the item and its priority, wraps it up in a tuple and
inserts it in the heap.
:params item: item to be inserted into the queue
:params priority: the priority of the item to be inserted
:return: None
"""
heapq.heappush(self.__queue, (priority, self.__index, item))
self.__index += 1
def remove(self):
"""
The functions removes the lowest priority item from the priority queue (via heaps)
and returns the item along with the cost of it.
:return : the item with the lowest priority
"""
temp = heapq.heappop(self.__queue)
cost = temp[0]
item = temp[-1]
return cost, item
def is_empty(self):
"""
Checks whether the queue is empty or not.
:returns: (Boolean)
"""
return len(self.__queue) == 0
if __name__ == "__main__":
# testing priority queue
queue = PriorityQueue()
queue.insert('e', 9)
queue.insert('a', 2)
queue.insert('h', 13)
queue.insert('c', 11)
print(queue.remove())
print(queue.remove())
print(queue.remove())
1 ответ
Чтобы иметь подписку, тип объекта должен либо наследоваться от другого типа, который может быть подписан (например, dict), либо реализовывать специальный метод
__getitem__()
.
Graph
не делает ни того, ни другого, поэтому это не индексируемый тип объекта.