A*——AcWing 179. 八数码

A*

定义

A* 算法是一种在图形或地图中寻找最短路径的启发式搜索算法。它通过综合考虑起始节点到当前节点的实际代价和当前节点到目标节点的预估代价,来决定下一步的搜索方向。

运用情况

  • 路径规划:如在地图导航中为车辆、行人规划最优路线。
  • 游戏开发:例如在策略游戏中为角色寻找到达目标的最短路径。
  • 机器人导航:帮助机器人在复杂环境中找到高效的移动路径。

注意事项

  • 启发函数的设计:启发函数的准确性对算法的效率和结果质量有很大影响。如果启发函数过于乐观或悲观,可能导致算法找不到最优解或效率低下。
  • 内存使用:在处理大规模的地图或图形时,A* 算法可能需要大量的内存来存储已访问和待访问的节点信息。
  • 优化策略:需要根据具体问题选择合适的优化策略,如双向搜索、限制搜索区域等。

解题思路

  1. 初始化:将起始节点放入开放列表,设置其代价。
  2. 循环:
    • 从开放列表中选择代价最小的节点作为当前节点。
    • 将当前节点移出开放列表,放入关闭列表。
    • 对当前节点的相邻节点进行处理:
      • 如果相邻节点在关闭列表中,忽略。
      • 如果不在开放列表中,计算其代价并放入开放列表。
      • 如果在开放列表中,更新其代价,如果新代价更小则更新其父节点。
  3. 直到目标节点被放入关闭列表,或者开放列表为空(未找到路径)。

例如,在地图导航中,起始节点是你的当前位置,目标节点是你的目的地。每个节点代表地图上的一个位置,节点之间的连接表示可能的路径。通过不断评估每个可能的下一步路径的代价,A* 算法能够快速找到从起始点到目标点的最短路径。

A 算法的优缺点*:

优点:

  1. 高效性:通常能够在合理的时间内找到较优的解,特别是在地图规模不是特别巨大的情况下。
  2. 最优性保证:在启发函数估计准确的前提下,能够找到最优解。
  3. 灵活性:可以应用于各种不同类型的图和问题领域,只要能够定义合适的代价函数和启发函数。
  4. 易于理解和实现:其基本思想相对直观,实现起来并不复杂。

例如,在城市交通导航中,A* 算法能够快速为司机规划出一条相对较短且高效的行驶路线,节省时间和燃油。

缺点:

  1. 启发函数的依赖:启发函数的质量对算法性能影响极大,如果启发函数设计不好,可能导致算法效率低下或找不到最优解。
  2. 内存消耗:在处理大规模的问题时,可能需要大量的内存来存储节点信息和搜索过程中的数据。
  3. 计算开销:计算每个节点的代价和启发值需要一定的计算资源。
  4. 对复杂环境的适应性有限:在某些极端复杂或动态变化的环境中,可能表现不佳。

比如,在一个实时变化的物流配送网络中,由于路况等因素不断变化,A* 算法可能难以快速适应并重新规划最优路径。

常用的路径规划算法

Dijkstra 算法
这是一种用于求解图中单个源点到其他所有顶点的最短路径的算法。它会遍历所有可能的路径,逐步更新节点的最短距离,直到找到所有节点的最短路径。优点是能保证找到最短路径,缺点是计算量较大,效率相对较低。

例如,在物流配送中心规划送货路线时,如果只关注从配送中心到各个目的地的最短距离,Dijkstra 算法就可以适用。

Floyd-Warshall 算法
用于计算图中所有顶点对之间的最短路径。通过动态规划的思想,逐步更新任意两点之间的最短距离。该算法的优点是可以一次性得到所有点对之间的最短路径,缺点是时间和空间复杂度较高。

比如,在分析多个城市之间的最优交通连接时,Floyd-Warshall 算法可以提供全面的路径信息。

蚁群算法
模拟蚂蚁在寻找食物过程中的行为来寻找最优路径。蚂蚁会根据路径上的信息素浓度选择路径,同时在经过的路径上留下信息素,使得后续的蚂蚁更倾向于选择较优的路径。优点是具有较强的全局搜索能力和自适应性,缺点是计算时间可能较长,参数设置较复杂。

在大规模的网络路由规划中,蚁群算法可以发现复杂网络中的优质路径。

粒子群优化算法
通过模拟鸟群觅食的行为来寻找最优解。粒子在解空间中移动,根据自身和群体的历史最优位置来更新自己的位置。优点是实现简单,收敛速度较快,缺点是容易陷入局部最优。

例如,在无人机的自主飞行路径规划中,可以使用粒子群优化算法来找到合适的路线。

遗传算法
基于生物进化的思想,通过选择、交叉和变异等操作来优化解。优点是能够处理复杂的优化问题,具有较好的全局搜索能力,缺点是计算量较大,编码和解码过程可能较复杂。

比如,在机器人在复杂环境中的路径规划问题中,遗传算法可以发挥作用。

AcWing 179. 八数码

题目描述

AcWing 179. 八数码 - AcWing

运行代码

#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <unordered_map>
using namespace std;
typedef pair<int, string> PIS;
int f(string state)
{
    int res = 0;
    for(int i = 0; i < state.size(); i ++ )
        if(state[i] != 'x')
        {
            int t = state[i] - '1';
            res += abs(i / 3 - t / 3) + abs(i % 3 - t % 3);
        }
    return res;
}
string bfs(string start)
{
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
    char op[4] = {'u', 'r', 'd', 'l'};
    string end = "12345678x";
    unordered_map<string, int> dist;
    unordered_map<string, pair<string, char>> prev;
    priority_queue<PIS, vector<PIS>, greater<PIS>> heap;
    heap.push({f(start), start});
    dist[start] = 0;
    while(heap.size())
    {
        auto t = heap.top();
        heap.pop();
        string state = t.second;
        if(state == end) break;
        int step = dist[state];
        int x, y;
        for(int i = 0; i < state.size(); i ++ )
            if(state[i] == 'x')
            {
                x = i / 3, y = i % 3;
                break;
            }
        string scource = state;
        for(int i = 0; i < 4; i ++ )
        {
            int a = x + dx[i], b = y + dy[i];
            if(a >= 0 && a <= 2 && b >= 0 && b <= 2)
            {
                swap(state[x * 3 + y], state[a * 3 + b]);
                if(!dist.count(state) || dist[state] > step + 1)
                {
                    dist[state] = step + 1;
                    prev[state] = {scource, op[i]};
                    heap.push({dist[state] + f(state), state});
                }
                swap(state[x * 3 + y], state[a * 3 + b]);
            }
            
        }
    }
    string res;
    while(end != start)
    {
        res += prev[end].second;
        end = prev[end].first;
    }
    reverse(res.begin(), res.end());
    return res;
}
int main()
{
    string g, c, seq;
    while(cin >> c)
    {
        g += c;
        if(c != "x") seq += c;
    }
    int res = 0;
    for(int i = 0; i < seq.size(); i ++ )
        for(int j = i + 1; j < seq.size(); j ++ )
            if(seq[i] > seq[j]) res ++ ;
    if(res & 1) puts("unsolvable");
    else cout << bfs(g) << endl;
    return 0;
}

代码思路

  1. f 函数用于计算一个状态与目标状态的曼哈顿距离估计值,作为启发函数。
  2. bfs 函数实现了广度优先搜索来求解八数码问题的最优路径。
    • 定义了移动方向和对应的操作字符。
    • 使用优先队列进行搜索,根据当前状态的步数和启发函数值进行排序。
    • 通过遍历四个方向,尝试交换空白格与相邻位置的数字,更新状态和相关信息。
    • 最终通过回溯得到从起始状态到目标状态的路径。
  3. main 函数用于读取输入的八数码状态,判断是否可解,并调用 bfs 函数求解。

改进思路

  1. 数据结构优化:考虑使用更高效的数据结构来存储已访问的状态,例如布隆过滤器或者哈希表的优化实现,以提高查找速度。
  2. 启发函数改进:进一步优化启发函数,使其更准确地估计到目标状态的距离,可能会提高搜索效率。
  3. 剪枝策略:分析问题的特性,添加更多有效的剪枝条件,避免不必要的搜索。
  4. 并行化:如果计算资源允许,可以考虑对搜索过程进行并行化处理,加快搜索速度。
  5. 代码可读性和可维护性:添加更多的注释来解释关键代码段的作用和逻辑。将一些复杂的逻辑提取为独立的函数,以提高代码的可读性和可维护性。

其它代码

#include <cstring>
#include <iostream>
#include <algorithm>
#include <queue>
#include <unordered_map>
using namespace std;
typedef pair<int, string> PIS;
int f(string state) {
    int res = 0;
    for (int i = 0; i < state.size(); i++)
        if (state[i]!= 'x') {
            int t = state[i] - '1';
            res += abs(i / 3 - t / 3) + abs(i % 3 - t % 3);
        }
    return res;
}
string bfs(string start) {
    int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
    char op[4] = {'u', 'r', 'd', 'l'};
    string end = "12345678x";
    unordered_map<string, int> dist;
    unordered_map<string, pair<string, char>> prev;
    priority_queue<PIS, vector<PIS>, greater<PIS>> heap;
    heap.push({f(start), start});
    dist[start] = 0;
    while (heap.size()) {
        auto t = heap.top();
        heap.pop();
        string state = t.second;
        if (state == end) break;
        int step = dist[state];
        int x, y;
        for (int i = 0; i < state.size(); i++)
            if (state[i] == 'x') {
                x = i / 3, y = i % 3;
                break;
            }
        string scource = state;
        for (int i = 0; i < 4; i++) {
            int a = x + dx[i], b = y + dy[i];
            if (a >= 0 && a <= 2 && b >= 0 && b <= 2) {
                swap(state[x * 3 + y], state[a * 3 + b]);
                if (!dist.count(state) || dist[state] > step + 1) {
                    dist[state] = step + 1;
                    prev[state] = {scource, op[i]};
                    heap.push({dist[state] + f(state), state});
                }
                swap(state[x * 3 + y], state[a * 3 + b]);
            }
        }
    }
    string res;
    while (end!= start) {
        res += prev[end].second;
        end = prev[end].first;
    }
    reverse(res.begin(), res.end());
    return res;
}

int main() {
    string g, c, seq;
    while (cin >> c) {
        g += c;
        if (c!= "x") seq += c;
    }
    int res = 0;
    for (int i = 0; i < seq.size(); i++)
        for (int j = i + 1; j < seq.size(); j++)
            if (seq[i] > seq[j]) res++;
    if (res & 1) puts("unsolvable");
    else cout << bfs(g) << endl;
    return 0;
}

代码思路

  • f 函数用于计算当前状态与目标状态的曼哈顿距离估计值。
  • bfs 函数通过广度优先搜索和优先队列来找到从初始状态到目标状态的最优路径。
    • 定义了移动方向和对应的操作字符。
    • 维护了已访问状态的距离和前驱信息。
    • 通过交换 x 与相邻位置的数字来探索新状态。
  • main 函数读取输入的初始状态,判断其是否可解,然后调用 bfs 函数求解并输出结果。

改进思路

  • 可以考虑使用位运算来表示状态,减少存储空间和计算量。
  • 对于启发函数,可以进一步研究更精确的估计方式。
  • 对搜索过程中的一些边界情况和异常处理进行更完善的考虑。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

旅游系统(附管理端+前台)PHP源码

一. 前言 今天小编给大家带来了一款可学习&#xff0c;可商用的&#xff0c;旅游系统 源码&#xff0c;支持二开&#xff0c;无加密。支持景点管理&#xff0c;登录&#xff0c;景点预定&#xff0c;意见反馈&#xff0c;统计等功能。详细界面和功能见下面视频演示。 二. 视频…

深入挖掘海外快手kwai ads推广巴西slots手游广告独家优势

深入挖掘海外快手kwai ads推广巴西slots手游广告独家优势 在数字化时代&#xff0c;广告投放已成为各行各业不可或缺的一部分&#xff0c;特别是在游戏行业&#xff0c;如何有效地推广游戏产品&#xff0c;吸引玩家的眼球&#xff0c;成为了每一个游戏开发商和广告主所关注的焦…

DllImport进阶:参数配置与高级主题探究

深入讨论DllImport属性的作用和配置方法 在基础篇中&#xff0c;我们已经简单介绍了DllImport的一些属性。现在我们将深入探讨这些属性的实际应用。 1. EntryPoint EntryPoint属性用于指定要调用的非托管函数的名称。如果托管代码中的函数名与非托管代码中的函数名不同&#…

TreeSize Free - 硬盘空间管理工具

TreeSize FreeTreeSize Free 是一款免费的强大灵活的硬盘空间管理工具。可以帮你找出硬盘上最大的目录以及它占用的空间。支持空间大小显示、分配空间和占用空间、文件数、3D工具条和分配图、最近使用数据、文件作者、NTFS压缩率等信息&#xff0c;并支持搜索文件。该软件类似浏…

掌握亚马逊自养号:测评策略的核心要点与实战经验

在当今电商领域的激烈角逐中&#xff0c;亚马逊测评对于卖家而言&#xff0c;已从单纯的销量助推器与好评累积工具&#xff0c;进化为品牌塑造与市场洞察的关键环节。然而&#xff0c;许多卖家仍局限于传统认知&#xff0c;未能充分挖掘自养号测评的多元化价值与深远影响。本文…

Modbus协议转Profinet协议网关模块连智能仪表与PLC通讯

一、现场需求&#xff1a;PLC作为控制器&#xff0c;仪表设备做为执行设备&#xff0c;执行设备能够实时响应PLC传来的指令&#xff0c;并且向PLC回馈数据&#xff0c;从而达到PLC对仪表设备进行控制和监测&#xff0c;实现对生产过程的精准控制。 二、解决方案&#xff1a;通过…

2024年7月5日 十二生肖 今日运势

小运播报&#xff1a;2024年7月5日&#xff0c;星期五&#xff0c;农历五月三十 &#xff08;甲辰年庚午月庚午日&#xff09;&#xff0c;法定工作日。 红榜生肖&#xff1a;狗、羊、虎 需要注意&#xff1a;鸡、牛、鼠 喜神方位&#xff1a;西北方 财神方位&#xff1a;正…

java考试题20道

选择题 编译Java源代码文件的命令是javac javac命令是将Java源代码文件进行编译得到字节码文件(.class文件) java命令是在JVM上运行得到的字节码文件 下面是一个示例&#xff1a; javac test.java -------> test.class java test ------> 运行test.class文件下列那…

QT_GUI

1、QT安装 一个跨平台的应用程序和用户界面框架&#xff0c;用于开发图形用户界面&#xff08;GUI&#xff09;应用程序以及命令行工具。QT有商业版额免费开源版&#xff0c;一般使用免费开源版即可&#xff0c;下面安装的是QT5&#xff0c;因为出来较早&#xff0c;使用较多&…

以品质为初心,以创新为驱动,光明乳业闪耀第十五届中国奶业大会

2024年7月3日&#xff0c;以“数智赋能引领产业发展增长点&#xff0c;科技创新驱动奶业新质生产力”为主题的中国奶业协会第十五届奶业大会奶业20强&#xff08;D20&#xff09;论坛暨2024中国奶业展览会隆重召开&#xff0c;光明乳业党委书记、董事长黄黎明受邀出席会议&…

代谢组数据分析(十三):评估影响代谢物的重要临床指标

欢迎大家关注全网生信学习者系列: WX公zhong号:生信学习者Xiao hong书:生信学习者知hu:生信学习者CDSN:生信学习者2介绍 相关性分析是通过计算两个变量之间的相关系数来评估它们之间线性关系的强度和方向。最常用的是皮尔逊相关系数(Pearson correlation coefficient),…

python库(3):Cerberus库

1 Cerberus简介 Cerberus 是一个Python数据验证库&#xff0c;设计用于验证数据结构的有效性和一致性。它提供了一种简单而强大的方式来定义和应用验证规则&#xff0c;特别适用于处理用户输入的验证、配置文件的检查以及API的参数验证等场景。下面将详细介绍 Cerberus 的特点…

vite项目配置svg图标(vite-plugin-svg-icons)

1.插件地址 网址 , 可以去里面查看中文文档,里面有详情的教程 2.使用, 如果你安装的有element-plus ,可以使用这样的方式来修改大小和颜色 <el-icon size"18" color"red"><SvgIcon name"xing"></SvgIcon></el-icon> …

汇聚荣拼多多评价好不好?

汇聚荣拼多多评价好不好?在探讨电商平台的口碑时&#xff0c;用户评价是衡量其服务质量和商品质量的重要指标。拼多多作为国内领先的电商平台之一&#xff0c;其用户评价自然成为消费者选择购物平台时的参考依据。针对“汇聚荣拼多多评价好不好?”这一问题&#xff0c;可以从…

Elasticsearch初识与 index+mapping+document 基操

前言 在21年多少有使用过es 当时是在艺术赛道的一个教育公司&#xff0c;大概流程就是 将mysql中的各种课程数据通过logstash汇总到es 然后提供rest接口出去。由于在职时间较短(很不幸赶上了教育双减)&#xff0c;所以对es的了解其实仅仅是些皮毛&#xff0c;当然elk在我的任职…

稀疏数组搜索

题目链接 稀疏数组搜索 题目描述 注意点 字符串数组中散布着一些空字符串words的长度在[1, 1000000]之间字符串数组是排好序的数组中的字符串不重复 解答思路 因为数组中的字符串是排好序的&#xff0c;所以首先想到的是二分查找&#xff0c;先将数组中长度与s相同的字符串…

全网都在疯传的最新蓝海风口项目!

最近全网都在疯传这种视频&#xff0c;想必兄弟们都见到过了&#xff01; 大家看这个号&#xff0c;1天的时间&#xff0c;2个作品&#xff0c;第2个直接就爆了&#xff0c;昨天看点赞还是3.8w&#xff0c;今天已经10w了&#xff0c;这是妥妥的风口啊&#xff01; 大家有没有想…

io_contextttttttttttt

创建上下文——io_context_t 它是一个上下文结构&#xff0c;在内部它包含一个完成队列&#xff0c;在线程之间是可以共享的。 提交请求——iocb io回调数据结构&#xff0c;和io_submit配合使用。 处理结果 通过io_event处理结果&#xff0c; struct io_event {void *data…

TIS人人都会用的数据集成产品

文章目录 1.TIS是什么&#xff1f;1.1 简介1.2 官网及项目地址1.3 架构 2.功能特性2.1 基于Web UI的开箱即用2.2 支持分布式任务分发2.3 全新的基于微内核的运行环境2.4 功能覆盖DataX大部分&#xff08;Reader/Writer&#xff09;Plugin2.5 重构DataX的Classloader2.6 支持RDB…

科比老大职业生涯数据预测(基于随机森林模型)

1.实验背景 科比布莱恩特&#xff0c;作为NBA历史上最伟大的篮球运动员之一&#xff0c;他的职业生涯充满了无数精彩瞬间。 科比于1996年以13顺位的选秀身份进入联盟&#xff0c;一生都效力于洛杉矶湖人队。于2016年宣布退役&#xff0c;职业生涯获奖无数&#xff0c;5次NBA总…