AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / coding / 问题 / 77920628
Accepted
Awe Kumar Jha
Awe Kumar Jha
Asked: 2024-02-01 21:38:44 +0800 CST2024-02-01 21:38:44 +0800 CST 2024-02-01 21:38:44 +0800 CST

这个特定版本的 A-star 算法是如何工作的(手工操作,而不是在 PC 上使用代码)?

  • 772

当我在 A* 算法中遇到这个问题时,我正在上人工智能课程: A_star问题图片

启发式如下:

          N : h(N)

         'A': 9,
         'B': 10,
         'C': 13,
         'D': 9,
         'E': 17,
         'F': 4,
         'G': 0,
         'H': 9,
         'I': 11,
         'J': 2,
         'K': 5,
         'L': 14,
         'M': 4,
         'N': 6,
         'O': 11,
         'P': 4,
         'Q': 4,
         'R': 6,
         'S': 12

起始节点是“S”,目标节点是“G”。节点间成本在图像中以红色指定。官方答案是路径“SCDFJG”,成本= 26。节点检查的顺序为:S,I,C,D,F,H,K,J。

根据我的理解,在每一步中,我们根据启发式 f = g + h 的值选择和扩展一个节点,其中 g 是沿着到达那里的路径从节点“S”移动到给定节点的成本。对于相等 g 值的情况,平局决胜者应该是原始问题中节点的字母顺序。

失败的尝试

S -> {C,H,I,K}
argmin(f{SC,SH,SI,SK}) = SI
I -> {N,O,L,E}
argmin(f{SIN,SIO,SIL,SIE}) = SIN
.
.
.
path = SINRQG
cost = 36

按照上述过程,我尝试了加权 A*(权重 W = 3),其中 f = g + 3*h,得到:

path = SKHFJG
cost = 48

在这种情况下,官方答案是路径 SINRQG!现在,在原始问题(w = 1)中,当我应用 Dijkstra 算法并仅用 f 作为决策启发式来代替 g 时,成本为 26,检查顺序为 S,I,N,K,H,C ,D,F,J,G。那么,如何手动使用 A* 呢?经过一番工作后,我可以从课程中获得解决方案的代码版本:

from collections import deque

class Graph:
    

    def __init__(self, adjacency_list):
        self.adjacency_list = adjacency_list

    def get_neighbors(self, v):
        return self.adjacency_list[v]

    # heuristic function with equal values for all nodes, H[n]
.....
def a_star_algorithm(self, start_node, stop_node):
        open_list = set([start_node])
        closed_list = set([])
        g = {}
        g[start_node] = 0
        parents = {}
        parents[start_node] = start_node
        W = 3 #weight

        while len(open_list) > 0:
            n = None

            # Printing open and closed lists
            print(f"Open List: {open_list}")
            print(f"Closed List: {closed_list}")

            for v in open_list:
                if n is None or (g[v] + W*self.h(v)[0], v) < (g[n] + W*self.h(n)[0], n):
                    n = v;

            if n is None:
                print('Path does not exist!')
                return None

            if n == stop_node:
                reconst_path = []
                while parents[n] != n:
                    reconst_path.append(n)
                    n = parents[n]
                reconst_path.append(start_node)
                reconst_path.reverse()
                print('Path found:', reconst_path)
                return reconst_path

            for (m, weight) in self.get_neighbors(n):
                if m not in open_list and m not in closed_list:
                    open_list.add(m)
                    parents[m] = n
                    g[m] = g[n] + weight
                    print(f"Inspecting node {m}")
                    print(g[m]+W*self.h(m)[0])

                else:
                    if g[m] > g[n] + weight:
                        g[m] = g[n] + weight
                        parents[m] = n
                        if m in closed_list:
                            closed_list.remove(m)
                            open_list.add(m)

            open_list.remove(n)
            closed_list.add(n)

        print('Path does not exist!')
        return None

# Test your modified A* algorithm
adjacency_list = {
.......

然而,我发现这太笨拙了,无法手动理解和实现,尽管它给出了正确的答案。

algorithm
  • 1 1 个回答
  • 38 Views

1 个回答

  • Voted
  1. Best Answer
    trincot
    2024-02-02T01:05:38+08:002024-02-02T01:05:38+08:00

    A* 星算法从不丢弃其扩展的路径。这些路径中的任何一条(无论是短路径还是长路径)仍将通过其 f 值与新路径竞争。

    您在书面分析中显然没有这样做:

    S -> {C,H,I,K}
    argmin(f{SC,SH,SI,SK}) = SI
    I -> {N,O,L,E}
    argmin(f{SIN,SIO,SIL,SIE}) = SIN
    .
    .
    .
    path = SINRQG
    cost = 36
    

    是的,S 扩展为 C、H、I、K,g、h 和 f 的值如下:

    节点 G H f=g+h
    SI 6 11 17 号
    SC 6 13 19
    SK 16 5 21
    SH 16 9 25

    你是对的,现在节点 I 扩展到 SIN、SIO、SIL、SIE,但你不应该丢弃 SC、SK 和 SH:它们仍然留在“竞争”中!所以我们得到这个:

    节点 G H f=g+h
    SC 6 13 19
    SK 16 5 21
    罪 16 6 22
    SH 16 9 25
    西奥 30 11 41
    安全等级等级 30 14 44
    SIE 30 17 号 47

    因此,下一个要扩展的节点不是 N(通过 SIN),而是 C(通过 SC),这符合预期的节点检查顺序(S,I,C,...)。

    如果您继续这样,从不丢弃路径,除了被其扩展名替换的路径之外,那么您将获得预期的结果。

    • 1

相关问题

  • 找到能够整除数组中整数之间互不差的最小正整数

  • Golang Codewars 中大量测试用例的最后一位失败

  • 编写 LMC 程序来计算用户输入的数字之和。停止前显示总和

  • 如何确定3个水壶问题中的可达状态?

  • 查找从 l 到 r 中按位与等于 0 的自然数对的数量

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    Vue 3:创建时出错“预期标识符但发现‘导入’”[重复]

    • 1 个回答
  • Marko Smith

    为什么这个简单而小的 Java 代码在所有 Graal JVM 上的运行速度都快 30 倍,但在任何 Oracle JVM 上却不行?

    • 1 个回答
  • Marko Smith

    具有指定基础类型但没有枚举器的“枚举类”的用途是什么?

    • 1 个回答
  • Marko Smith

    如何修复未手动导入的模块的 MODULE_NOT_FOUND 错误?

    • 6 个回答
  • Marko Smith

    `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它?

    • 3 个回答
  • Marko Smith

    何时应使用 std::inplace_vector 而不是 std::vector?

    • 3 个回答
  • Marko Smith

    在 C++ 中,一个不执行任何操作的空程序需要 204KB 的堆,但在 C 中则不需要

    • 1 个回答
  • Marko Smith

    PowerBI 目前与 BigQuery 不兼容:Simba 驱动程序与 Windows 更新有关

    • 2 个回答
  • Marko Smith

    AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String”

    • 1 个回答
  • Marko Smith

    我正在尝试仅使用海龟随机和数学模块来制作吃豆人游戏

    • 1 个回答
  • Martin Hope
    Aleksandr Dubinsky 为什么 InetAddress 上的 switch 模式匹配会失败,并出现“未涵盖所有可能的输入值”? 2024-12-23 06:56:21 +0800 CST
  • Martin Hope
    Phillip Borge 为什么这个简单而小的 Java 代码在所有 Graal JVM 上的运行速度都快 30 倍,但在任何 Oracle JVM 上却不行? 2024-12-12 20:46:46 +0800 CST
  • Martin Hope
    Oodini 具有指定基础类型但没有枚举器的“枚举类”的用途是什么? 2024-12-12 06:27:11 +0800 CST
  • Martin Hope
    sleeptightAnsiC `(表达式,左值) = 右值` 在 C 或 C++ 中是有效的赋值吗?为什么有些编译器会接受/拒绝它? 2024-11-09 07:18:53 +0800 CST
  • Martin Hope
    The Mad Gamer 何时应使用 std::inplace_vector 而不是 std::vector? 2024-10-29 23:01:00 +0800 CST
  • Martin Hope
    Chad Feller 在 5.2 版中,bash 条件语句中的 [[ .. ]] 中的分号现在是可选的吗? 2024-10-21 05:50:33 +0800 CST
  • Martin Hope
    Wrench 为什么双破折号 (--) 会导致此 MariaDB 子句评估为 true? 2024-05-05 13:37:20 +0800 CST
  • Martin Hope
    Waket Zheng 为什么 `dict(id=1, **{'id': 2})` 有时会引发 `KeyError: 'id'` 而不是 TypeError? 2024-05-04 14:19:19 +0800 CST
  • Martin Hope
    user924 AdMob:MobileAds.initialize() - 对于某些设备,“java.lang.Integer 无法转换为 java.lang.String” 2024-03-20 03:12:31 +0800 CST
  • Martin Hope
    MarkB 为什么 GCC 生成有条件执行 SIMD 实现的代码? 2024-02-17 06:17:14 +0800 CST

热门标签

python javascript c++ c# java typescript sql reactjs html

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve