图的表示(一)

数学图是一组节点节点(也称为顶点或对象)通过边(也称为链接或连接或箭头或弧)连接在一起。对于任何图表,我们需要知道两件事:

  1. 中的节点集
  2. 每个节点的边集

图表形式的网格

使用方形网格时,我们需要制作一个节点列表。我们不仅限于矩形,但为简单起见,这里是 20x10 矩形的代码:

all_nodes = []
for x in range(20):
    for y in range(10):
        all_nodes.append([x, y])

边缘将是四个方向:东,北,西,南。对于任何节点,我们需要知道通过边连接到该节点的其他节点。我们称这些邻居为

def neighbors(node):
    dirs = [[1, 0], [0, 1], [-1, 0], [0, -1]]
    result = []
    for dir in dirs:
        result.append([node[0] + dir[0], node[1] + dir[1]])
    return result

如果您的游戏允许对角线移动,您将在dirs.

但是,我们只想返回我们可以移动到的节点,所以我们将添加一个检查:

def neighbors(node):
    dirs = [[1, 0], [0, 1], [-1, 0], [0, -1]]
    result = []
    for dir in dirs:
        neighbor = [node[0] + dir[0], node[1] + dir[1]]
        if neighbor in all_nodes:
            result.append(neighbor)
    return result

另一种检查方法是确保坐标在范围内。这仅适用于地图是矩形的。这是我们之前生成的 20x10 地图的代码:

def neighbors(node):
    dirs = [[1, 0], [0, 1], [-1, 0], [0, -1]]
    result = []
    for dir in dirs:
        neighbor = [node[0] + dir[0], node[1] + dir[1]]
        if 0 <= neighbor[0] < 20 and 0 <= neighbor[1] < 10:
            result.append(neighbor)
    return result

变体

我掩盖了边缘的处理方式。在图论中,有几种处理边的方法:

  • 图具有双向的边。这在游戏地图中很常见。在前面的示例中,每个无向边(例如 B↔C)被列出两次,一次是 B→C,一次是 C→B。
  • 图的边可以朝一个方向,但不能朝另一个方向。单向门、跳下窗台和传送门可能是游戏中的单向边缘。一个图可以有边 B→C 而没有边 C→B。
  • 多重图相同节点之间可以有多个边。能够游泳过河或乘木筏渡过同一条河是游戏中的一个例子。节点 B 可以有不止一条边 B→C 通向节点 C。

此外,您可以使用额外信息来注释节点和边。寻路算法中经常出现的一种注释是边缘权重。加权图允许在每条边上使用数字权重在加权无向图中,我们可以将铺砌的道路标记为权重 1,将曲折的森林路径标记为权重 4,以使探路者偏爱道路。在加权有向图中,我们可能会将下坡边 B→C 标记为权重 2,并将上坡边 C→B 标记为权重 5,以便更容易下坡。

障碍

我们如何以图形的形式表示网格的障碍?一般的策略有以下三种:

  1. 删除节点如果障碍物占据方格,您可以从图中删除这些节点(all_nodes)。您还需要删除相应的边缘,如果您使用“ if neighbor in all_nodes”来测试是否添加了边缘,则会自动发生这种情况,但如果您正在测试 x/y 是否在范围内,则不会。
  2. 去除边缘neighbors()如果障碍物占据了正方形之间的边界,您可以通过在函数中添加额外的检查来从图中删除这些边。如果障碍物占据了方格,您可以移除通向这些方格的边缘。
  3. 无限重边如果障碍物占据了方块之间的边界,您可以将这些边缘标记为 Infinity 作为权重。如果障碍物占据方格,您可以将通向障碍物的边缘标记为权重为 Infinity。在您的图形搜索功能中,您必须在访问以 Infinity 作为成本的节点之前退出。

如果您想在构建图表后更改障碍物,更改权重可能会更容易。

更多的

为什么我在寻路教程中一直使用网格?因为它们易于使用,并且在我开始制作游戏时非常常见。他们使用基于图形的寻路算法。我也计划构建一些非网格寻路图的演示,但网格更容易解释。

我没有涵盖边缘的替代表示。我通常使用每个节点的边列表,但您也可以使用全局边集,或跟踪哪些节点对之间有边的矩阵表示。阅读更多关于维基百科

我也没有涵盖游戏中其他用途的图表。虽然图形搜索与地图上的寻路很明显匹配,但您也可以将其用于许多其他问题。您可以在地牢探索游戏中表示房间(节点)和走廊(边缘)。您可以在社交游戏中表示玩家(节点)和他们的友谊(边缘)。您可以将可能的行为表示为图表,然后搜索它以决定要执行的行为。您可以将所有可能的棋盘配置表示为节点,将游戏移动表示为边,然后搜索其中的一部分以决定如何移动。您可以将NPC 的状态表示为节点和作为边缘的动作。您可以在 NPC 对话数据库中表示对话主题。您可以在地图生成器中使用图表来生成河流和道路您可以将游戏的经济表示为图表,以小麦和面包为节点,以烘焙为边。3D 多边形网格也可以被视为图形。图是一种简洁的抽象。如果您可以使您的数据看起来像一个图形,您可以重用各种图形算法。

Copyright © 2022 Red Blob Games

转载于https://www.redblobgames.com/pathfinding/grids/graphs.html

posted on 2022-03-17 19:52  -G  阅读(165)  评论(0)    收藏  举报

导航