如何在大空间尺度上加速A*算法?

2024-05-28

From http://ccl.northwestern.edu/netlogo/models/community/Astardemo http://ccl.northwestern.edu/netlogo/models/community/Astardemo1,我通过使用网络中的节点来定义最低成本路径来编写 A* 算法。该代码似乎可以工作,但当我在大空间尺度上使用它时,速度太慢了。我的景观范围为 1000 个补丁 x 1000 个补丁,其中 1 个补丁 = 1 像素。即使我将其减少到 400 个补丁 x 400 个补丁,其中 1 个补丁 = 1 个像素,它仍然太慢(我无法将我的景观修改为低于 400 个补丁 x 400 个补丁)。这是代码:

to find-path [ source-node destination-node] 

let search-done? false
let search-path []
let current-node 0
set list-open []
set list-closed []  
let list-links-with-nodes-in-list-closed []
let list-links []

set list-open lput source-node list-open
while [ search-done? != true]
[    
ifelse length list-open != 0
[
  set list-open sort-by [[f] of ?1 < [f] of ?2] list-open 
  set current-node item 0 list-open 
  set list-open remove-item 0 list-open 
  set list-closed lput current-node list-closed
  ask current-node
  [  
    if parent-node != 0[
    set list-links-with-nodes-in-list-closed lput link-with parent-node list-links-with-nodes-in-list-closed 
    ]
    ifelse any? (nodes-on neighbors4) with [ (xcor = [ xcor ] of destination-node) and (ycor = [ycor] of destination-node)]
    [
      set search-done? true 
    ]
    [        
      ask (nodes-on neighbors4) with [ (not member? self list-closed) and (self != parent-node) ]  
      [  
        if not member? self list-open and self != source-node and self != destination-node
        [
          set list-open lput self list-open
          set parent-node current-node
          set list-links sentence (list-links-with-nodes-in-list-closed) (link-with parent-node)
          set g sum (map [ [link-cost] of ? ] list-links)
          set h distance destination-node 
          set f (g + h)
        ]
      ]
    ]
  ]
]

[
  user-message( "A path from the source to the destination does not exist." )
  report []
 ]
]
set search-path lput current-node search-path
let temp first search-path
while [ temp != source-node ]
[
 ask temp
[
  set color red
]
set search-path lput [parent-node] of temp search-path 
set temp [parent-node] of temp 
]
set search-path fput destination-node search-path
set search-path reverse search-path  
print search-path
end

不幸的是,我不知道如何加速这段代码。是否有解决方案可以在大空间尺度上快速计算最低成本路径?

非常感谢您的帮助。


很好奇,所以我测试了我的 A*,这是我的结果

迷宫 1280 x 800 x 32 位像素

  • 如您所见,花费了约 23 毫秒
  • 无多线程(AMD 3.2GHz)
  • C++ 32 位应用程序(如果您愿意,可以使用 BDS2006 Turbo C++ 或 Borland C++ builder 2006)
  • 我发现的最慢路径约为 44 毫秒(几乎填满整个地图)

我认为这已经足够快了...

这是我的 A* 类的来源:

//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
const DWORD A_star_space=0xFFFFFFFF;
const DWORD A_star_wall =0xFFFFFFFE;
//---------------------------------------------------------------------------
class A_star
    {
public:
    // variables
    DWORD **map;        // map[ys][xs]
    int xs,ys;          // map esolution   xs*ys<0xFFFFFFFE !!!
    int *px,*py,ps;     // output points px[ps],py[ps] after compute()

    // internals
    A_star();
    ~A_star();
    void _freemap();                                    // release map memory
    void _freepnt();                                    // release px,py memory

    // inteface
    void resize(int _xs,int _ys);                       // realloc map to new resolution
    void set(Graphics::TBitmap *bmp,DWORD col_wall);    // copy bitmap to map
    void get(Graphics::TBitmap *bmp);                   // draw map to bitmap for debuging
    void compute(int x0,int y0,int x1,int y1);          // compute path from x0,y0 to x1,y1 output to px,py
    };
//---------------------------------------------------------------------------
     A_star::A_star()   { map=NULL; xs=0; ys=0; px=NULL; py=NULL; ps=0; }
     A_star::~A_star()  { _freemap(); _freepnt(); }
void A_star::_freemap() { if (map) delete[] map; map=NULL; xs=0; ys=0; }
void A_star::_freepnt() { if (px) delete[] px; px=NULL; if (py) delete[] py; py=NULL; ps=0; }
//---------------------------------------------------------------------------
void A_star::resize(int _xs,int _ys)
    {
    if ((xs==_xs)&&(ys==_ys)) return;
    _freemap();
    xs=_xs; ys=_ys;
    map=new DWORD*[ys];
    for (int y=0;y<ys;y++)
     map[y]=new DWORD[xs];
    }
//---------------------------------------------------------------------------
void A_star::set(Graphics::TBitmap *bmp,DWORD col_wall)
    {
    int x,y;
    DWORD *p,c;
    resize(bmp->Width,bmp->Height);
    for (y=0;y<ys;y++)
     for (p=(DWORD*)bmp->ScanLine[y],x=0;x<xs;x++)
        {
        c=A_star_space;
        if (p[x]==col_wall) c=A_star_wall;
        map[y][x]=c;
        }
    }
//---------------------------------------------------------------------------
void A_star::get(Graphics::TBitmap *bmp)
    {
    int x,y;
    DWORD *p,c;
    bmp->SetSize(xs,ys);
    for (y=0;y<ys;y++)
     for (p=(DWORD*)bmp->ScanLine[y],x=0;x<xs;x++)
        {
        c=map[y][x];
             if (c==A_star_wall ) c=0x00000000;
        else if (c==A_star_space) c=0x00FFFFFF;
        else                      c=((c>>1)&0x7F)+0x00404040;
        p[x]=c;
        }
    }
//---------------------------------------------------------------------------
void A_star::compute(int x0,int y0,int x1,int y1)
    {
    int x,y,xmin,xmax,ymin,ymax,xx,yy;
    DWORD i,j,e;
    // [clear previous paths]
    for (y=0;y<ys;y++)
     for (x=0;x<xs;x++)
      if (map[y][x]!=A_star_wall)
       map[y][x]=A_star_space;
/*
    // [A* no-optimizatims]
    xmin=x0; xmax=x0; ymin=y0; ymax=y0;
    if (map[y0][x0]==A_star_space)
     for (i=0,j=1,e=1,map[y0][x0]=i;(e)&&(map[y1][x1]==A_star_space);i++,j++)
      for (e=0,y=ymin;y<=ymax;y++)
       for (   x=xmin;x<=xmax;x++)
        if (map[y][x]==i)
        {
        yy=y-1; xx=x; if ((yy>=0)&&(map[yy][xx]==A_star_space)){ map[yy][xx]=j; e=1; if (ymin>yy) ymin=yy; }
        yy=y+1; xx=x; if ((yy<ys)&&(map[yy][xx]==A_star_space)){ map[yy][xx]=j; e=1; if (ymax<yy) ymax=yy; }
        yy=y; xx=x-1; if ((xx>=0)&&(map[yy][xx]==A_star_space)){ map[yy][xx]=j; e=1; if (xmin>xx) xmin=xx; }
        yy=y; xx=x+1; if ((xx<xs)&&(map[yy][xx]==A_star_space)){ map[yy][xx]=j; e=1; if (xmax<xx) xmax=xx; }
        }
*/
    // [A* changed points list]
    // init space for 2 points list
    _freepnt();
    int i0=0,i1=xs*ys,n0=0,n1=0,ii;
    px=new int[i1*2];
    py=new int[i1*2];
    // if start is not on space then stop
    if (map[y0][x0]==A_star_space)
        {
        // init start position to first point list
        px[i0+n0]=x0; py[i0+n0]=y0; n0++; map[y0][x0]=0;
        // search until hit the destination (swap point lists after each iteration and clear the second one)
        for (j=1,e=1;(e)&&(map[y1][x1]==A_star_space);j++,ii=i0,i0=i1,i1=ii,n0=n1,n1=0)
         // test neibours of all points in first list and add valid new points to second one
         for (e=0,ii=i0;ii<i0+n0;ii++)
            {
            x=px[ii]; y=py[ii];
            yy=y-1; xx=x; if ((yy>=0)&&(map[yy][xx]==A_star_space)){ map[yy][xx]=j; e=1; px[i1+n1]=xx; py[i1+n1]=yy; n1++; map[yy][xx]=j; }
            yy=y+1; xx=x; if ((yy<ys)&&(map[yy][xx]==A_star_space)){ map[yy][xx]=j; e=1; px[i1+n1]=xx; py[i1+n1]=yy; n1++; map[yy][xx]=j; }
            yy=y; xx=x-1; if ((xx>=0)&&(map[yy][xx]==A_star_space)){ map[yy][xx]=j; e=1; px[i1+n1]=xx; py[i1+n1]=yy; n1++; map[yy][xx]=j; }
            yy=y; xx=x+1; if ((xx<xs)&&(map[yy][xx]==A_star_space)){ map[yy][xx]=j; e=1; px[i1+n1]=xx; py[i1+n1]=yy; n1++; map[yy][xx]=j; }
            }
        }
    // [reconstruct path]
    _freepnt();
    if (map[y1][x1]==A_star_space) return;
    if (map[y1][x1]==A_star_wall) return;
    ps=map[y1][x1]+1;
    px=new int[ps];
    py=new int[ps];
    for (i=0;i<ps;i++) { px[i]=x0; py[i]=y0; }
    for (x=x1,y=y1,i=ps-1,j=i-1;i>=0;i--,j--)
        {
        px[i]=x;
        py[i]=y;
        if ((y>   0)&&(map[y-1][x]==j)) { y--; continue; }
        if ((y<ys-1)&&(map[y+1][x]==j)) { y++; continue; }
        if ((x>   1)&&(map[y][x-1]==j)) { x--; continue; }
        if ((x<xs-0)&&(map[y][x+1]==j)) { x++; continue; }
        break;
        }
    }
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------
//---------------------------------------------------------------------------

我知道代码有点太多,但它已经完成了。重要的是成员函数compute所以搜索[A* changed points list]。未优化的A*(rem-ed) 大约慢 100 倍。

代码使用 Borland VCL 中的位图,因此如果您没有它,请忽略函数get,set并将它们重写为您的输入/输出 gfx 样式。他们只是加载map from bitmap并绘制计算出的map回到bitmap

Usage:

// init
A_star map;
Graphics::TBitmap *maze=new Graphics::TBitmap;
maze->LoadFromFile("maze.bmp");
maze->HandleType=bmDIB;
maze->PixelFormat=pf32bit;
map.set(maze,0); // walls are 0x00000000 (black)
// this can be called repetitive without another init
map.compute(x0,y0,x1,y1); // map.px[map.ps],map.py[map.ps] holds the path
map.get(maze,0); // this is just for drawing the result map back to bitmap for viewing

有关 A* 的更多信息,请参阅A星中的回溯 https://stackoverflow.com/a/28317199/2521214

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在大空间尺度上加速A*算法? 的相关文章

  • 解决复发问题

    我被给予F 0 X and F i A F i 1 2 B F i 1 C 1000000 for 1 i N 现在给出N A B C and X 如何找到所有N元素有效吗 我需要将这 N 个元素分成 2 个集合 其中最大的元素在第一个集合
  • 如何使我的网站获得更好的性能

    嘿那里 我在 Windows 2008 服务器上运行 IIS7 在高峰时段 我们有以下行为 CPU负载接近空闲 请求排队 使用资源监视器进行监控 执行时间超过10秒 1 4 请参阅以前的版本和编辑 5 异步做事 按照建议 我创建了一个简单的
  • 将平面表解析为树的最有效/优雅的方法是什么?

    假设您有一个存储有序树层次结构的平面表 Id Name ParentId Order 1 Node 1 0 10 2 Node 1 1 1 10 3 Node 2 0 20 4 Node 1 1 1 2 10 5 Node 2 1 3 10
  • sprintf 与 String.Format 的性能[重复]

    这个问题在这里已经有答案了 我正在比较 sprintf 用法的性能 并对我所看到的感到有点困扰 我测试了以下 4 个方法 将 ClassWithToString 的实例传递给每个方法 PrintInt 除外 它接收实际的整数值 type C
  • 递归分层父子

    我有一个来自数据库的项目集合 该数据库具有parentid值或空 这是我的班级设计 public class Item public int id get set public string Name get set public int
  • JavaScript 中多个数组的笛卡尔积

    如何在 JavaScript 中实现多个数组的笛卡尔积 举个例子 cartesian 1 2 10 20 100 200 300 应该返回 1 10 100 1 10 200 1 10 300 2 10 100 2 10 200 2020
  • 如何测量 Storm 拓扑中的延迟和吞吐量

    我正在通过示例学习 StormExclamationTopology https github com nathanmarz storm starter blob master src jvm storm starter Exclamati
  • 不同大小组的高效递归随机抽样

    这个问题是我之前关于递归随机抽样问题的后续问题高效的递归随机采样 https stackoverflow com questions 69824065 efficient recursive random sampling 当组大小相同或每
  • 如何使用NetLogo 6.2公平分配海龟?

    我有一个问题 我在这里寻求帮助 如何使用 NetLogo 6 2 为每种配置文件类型均匀分配海龟 https stackoverflow com questions 70748349 how to make an equal distrib
  • 转置矩阵存储在一维数组中,无需使用额外的内存[重复]

    这个问题在这里已经有答案了 可能的重复 矩阵的就地转置 https stackoverflow com questions 9227747 in place transposition of a matrix 最近参加了技术笔试 通过以下问
  • 预编译 ASP.NET 网站上的“JIT 时间百分比”高且波动

    拥有 150 个 dll 的 ASP NET 网站预编译的 可更新 导致 的可能原因是什么JIT 时间百分比 这通常相当高 gt 60 并且波动的应用程序预热后很长一段时间 访问所有功能 并且没有 应用程序重新启动或文件更改可能会生成新的程
  • 从高斯分布中采样随机值的最快方法是什么?

    The Box Muller 变换 http en wikipedia org wiki Box E2 80 93Muller transform 是一种从高斯分布中采样随机值的优雅且性能合理的方法 我正在寻找一种用 C 编写 清晰的更快方
  • 基准测试:PostgreSQL 上的 bigint 与 int

    我想提高数据库性能 在一个项目中 所有表都来自int to bigint 我认为这不仅在存储方面是一个糟糕的选择 因为int需要4 bytes and bigint需要8 bytes 但也与性能有关 所以我创建了一个小表1000万条目 其中
  • 如何找到权重为 1、0、-1 且成本精确为 0 的多维路径

    我得到了一个有向图 其中有 n 个节点和边 向量的权重 每个向量的长度为 m 为数字 1 0 1 我想找到从一个节点到另一个节点 我们可以多次访问节点 的任何路径 或者说这样的路径不存在 使其权重之和等于仅由零组成的向量 我正在考虑暴力回溯
  • 如何提取世界上每只海龟走过的路径并将其保存在 .csv 文件中?

    我仍在尝试提取世界上每只海龟所走路径的坐标 例如 我想知道海龟 0 所采取的路径是 patch 00 patch 0 5 patch 0 2 和 patch 1 4 并将此信息保存在 csv 文件中 这样 我想提取世界上所有海龟所走路径的坐
  • 动态_cast的性能?

    在阅读问题之前 这个问题不是关于它有多大用处dynamic cast 这只是关于它的性能 我最近开发了一个设计 其中dynamic cast被大量使用 与同事讨论时 几乎每个人都这么说dynamic cast不应该使用 因为它的性能很差 这
  • 排序数组最快的搜索方法是什么?

    正在回答另一个问题 https stackoverflow com questions 4752028 whats wrong with this interpolation search implementation 4752042 47
  • Django:将博客条目查看次数增加一。这有效率吗?

    我的索引视图中有以下代码 latest entry list Entry objects filter is published True order by date published 10 for entry in latest ent
  • 如何实现具有LinkedHashMap类似功能的ConcurrentHashMap?

    我用过LinkedHashMap with accessOrdertrue 并同时允许最多 500 个条目作为数据的 LRU 缓存 但由于可扩展性问题 我想转向一些线程安全的替代方案 ConcurrentHashMap在这方面似乎不错 但缺
  • 从邻接表计算图的入度

    我遇到了这个问题 其中需要根据邻接列表表示来计算图的每个节点的入度 for each u for each Adj i where i u if i u E in degree u 1 现在根据我的说法 它的时间复杂度应该是O V E V

随机推荐

  • 如何使用 IdTCPClient 等待来自服务器的字符串?

    我的 IdTelnet indy 10 1 有问题 我无法以 Unicode 模式从服务器读取数据 现在我想用 IdTCPClient 编写 telnet 终端 服务器有时发送一行 有时发送越来越多的行 但发送之间没有固定的时间 现在我的问
  • C++ 实现友元/内联函数

    我似乎找不到这个新手问题的答案 如果我有课 头文件 h Class X public friend bool operator const X const X inline size type rows const ETC 当我去实现X的
  • 为实体框架中的实体创建基类

    我想创建一个对我的所有实体都通用的基类 该类将具有 Save Delete GetByID 等方法以及其他一些基本功能和属性 我在 Linq to SQL 方面有更多经验 希望能在 EF 中获得一些类似的好示例 谢谢 像这样 public
  • PHP 使用今天的日期生成一个随机数

    我正在尝试为内容块 在网页上 分配一个随机生成的数字 该数字基于今天的日期 无论是什么 和固定数字 由于某种原因 输出的数字种类存在巨大差异 例如 当我在本地测试我的代码时 生成的数字对我来说足够好 正数 但在实际的实时服务器上时 它们通常
  • 之后的脚本会阻止 DOM 加载

    考虑以下代码 div class box div 令我惊讶的是 DOM 延迟了十秒的加载 10秒后出
  • 在 C 中使用 pow 时,CMake 可以检测是否需要链接到 libm 吗?

    对于某些编译器 using powC 程序中的某些其他函数需要链接到m library https stackoverflow com q 8671366 1959975 但是 某些编译器不需要这样做 并且在链接到m图书馆 C 也存在几乎相
  • 检测 404 而不捕获异常

    简单功能 检查网络服务器是否返回非 200 HTTP 状态 Private Function RemoteFileOk ByVal Url As String As Boolean Dim req As HttpWebRequest Try
  • Android 偏好设置中的“是”或“否”确认[重复]

    这个问题在这里已经有答案了 我需要在 设置 中实现 重置 选项 单击该设置后 将打开一个简单的对话框 要求确认 我看过了DialogPreference但我似乎无法在任何地方找到好的解决方案或教程 有人可以帮我吗 我是初学者 想法甚至代码都
  • 如何在张量流中使用索引数组?

    如果给定一个矩阵a有形状 5 3 和索引数组b有形状 5 我们很容易得到对应的向量c通过 c a np arange 5 b 但是 我不能用张量流做同样的事情 a tf placeholder tf float32 shape 5 3 b
  • QGraphicsSimpleTextItem“无效使用不完整类型”

    我的代码如下 指针部件 h QGraphicsSimpleTextItem text 指针控件 cpp void PointerWidget placeNumbers float spacing int currentTickNumber
  • 帮助理解 JQuery 属性等于选择器

    我想找一个 td class one two three four 在一个 div 这两个选择器的工作原理 myid td role foo myid two 但这个却没有 为什么呢 myid two td role foo 因为选择器字符
  • 如何使用 WP REST API 插件获取 YOAST SEO 插件数据?特别是 wpseo_head 挂钩内容

    我正在使用 WP REST API 来获取所有发布数据 嗯 它工作得很好 但任何网站最关心的是 SEO 部分 我正在使用 YOAST SEO 插件 我想获取它在 HTML 的 Head 部分中创建的所有元标记 仅供参考 我使用 Wordpr
  • log4net 每分钟创建新日志

    log4net在我的项目中每分钟都会创建新的日志文件 我希望应用程序的每个实例只有一个文件 但每个运行的实例都应该创建新的日志文件 这是来自我的app config file
  • 将 Datastax Enterprise Cassandra 迁移到 Apache Cassandra

    我们目前使用的是 DSE 4 8 和 5 12 我们想迁移到 apache cassandra 因为我们不使用 Spark 或搜索 所以想节省一些钱迁移到 apache 这可以在不停机的情况下实现吗 我看到 sstableloader 以其
  • 我应该始终在 Silverlight 游戏中使用游戏循环吗?

    我读过有关在 silverlight 中使用 CompositionTarget Rendering Timer 进行主要游戏循环的内容 用于命中测试和一般游戏逻辑 就像任何语言一样 这就是说 我想知道最好是一次在这个 x 像素内移动对象
  • .net core 1.1 中嵌入的 power bi

    目前 我正在尝试在 Visual Studio 2017 中为我的 net core 1 1 项目导入 powerbi 包 但是 我收到以下错误 Install Package Package Microsoft PowerBI Core
  • AngularJS 中的重定向状态

    这是状态配置 angular module grabhutApp config function stateProvider urlRouterProvider stateProvider ACCOUNT state account abs
  • 如何为字符串生成 GUID?

    我在为字符串生成 GUID 时遇到问题 例如 Guid g New Guid Mehar 如何计算 GUID Mehar 我遇到了例外 这个线程很旧 但这就是我们解决这个问题的方法 由于 NET 框架中的 Guid 是任意 16 字节或 1
  • 在哪里以及如何安装 twitter 的 Python API?

    我访问了 Twitter 的 API 它把我重定向到了谷歌代码 但网站不在那里 有其他替代的 Twitter API 以及教程吗 谢谢 尝试推推 http code google com p tweepy http code google
  • 如何在大空间尺度上加速A*算法?

    From http ccl northwestern edu netlogo models community Astardemo http ccl northwestern edu netlogo models community Ast