【问题标题】:Is Jump Point Search strictly better than A*?Jump Point Search 是否严格优于 A*?
【发布时间】:2019-03-20 12:26:20
【问题描述】:

根据许多相关信息,当满足所需条件(统一成本网格等)时,Jump Point Search 似乎严格优于 A*

但是经过一些实际测试,我发现 Jump Point Search 的搜索时间与 A* 几乎相同(甚至更糟......),我对此不太确定......(实现问题?随机网格?)

搜索实现来自here,测试代码如下:

int profileCount = 256;
long elapsedJumpPoint = 0;
long elapsedAStar = 0;

for (int i = 0; i < profileCount; ++i)
{
    // random set obstacles here
    RandomizeGrid(searchGrid);

    {
        searchGrid.Reset();

        var stopWatch = Stopwatch.StartNew();
        jumpParam.DiagonalMovement = (DiagonalMovement)cbbJumpType.SelectedIndex;
        jumpParam.CurIterationType = cbUseRecursive.Checked ? IterationType.RECURSIVE : IterationType.LOOP;
        jumpParam.Reset(startPos, endPos);
        var path = JumpPointFinder.FindPath(jumpParam);
        elapsedJumpPoint += stopWatch.ElapsedMilliseconds;
    }

    {
        searchGrid.Reset();

        var stopWatch = Stopwatch.StartNew();
        starParam.DiagonalMovement = (DiagonalMovement)cbbJumpType.SelectedIndex;
        starParam.SetHeuristic(HeuristicMode.EUCLIDEAN);
        starParam.Reset(startPos, endPos);
        var path = AStarFinder.FindPath(starParam);
        elapsedAStar += stopWatch.ElapsedMilliseconds;
    }
}

MessageBox.Show(string.Format("JP time : {0}ms\nA* time : {1}ms", elapsedJumpPoint / (float)profileCount, elapsedAStar / (float)profileCount));

RandomizeGrid 代码在这里:

void RandomizeGrid(BaseGrid searchGrid, float randomPercent = 0.2f)
{
    if (searchGrid != null)
    {
        var width = searchGrid.width;
        var height = searchGrid.height;

        for (int i = 0; i < width; ++i)
        {
            for (int j = 0; j < height; ++j)
            {
                searchGrid.SetWalkableAt(new GridPos(i, j), true);
            }
        }

        var random = new Random();
        for (int i = 0; i < width * height * randomPercent; ++i)
        {
            var randWidth = random.Next(0, width);
            var randHeight = random.Next(0, height);
            searchGrid.SetWalkableAt(new GridPos(randWidth, randHeight), false);
        }
    }
}

下面还列出了一些测试结果:

|随机百分比 |太平绅士 |一个* |

| 0.05 | ~8.7ms | ~8.2ms |

| 0.1 | ~11ms | ~14.3 毫秒 |

| 0.2 | ~15ms | ~13.7 毫秒 |

| 0.5 | ~20.5ms | ~22ms |

【问题讨论】:

  • 您能否更具体地说明研究表明它“严格意义上更好”?这是否意味着跑步的时间?你能分享你的跑步结果吗?均值和方差,所以我可以检查这是否具有统计意义?您确定您的设置符合规定的标准吗?您是否比较过其他实现?性能计数器会给出不同的结果吗?这在另一个 stackexchange 网站上是否更好,例如数据科学?
  • RandomizeGrid 的随机性如何?当然,如果因为到处都是障碍物而找不到跳跃点,JPS 就无法使用它的主要功能。
  • 抱歉代码缺失,我添加了 RandomizeGrid

标签: search a-star


【解决方案1】:

跳转点搜索从 A* 显着减少了优先级队列的大小,但查找每个单独的跳转点本身所花费的时间要多得多。但是,它节省了大量时间,因为它不需要存储和维护可以从 A* 生成的大型优先级队列,在这些队列中保持排序的推送操作可能很昂贵。较小的队列也将有助于缓存行。但是 Jump Point Search 最终会扩展比 A* 更多的节点,即使它们没有被添加到打开列表/优先级队列中。

要回答关于它在运行时方面是否更好的问题,它实际上取决于算法的实现以及给定的映射。内存使用通常会更好,因为打开列表的大小要小得多。如果网格像迷宫或有很多障碍物,则速度通常会降低,因为它最终会增加很多跳跃点,这可能会很昂贵。

我针对 A* (https://github.com/YashTrikannad/mpl/blob/master/include/mpl/jps.h) 对跳转点搜索的实现进行了基准测试,在 1000x1000 2d 网格上,跳转点搜索的运行速度平均快了大约 10 倍,测试了 1000 次带有 4-5 个大型障碍物(不是迷宫)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-02-06
    • 1970-01-01
    相关资源
    最近更新 更多