基于A*的网格地图最短路径问题求解

news2024/11/20 12:44:49

基于A*的网格地图最短路径问题求解

  • 一、A*算法介绍、原理及步骤
  • 二、Dijkstra算法和A*的区别
  • 三、A*算法应用场景
  • 四、启发函数
  • 五、距离
  • 六、基于A*的网格地图最短路径问题求解
    • 实例分析
    • 完整代码
  • 七、A*算法的改进思路

一、A*算法介绍、原理及步骤

A*搜索算法(A star algorithm)是用于寻路和图遍历的最佳和流行的技术之一。A*搜索算法,不像其他传统算法,它有“大脑”,是一个真正的智能算法将它与其他传统算法区分开来,A*算法作为Dijkstra算法和BFS的结合算法,其与这两种算法的区别就是采用了启发函数,这也是这个算法的核心。

许多游戏和基于web的地图都使用这种算法来非常有效地找到最短路径(近似)。为了在现实生活中接近最短路径,比如在地图中,有很多障碍的游戏中。我们可以考虑一个有几个障碍的二维网格,我们从一个起点(下图红色)开始,寻找到达终点(下图绿色)的最短路径问题。

A*算法思想:
A*搜索算法所做的是,从起点开始,根据一个值 f f f选择下一步移动的网格, f = g + h f=g+h f=g+h。在每一步中,它选择具有最低 f f f的节点进行处理。
其中:

  • g g g为从起始点移动到给定方格的移动成本
  • h h h为从给定方格移动到最终目的地的估计移动成本,通常被称为启发式函数,是一种猜测或者估算。在找到路径之前,不可能知道实际的距离,因为各种各样的东西都可能挡在路上(墙壁、水等)。计算 h h h的方法有很多。

算法步骤如下:
输入:图,起点 src \text{src} src,终点 tgt \text{tgt} tgt, 每个点的父节点 node_parent \text{node\_parent} node_parent用于保存最有路径。
输出:起点到终点的最短路径。
step1. \text{step1.} step1. 初始化open listclosed list,将起点加入open list,并设置优先级为0(优先级最高)。【注】open list可以是一个优先队列。
step2. \text{step2.} step2. while open list is not empty: \text {while open list is not empty}: while open list is not empty
    a)查找open list中 f f f值最小的节点,把它作为当前要处理的节点cur_node,将cur_node从open list中删除。
    b) if cur_node == tgt \text {if cur\_node == tgt} if cur_node == tgt,跳出 while \text {while} while循环,停止搜索
    c) else: \text {else:} else:
        i)获取 cur_node \text{cur\_node} cur_node的相邻8个方格 successors \text{successors} successors
        ii)将 cur_node \text{cur\_node} cur_node加入 close list \text{close list} close list
        iii)遍历 successors \text{successors} successors,对于每个 successor \text{successor} successor
            1)若 successor \text{successor} successor在close list中,跳过本次循环(continue)
            2)若 successor \text{successor} successor不在open list中,计算 successor \text{successor} successor的g、h和f值。
                ① succesor.g=cur_node.g+cur_node \text{succesor.g=cur\_node.g+cur\_node} succesor.g=cur_node.g+cur_node successor \text{successor} successor的欧几里得距离;
                ② succesor.h \text{succesor.h} succesor.h=从 successor \text{successor} successor到终点的曼哈顿距离。
                ③ succesor.f=succesor.g+succesor.h。 \text{succesor.f=succesor.g+succesor.h。} succesor.f=succesor.g+succesor.h
                ④ 将 succesor \text{succesor} succesor加入 open list \text{open list} open list
            3)若 successor \text{successor} successor在open list中,判断从 cur_node \text{cur\_node} cur_node到successor的距离是否>succesor.g,若是则
                ① succersor.g=cur_node.g; \text{succersor.g=cur\_node.g;} succersor.g=cur_node.g;
                ② succesor.f=succesor.g + succesor.h; \text{succesor.f=succesor.g + succesor.h;} succesor.f=succesor.g + succesor.h;
                ③ node_parent[neighbor] = node \text{node\_parent[neighbor] = node} node_parent[neighbor] = node

二、Dijkstra算法和A*的区别

  1. Dijkstra算法计算源点到其他所有点的最短路径长度,A*关注点到点的最短路径(包括具体路径)。
  2. A*可以轻松地用在比如无人机航路规划、游戏地图寻路中(grid),而Dijkstra建立在较为抽象的图论层面(graph)。
  3. Dijkstra算法的实质是广度优先搜索,是一种发散式的搜索,所以空间复杂度和时间复杂度都比较高。对路径上的当前点,A*算法不但记录其到源点的代价,还计算当前点到目标点的期望代价,是一种启发式算法,也可以认为是一种深度优先的算法。
  4. 由第一点,当目标点很多时,A*算法会带入大量重复数据和复杂的估价函数,所以如果不要求获得具体路径而只比较路径长度时,Dijkstra算法会成为更好的选择。

三、A*算法应用场景

What if the search space is not a grid and is a graph ?
The same rules applies there also. The example of grid is taken for the simplicity of understanding. So we can find the shortest path between the source node and the target node in a graph using this A* Search Algorithm, just like we did for a 2D Grid.

应该使用哪种算法在图上查找路径?
1.如果要查找从所有位置起始或到所有位置的路径,使用广度优先搜索或Dijkstra算法。如果移动成本相同,使用广度优先搜索;如果移动成本不同,使用Dijkstra算法。
2.如果想找到通往一个位置或几个目标中最接近的位置的路径,使用Greedy Best First Search或A*。大多数情况下选择A*。当使用贪婪最佳优先搜索时,可以考虑使用带有“不可接受”启发式的A*。

图形搜索算法可以用于任何类型的图。图上的移动成本变成在图边上的权重。启发式距离不容易转化到不同的图中,必须为每种类型的图设计一个启发式距离。

四、启发函数

上面已经提到,启发函数h(n)会影响A算法的行为。在极端情况下,当启发函数h(n)始终为0,则将由g(n)决定节点的优先级,此时算法就退化成了Dijkstra算法。如果h(n)始终小于等于节点n到终点的代价,则A算法保证一定能够找到最短路径。但是当h(n)的值越小,算法将遍历越多的节点,也就导致算法越慢。如果h(n)完全等于节点n到终点的代价,则A算法将找到最佳路径,并且速度很快。可惜的是,并非所有场景下都能做到这一点。因为在没有达到终点之前,我们很难确切算出距离终点还有多远。
如果h(n)的值比节点n到终点的代价要大,则A
算法不能保证找到最短路径,不过此时会很快。
在另外一个极端情况下,如果h()n相较于g(n)大很多,则此时只有h(n)产生效果,这也就变成了最佳优先搜索。
由上面这些信息我们可以知道,通过调节启发函数我们可以控制算法的速度和精确度。因为在一些情况,我们可能未必需要最短路径,而是希望能够尽快找到一个路径即可。这也是A*算法比较灵活的地方。

对于网格形式的图,有以下这些启发函数可以使用:

如果图形中只允许朝上下左右四个方向移动,则可以使用曼哈顿距离(Manhattan distance)。
如果图形中允许朝八个方向移动,则可以使用对角距离。
如果图形中允许朝任何方向移动,则可以使用欧几里得距离(Euclidean distance)。

五、距离

  • 如果图形中只允许朝上下左右四个方向移动,则启发函数可以使用曼哈顿距离;
  • 如果图形中允许斜着朝邻近的节点移动,则启发函数可以使用对角距离。

六、基于A*的网格地图最短路径问题求解

实例分析

1、计算grid中从从起点(2,2)到终点(3,6)的最短路。初始化open list,close list,将起点(2,2)加入到open list中,其优先级为0(最高),这里可以看出open list可以用优先队列。
图片
2、open list不为空,遍历 open list ,查找F值最小的节点q,此时q为起点,获取对当前方格q的 8 个相邻方格(successors),[(1, 1), (1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2), (3, 3)],遍历successors,对于每一个successor,计算G ,H,和F值,F=G+H,G通过欧几里得距离计算,如(2,2)和(1,1)之间的G值为 ( 2 − 1 ) 2 + ( 2 − 1 ) 2 = 2 = 1.4 \sqrt{(2-1)^2+(2-1)^2}=\sqrt 2 = 1.4 (21)2+(21)2 =2 =1.4,计算机中浮点数运算会产生容差(tolerance),这里记为14。H值为当前successor到终点的曼哈顿距离,是一个估计距离,因为还没找到最短路,不可能直接计算出确切值。如(1,1)和(3,6)之间的H值为70,故(1,1)的F值=G+H=84。同理可计算起点的其它successors的F值。最后将8个相邻方格加入open list,第一次迭代结束,将q加入close list。

点(x1,y1)和(x2,y2)间的欧几里得距离为 ( x 1 − x 2 ) 2 + ( y 1 − y 2 ) 2 \sqrt{(x_1-x_2)^2+(y_1-y_2)^2} (x1x2)2+(y1y2)2
点(x1,y1)和(x2,y2)间的曼哈顿距离为 ∣ x 1 − x 2 ∣ + ∣ y 1 − y 2 ∣ |x_1-x_2|+|y_1-y_2| x1x2+y1y2

在这里插入图片描述
3、重复上一步,open list不为空,遍历 open list ,查找F值最小的节点q,此时q为(3,3),F=44最小,获取q=(3,3)的相邻方格,successors=[(2, 2), (2, 3), (3, 2), (4, 2), (4, 3), (4, 4)],由于(2,4)和(3,4)为障碍,所以不算相邻方格。此时,(2,2)和(3,3)在close list中,遍历相邻方格F值,需要跳过。
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

完整代码

图片
将实例分析中的网格地图映射为二维矩阵,其中1表示该网格可以通过,0表示为障碍。src=(2,2),tgt=(3,6)

          [1, 1, 1, 1, 0, 1, 1, 1],
          [1, 1, 1, 1, 0, 1, 1, 1],
          [1, 1, 1, 1, 0, 1, 1, 1],
          [1, 1, 1, 1, 1, 1, 1, 1],
          [1, 1, 1, 1, 1, 1, 1, 1],`

创建一个节点类Node,表示网格地图中的每一个网格(节点),Node类有4个属性值,分别是坐标、f值、g值、h值。将Node节点加入open list(优先队列)中,每次按优先级(f越小优先级越高)进行出队。重写equals方法和哈希方法,用坐标唯一标志一个Node。重写__lt__()方法使Node按f值比较大小。

完整代码如下:

from collections import defaultdict
from typing import Tuple
from queue import PriorityQueue

import numpy as np
import pandas as pd
import logging

logging.basicConfig(level=logging.DEBUG, format='%(message)s')

# 显示所有列
pd.set_option('display.max_columns', None)
# 显示所有行
pd.set_option('display.max_rows', None)
# 不换行打印
pd.set_option('display.width', 5000)


class Node:
    def __init__(self, coord, priority=0):
        self.coord = coord
        self.f = priority
        self.g = 0
        self.h = 0

    def __eq__(self, other):
        return self.coord == other.coord

    def __hash__(self):
        return hash(self.coord)

    def __lt__(self, other):
        return self.f < other.f

    def __getitem__(self, item):
        return self.coord

    def __repr__(self):
        return str({'坐标': self.coord, 'f': self.f})


class Grid:

    def __init__(self, ):

        # self.grid = np.asarray([
        #     [1, 0, 1, 1, 1, 1, 0, 1, 1, 1],
        #     [1, 1, 1, 0, 1, 1, 1, 0, 1, 1],
        #     [1, 1, 1, 0, 1, 1, 0, 1, 0, 1],
        #     [0, 0, 1, 0, 1, 0, 0, 0, 0, 1],
        #     [1, 1, 1, 0, 1, 1, 1, 0, 1, 0],
        #     [1, 0, 1, 1, 1, 1, 0, 1, 0, 0],
        #     [1, 0, 0, 0, 0, 1, 0, 0, 0, 1],
        #     [1, 0, 1, 1, 1, 1, 0, 1, 1, 1],
        #     [1, 1, 1, 0, 0, 0, 1, 0, 0, 1]]
        # )

        # // Driver program to test above function
        # /* Description of the Grid-
        #  1--> The cell is not blocked
        #  0--> The cell is blocked    */
        self.grid = np.asarray([
            [1, 1, 1, 1, 1, 1, 1, 1],
            [1, 1, 1, 1, 0, 1, 1, 1],
            [1, 1, 1, 1, 0, 1, 1, 1],
            [1, 1, 1, 1, 0, 1, 1, 1],
            [1, 1, 1, 1, 1, 1, 1, 1],
            [1, 1, 1, 1, 1, 1, 1, 1],
        ])
        self.nodes = []
        logging.info(self.grid)
        for x in range(self.grid.shape[0]):
            for y in range(self.grid.shape[1]):
                coord = (x, y)
                node = Node(coord)
                self.nodes.append(node)

    def is_valid(self, node):
        x, y = node
        if x < 0 or x > self.grid.shape[0] - 1 or y < 0 or y > self.grid.shape[1] - 1:
            return False
        if self.grid[x][y] == 0:
            return False
        return True

    def get_neighbors(self, node: Node):
        x, y = node.coord
        neighbors = [(x - 1, y - 1), (x - 1, y), (x - 1, y + 1),
                     (x, y - 1), (x, y + 1),
                     (x + 1, y - 1), (x + 1, y), (x + 1, y + 1)]

        valid_neighbors = [neighbor for neighbor in neighbors if self.is_valid(neighbor)]
        valid_neighbors = [Node(neighbor) for neighbor in valid_neighbors]
        return valid_neighbors

    def manhattan_distance(self, node_i, node_j):
        x1, y1 = node_i.coord
        x2, y2 = node_j.coord
        return np.abs(x1 - x2) + np.abs(y1 - y2)

    def euclidean_distance(self, node_i, node_j):
        x1, y1 = node_i.coord
        x2, y2 = node_j.coord
        return np.sqrt(np.power((x1 - x2), 2) + np.power((y1 - y2), 2))


def a_star_algorithm(grid, src, tgt):
    src = Node(src)
    tgt = Node(tgt)

    shortest_path = [tgt]

    open_list = PriorityQueue()
    closed_list = set()
    open_list.put(src)
    node_parent = {}
    while not open_list.empty():
        node = open_list.get()
        if node == tgt:  # 若为终点,
            cur = node_parent[tgt]
            while cur != src:
                shortest_path.append(cur)
                cur = node_parent[cur]
            shortest_path.append(src)
            shortest_path.reverse()
            break
        else:  # 不是终点,
            neighbors = grid.get_neighbors(node)
            closed_list.add(node)
            for neighbor in neighbors:

                if neighbor in closed_list:
                    continue
                if neighbor not in open_list.queue:
                    node_parent[neighbor] = node  # 将当前邻接点neighbor的父节点为node,k=父节点,v=子节点
                    neighbor.g = node.g + grid.euclidean_distance(node, neighbor)
                    neighbor.h = grid.manhattan_distance(neighbor, tgt)
                    neighbor.f = neighbor.g + neighbor.h

                    open_list.put(neighbor)

                if neighbor in open_list.queue:
                    if node.g + grid.euclidean_distance(node, neighbor) > neighbor.g:
                        neighbor.g = node.g
                        neighbor.f = neighbor.g + neighbor.h
                        node_parent[neighbor] = node
    # 打印地图每个点的f值
    df = pd.DataFrame(index=np.arange(0, 6), columns=np.arange(0, 8), dtype=np.float_)
    for node in node_parent.keys():
        x, y = node.coord
        df.loc[x, y] = node.f
    print(df)

    return shortest_path


if __name__ == "__main__":
    grid = Grid()
    shortest_path = a_star_algorithm(grid, (2, 2), (3, 6))
    logging.info(f'最优路径:{shortest_path}')

程序运行结果如下:

[[1 1 1 1 1 1 1 1]
 [1 1 1 1 0 1 1 1]
 [1 1 1 1 0 1 1 1]
 [1 1 1 1 0 1 1 1]
 [1 1 1 1 1 1 1 1]
 [1 1 1 1 1 1 1 1]]
最优路径:[{'坐标': (2, 2), 'f': 0}, {'坐标': (3, 3), 'f': 4.414213562373095}, {'坐标': (4, 4), 'f': 5.82842712474619}, {'坐标': (3, 5), 'f': 5.242640687119286}, {'坐标': (3, 6), 'f': 0}]
    0         1         2         3         4         5         6   7
0 NaN       NaN       NaN       NaN       NaN       NaN       NaN NaN
1 NaN  8.414214  7.000000  6.414214       NaN       NaN       NaN NaN
2 NaN  7.000000       NaN  5.000000       NaN  7.242641  6.656854 NaN
3 NaN  6.414214  5.000000  4.414214       NaN  5.242641  5.242641 NaN
4 NaN  8.414214  7.828427  6.414214  5.828427  5.828427  6.656854 NaN
5 NaN       NaN       NaN  9.242641  7.828427  7.242641       NaN NaN

Process finished with exit code 0

七、A*算法的改进思路

【路径规划】A*算法方法改进思路简析

参考:

  • A*算法详解(个人认为最详细,最通俗易懂的一个版本)

  • 路径规划之 A* 算法

  • 寻路算法——A*算法详解并附带实现代码

  • 【路径规划】A*算法方法改进思路简析

  • https://www.geeksforgeeks.org/a-search-algorithm/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1275585.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

指针(3)

如图&#xff0c;这是比较常见的冒泡排序&#xff0c;不过只能对整形数据进行排序。本篇博文主要介绍如何模拟qsort函数实现冒泡排序对任何数据的排序。 如果我们想对任何数据进行排序&#xff0c;我们可以发现&#xff0c;排序的趟数是固定的&#xff0c;我们只需要对比较大…

多线程原理和常用方法以及Thread和Runnable的区别

文章目录 &#x1f366;多线程原理&#x1f367;随机性打印&#x1f368;多线程内存图解 &#x1f369;Thread类的常用方法&#x1f36a;获取线程名称 getName()&#x1f382;设置线程名称 setName() 或者 new Thread("线程名字")&#x1f370;使当前正在执行的线程以…

BUUCTF [GXYCTF2019]SXMgdGhpcyBiYXNlPw== 1

BUUCTF:https://buuoj.cn/challenges 题目描述&#xff1a; 得到的 flag 请包上 flag{} 提交。 密文&#xff1a; 下载附件&#xff0c;解压得到flag.txt文件。 解题思路&#xff1a; 1、打开flag.txt文件&#xff0c;内容如下。 Q2V0dGUgbnVpdCwK SW50ZW5hYmxlIGluc29tbm…

<Linux>(极简关键、省时省力)《Linux操作系统原理分析之存储管理(2)》(15)

[TOC](《Linux操作系统原理分析之存储管理&#xff08;2&#xff09;》&#xff08;15&#xff09; 5 存储管理5.4 分页存储管理5.4.1 纯分页存储管理a.页&#xff08;页面&#xff09;和物理块&#xff08;帧&#xff09;b. 页面大小c. 逻辑地址结构 5.5 存储扩充技术5.5.2 交…

1_企业架构之LNMP

公司企业架构LNMP(单点服务器部署) 学习目标和内容 1、能够描述项目流程 2、能够了解PV、QPS、DAU等参数 3、能够实现服务器基本环境配置 4、能够部署配置MySQL生产环境 5、能够部署配置Nginx生产环境 6、能够部署配置PHP生产环境 7、能够理解PHP-FPM和Nginx关联关系 8、能够配…

6.1810: Operating System Engineering <Lab2 syscall: System calls>

课程链接&#xff1a;6.1810 / Fall 2023 一、本节任务 二、要点 操作系统要满足三要素&#xff1a;并发、隔离、交互&#xff08;multiplexing, isolation, and interaction&#xff09;。 宏内核&#xff08;monolithic kernel&#xff09;&#xff1a;是操作系统核心架构…

docker部署kerberos,群晖nas中nfs开启kerberos校验

背景 nas开启nfs存储共享&#xff0c;默认情况下只能给IP/24做限制, 达不到安全效果 需要增加kerberos策略校验&#xff0c;并且持久化kerberos数据&#xff0c;避免容器重启丢失数据 环境描述 宿主机系统&#xff1a;CentOS Linux release 7.9.2009 (Core) Docker版本&#xf…

CentOS7根分区扩容之一

Centos默认根分区50G&#xff0c;很快接近100%&#xff0c;如果你的系统使用了全部磁盘&#xff0c;文件系统是xfs&#xff0c;根分区和/home都是逻辑卷&#xff0c;那么在没有额外的磁盘增加情况下&#xff0c;可以从/home卷中切分一部分空间增加到根分区空间。 1.由于xfs格式…

【Android】MotionLayout实现动画

MotionLayout不断地更新&#xff0c;文章并不适用全部最近的更新内容。 文章目录 引入 ConstraintSetTransitionManager和MotionLayout有什么区别&#xff1f; 使用ConstrainSet(属性类似于ConstrainLayout) Transition属性OnClickOnSwipeKeyFrameSetKeyPositionKeyAttribute C…

220V转12V60MA红外雷达降压芯片:节能、高效、多功能的解决方案

220V转12V60MA红外雷达降压芯片&#xff1a;节能、高效、多功能的解决方案 在我国&#xff0c;红外雷达技术已广泛应用于各种小型家用电器中&#xff0c;如遥控器、智能家居等。为了满足这些设备对电源电压的需求&#xff0c;推出了一款220V转12V60MA红外雷达降压芯片&#xf…

免费通配符证书

通配符SSL证书&#xff0c;也称为泛域名证书&#xff0c;能够在一个证书中保护一个主域名及其所有下一级子域名。例如&#xff0c;如果你拥有一个名为example.com的主域名和多个子域名如mail.example.com、blog.example.com等&#xff0c;只需要一个通配符SSL证书就可以覆盖所有…

kkFileView 从源码编译最新安装包

目录 一、前言二、拉取 kkFileView 最新代码三、kkFileView 打包 一、前言 kkFileView 是一个开源的附件在线预览项目&#xff0c;可以让你的项目方便的在线预览附件&#xff0c;包括比如&#xff1a;doc、docx、pdf、xml、xls、xlsx、ppt、pptx、zip、png、jpg、txt、mp4等常…

Windows C++ VS2022 OpenVINO 实例分割 Demo

目录 效果 模型信息 项目 代码 下载 其他 Windows C VS2022 OpenVINO 实例分割 Demo 效果 模型信息 Model Properties ------------------------- date&#xff1a;2023-09-07T17:11:46.798385 description&#xff1a;Ultralytics YOLOv8n-seg model trained on coco.…

STM32 定时器TIM

单片机学习 目录 文章目录 前言 一、TIM简介 二、STM32的三种定时器 2.1基本定时器 2.1.1定时中断功能 1. 时钟源 2. 预分频器 3. 计数器 4. 自动重装寄存器 5.更新中断和更新事件 2.1.2主模式触发DAC功能 2.2 计数模式 2.2通用定时器 2.2.1 时钟源 外部时钟模式2 外部时钟模式…

人才缺口达150万!云计算凭什么这么火?

《中国互联网发展报告2022》指出&#xff0c;2021年&#xff0c;我国云计算市场规模达到3229亿元&#xff0c;增速为54.4%。未来5年内&#xff0c;我国云计算产业将面临高达近150万的人才缺口&#xff0c;预计未来市场仍将保持30%的增速。与此同时&#xff0c;随着大数据、人工…

C/C++11 语法/概念易错总结(1)

文章目录 缺省参数函数重载引用引用和指针内联宏的优缺点auto范围forNULL和nullptr 缺省参数 半缺省参数必须从右往左依次来给出&#xff0c;不能间隔着给 void Func(int a, int b 10, int c 20){cout<<"a "<<a<<endl;cout<<"b &…

SQL 算术运算符:加法、减法、乘法、除法和取模的用法

SQL Server中的存储过程 什么是存储过程&#xff1f; 存储过程是一段预先编写好的 SQL 代码&#xff0c;可以保存在数据库中以供反复使用。它允许将一系列 SQL 语句组合成一个逻辑单元&#xff0c;并为其分配一个名称&#xff0c;以便在需要时调用执行。存储过程可以接受参数…

《C++PrimerPlus》第11章 使用类

11.1 运算符重载 11.2 计算时间&#xff1a;一个运算符重载示例 运算符重载示例&#xff08;计算时间&#xff09; 头文件mytime0.h #ifndef __MYTIME0__H__ #define __MYTIME0__H__ #include <iostream> using namespace std;class Time {private:int hours;int minu…

【ECCV 2022】《Transformers as Meta-learners for Implicit Neural Representations》

文章目录 一、动机二、相关工作三、方法四、实验部分五、Does the INR Exploit Data Structures?六、结论 一、动机 \quad 与像素、体素和网格等离散数据表示相比&#xff0c;INRs不需要依赖于分辨率的二次或三次存储。它们的表示能力并不依赖于网格分辨率&#xff0c;而是依赖…

《ChatGPT实操应用大全》探索无限可能

&#x1f5e3;️探索ChatGPT&#xff0c;开启无限可能&#x1f680; 文末有免费送书福利&#xff01;&#xff01;&#xff01; ChatGPT是人类有史以来最伟大的发明。他能写作、绘画、翻译、看病、做菜、编程、数据分析、制作视频、解高等数学题…&#xff0c;他会的技能…