【问题标题】:a* algorithm problem with one single edgea* 单边算法问题
【发布时间】:2020-12-25 10:39:29
【问题描述】:

我的 a* 算法的 python 实现有问题,但只有一个优势。 当我运行代码搜索具有两个损坏节点的路径时,代码会尝试比较单个节点以将其插入我的优先级队列中,但我已经定义了另一个类,这是帮助我向您解释的代码

 def a_search(self, start, goal):
    if start not in self.connections or goal not in self.connections:
        raise Exception("Non sono stati forniti nodi validi.")
    frontier = PriorityQueue()
    frontier.put(PrioritizedItem(0, start))
    visited_path = {}
    estimated_cost = dict()
    visited_path[start] = None
    estimated_cost[start] = 0
    while not frontier.empty():
        current = frontier.get()
        current = current.get_node()
        if current == goal:
            break
        next_node: Node
        for next_node in self.connection(current):
            new_cost = estimated_cost[current] + self.pathweight(current, next_node)
            if next_node not in estimated_cost or new_cost < estimated_cost[next_node]:
                estimated_cost[next_node] = new_cost
                priority = new_cost + self.euristic(next_node, goal)
                frontier.put(PrioritizedItem(priority, next_node))
                visited_path[next_node] = current
    return frontier

这是 PrioritizedItem 类

@dataclass(order=True)
class PrioritizedItem:
priority: float
item: object = field()

def get_node(self):
    return self.item

def __cmp__(self, other):
    if self.priority < other.priority:
        return -1
    elif self.priority > other.priority:
        return 1
    else:
        return 0

【问题讨论】:

  • __cmp__ 在 Python 3 中没有做任何事情 - 很久以前就被丰富的比较取代了。

标签: python python-3.x algorithm runtime-error


【解决方案1】:

__cmp__ 在 Python 3 中没有任何作用。它在很久以前就被 rich comparisons 取代了 - 每个比较运算符都有单独的方法,可以返回任意对象。

您告诉dataclass 为您生成与order=True 的比较方法。如果您不想在比较中考虑某个字段,您可以为该字段指定compare=False...但是具有相同优先级和不同项目的 PrioritizedItem 实例将被视为相等,这可能会产生奇怪的副作用。

不改变比较逻辑,处理这种事情的常用技巧是在你的元素中添加一个递增的计数器字段并将其用于平局,比如(priority, counter_value, item)而不是(priority, item)。如果您想坚持使用数据类,可以添加一个名为 counter 的字段或介于 priorityitem 之间的字段。


顺便说一句,如果 PriorityQueue 是来自 queue 模块的类,您应该改用 heapqqueue.PriorityQueue 专为用作优先级线程间消息传递系统而设计,它具有对单线程使用没有意义的设计决策和开销。例如,它在get 上阻塞,而不是在没有任何东西可获取时引发异常。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-20
    • 2021-08-23
    相关资源
    最近更新 更多