基于python的骑士游历问题解析

基于python的骑士游历问题解析 系统:windows 环境:codeblocks 语言:C++ 一

本文包含相关资料包-----> 点击直达获取<-------

基于python的骑士游历问题解析

  • 系统:windows

  • 环境:codeblocks

  • 语言:C++

一、需求分析

在棋盘上,骑士只能走日字(L 形).假设骑士在(0,0),我们希望用最少的移动步数使他走到(x,y)(例如,从(0,0)到(1,1)需要两步,骑士可以移动到棋盘的负坐标处)。

要求:设计一个可采纳的启发式函数,来估计需要的最小移动步数值,保证结果足够地精确。 用 A*算法和你的启发式函数来编程实现求解。结果输出详细过程。

证明你的函数是可采纳的。

二、问题重述

  • 将路径长度规定为移动步数。

  • 所得解路径必为哈密顿路径。

  • 根据对称性,可以看出需要到达负坐标之后再到达目的地的路径,完全可以先到达对称处的正坐标点,再到达目的地。

如下图:

  • s --> t1:可以找到相应的对称点A1';

  • s --> t2:可以找到相应的对称点B1'和B2';

并且路径长度是相同的。

三、算法分析

3.1. 算法步骤

具体步骤:

  • 把初始节点S0放入open表中,令f(S0)=0

  • 如果open表为空,则问题无解,退出。

  • 把open表中选取第一个节点(节点n)从open表中移到closed表中。

  • 考察节点n是否为目标节点,若是则求得问题的解,并退出;否则继续.

  • 如果节点n可扩展,则转6,否则转2

  • 扩展节点n,对其后续节点集合M中的某一个节点m(xm,ym),计算f(x,y)=g(x,y)+h(x,y) ,把open表中的节点按照f值从小到大排序。

  • 其中g(x,y)是从S0(x0,y0)到当前状态m(xm,ym)的步数

  • 初始条件

可根据父节点n(xn,yn)递推获得g(x,y)

  • h(x,y)是当前节点到目标状态T(tx,ty)的估计步数

  • 先令

所以 h(x_n,y_n) 函数形式可写为:

  • 为每个节点设置指向n的指针

  • 转向第2步

3.2. 证明算法是A*

3.2.1 可采纳性

根据前人的定理,A*算法具有可采纳性,所以只需要证明本文算法为A*算法,所以只需证明两个条件:

对于评判函数

只需证明:

(1)式由于递推的关系容易知道是正确的,起点x为特例 g(x) = 0

对于(2)式,图上两点最短距离为曼哈顿距离dt,而L形走法每次最多走3步,而且因为是L形限制,可能会走更多的路,所以容易得到

可见该算法是A*算法,有可采纳性。

四、算法实现与优化

4.1. 相关变量的定义

4.1.1 bili类与pair

  • bili类

存储状态节点和估计函数,方便之后的open表进行比较

c++ struct bili { int x,y,l; // x,y代表横纵坐标,l代表耗估计函数f(x,y); bili() {} bili(int _x,int _y,int _l):x(_x),y(_y),l(_l) {} };

  • pair 类(pii)
  • pair
  • 这里使用pii类是为了方便对状态(形如 (x,y) )的管理,为了方便open表比较耗散值大小,所以写了一个bili类来重写“<”号。

c++ typedef pair<int, int> pii;

元素 功能
first 相当于x
second 相当于y
make_pair(x,y) Construct pair object: pair

4.1.2 open表

c++ bili heap[maxn],open[maxn]; int sz = 0;

4.1.2.1 采用小根堆优化实现。

小根堆,又名最小堆,是一种经过排序的完全二叉树,其中任一非终端节点的数据值均不大于其左子节点和右子节点的值。

4.1.2.2 分析

如果用循环数组模拟open表,则每次都需要对数组进行排序,并且将估计耗散值最小的状态取出进行下一步操作。我会采用插入排序。

复杂度为:

而小根堆这个数据结构的功能采用堆排序的原理将一堆数据中估值最小的状态置于队列的顶端,方便取出和使用。

复杂度为:

4.1.3 closed表

c++ int g[maxm][maxm]; vector<pii> closed;

  • 用数组g标记状态S是否已经路过,降低判断S是否已经路过时的复杂度。

  • closed用来存储使用过的状态,降低打印的复杂度。

  • 判断复杂度:

  • 打印复杂度:

  • 总的复杂度:

4.1.4 设置指向n的指针

c++ pii pre[maxm][maxm]; //pre[x][y]表示(x,y)的上一个状态 //设置指向父节点的指针 pre[xx][yy] = make_pair(a.x, a.y);

具体实现逻辑请看代码。

4.1.5 估值函数h(x,y)

c++ int h(int x,int y) { int dt = abs(x-tx)+abs(y-ty); if (dt%3==0) { return dt/3; } return dt/3+1; }

4.1.6 打印函数

该函数存在的价值是打印每次 从open表取出父节点,扩展出子节点之后 的棋盘的状态,即可以展示每次增加了哪些子节点,具体效果请看使用说明书。

c++ void print_status(){ printf("\nboard:\nS: starting point, T: ending point;\nK : points that can be reached now, . :points that cannot be reached now.\n\n"); for (int i=0;i<m;i++){ for (int j=0;j<n;j++){ if(i==sx&&j==sy){ printf("S "); }else if (i==tx&&j==ty){ printf("T "); }else if (g[i][j]>0){ printf("K "); }else printf(". "); } printf("\n"); } printf("\nopen表:\n"); for (int i=0;i<sz;i++){ open[i] = heap[i]; } sort(open,open+sz,cmp); for (int i=0;i<sz;i++){ printf("(%d, %d) ",open[i].x,open[i].y); } printf("\nclosed表:\n"); for (int i=0;i<closed.size();i++){ printf("(%d, %d) ",closed[i].first,closed[i].second); } printf("\n"); system("pause"); }

4.1.7 其余变量解释

c++ const int maxm = 12; //棋盘最大尺寸 const int maxn = 150; //open表最大尺寸 int m,n,sx,sy,tx,ty,cnt=0; //cnt用于记录Step,比如Step 1 // m,n输入的棋盘尺寸 // sx,sy 起点, tx,ty 终点 int g[maxm][maxm]; // g(x,y) int dx[8] = { 1,2,2,1,-1,-2,-2,-1 }; int dy[8] = { 2,1,-1,-2,-2,-1,1,2 };

4.2. 整体实现

4.2.1 代码

c++ int bfs(int x,int y) { bili in(x,y,0); push(in); //closed.push_back(make_pair(x,y)); while(sz!=0) { bili a = pop(); closed.push_back(make_pair(a.x,a.y)); //printf("a: (%d,%d)",a.x,a.y); if (a.x == tx && a.y == ty) return g[tx][ty]; printf("\n-------------Step %d-------------\n",++cnt); for (int i=0;i<8;i++){ int xx = a.x+dx[i]; int yy = a.y+dy[i]; if (check(xx,yy)&&g[xx][yy]==0){ g[xx][yy] = g[a.x][a.y] + 1; bili nw(xx,yy,g[xx][yy] + h(xx,yy)); pre[xx][yy] = make_pair(a.x,a.y); push(nw); } } print_status(); } return -1; }

4.2.2 bfs函数流程

  • 将起点放入小根堆(heap),进入2。

  • 如果小根堆为空,进入6;否则进入3。

  • 把小根堆的堆顶元素a取出,如果堆顶元素为终点,进入5;否则,进入4。

  • 计算a的下一步能走到的 合法 的点(a的子节点),将a的子节点放入小根堆,使子节点指向a,即pre(son) = a,进入2。

  • 返回路径长度,函数结束。

  • 返回-1,函数结束。

五、测试

Step 1 输入棋盘大小

建议输入大小为8*8的棋盘,棋盘每行每列的下标从0开始。

Step 2 输入起点

请按照 x y 的格式输入,这里假定起点为(0,0)。

Step 3 输入终点

这里选择(6,6)做为终点。

Step 4 连续回车获得结果

这里的open表中放置的是图中K的坐标,closed表加入已经扩展过的节点, 这里是刚开始利用起点(0,0)进行扩展。

多次回车,如果不想回车,可以将以下源代码中 print_status() 函数中的 system("pause") 语句注释后重新编译。

可见Reslut中的最优路径符合预知。

Step 5 总结

可视化

利用字符串实现了简单可视化,不想用OpenGL实现可视化,感觉要学很久,配环境就配了半小时,学的话学到三角形就开始难受。Qt的话,电脑硬盘空间不够了。嗯,其实想用python,但是现在的我已经可以用简单的可视化让自己安心了,就这样吧,谢谢观看。

参考文献

  • 搜索引擎中网络爬虫及结果聚类的研究与实现(中国科学技术大学·梁萍)
  • 搜索引擎中网络爬虫及结果聚类的研究与实现(中国科学技术大学·梁萍)
  • 基于web数据的装备个性化问答系统的构建(电子科技大学·邓天)
  • 基于知识图谱的旅游问答系统研究与实现(桂林电子科技大学·张楚婷)
  • 基于游客行为的个性化推荐系统研究与实现(北京邮电大学·贾强)
  • 基于MongoDB的旅游垂直搜索系统的设计与实现(华中科技大学·费华辉)
  • 基于web的旅游服务平台的设计与实现(内蒙古大学·张凡)
  • 基于知识图谱的山西旅游饮食问答系统(中北大学·韩馥)
  • 基于SSH架构的个人空间交友网站的设计与实现(北京邮电大学·隋昕航)
  • 基于web数据的装备个性化问答系统的构建(电子科技大学·邓天)
  • 基于网络爬虫的论坛数据分析系统的设计与实现(华中科技大学·黎曦)
  • 基于web的旅游服务平台的设计与实现(内蒙古大学·张凡)
  • 分布式智能网络爬虫的设计与实现(中国科学院大学(工程管理与信息技术学院)·何国正)
  • 主题爬虫的实现及其关键技术研究(武汉理工大学·张航)
  • 基于知识图谱的广西旅游问答系统研究和实现(桂林理工大学·徐金诚)

本文内容包括但不限于文字、数据、图表及超链接等)均来源于该信息及资料的相关主题。发布者:代码货栈 ,原文地址:https://m.bishedaima.com/yuanma/35521.html

相关推荐

  • 基于Java+jsp+servlet+mysql的学生选课系统实现

    这是一个🔥🔥基于jsp+servlet+mysql的学生选课系统实现🔥🔥的项目源码,开发语言Java,开发环境Idea/Eclipse,这个 学生选课系统实现开发技术栈为JSP项目
    2024年05月23日
    17 1 5
  • 基于SpringBoot框架的校园网上店铺

    这是一套采用Java编程语言,基于SpringBoot框架构建的📚校园电商系统源代码,该项目运用了SpringBoot和Vue技术栈,开发工具为Idea或Eclipse
    2024年05月23日
    2 1 2
  • 基于JSP/Servlet的购物车系统实现源码

    这是一个🔥🔥基于JSP的购物车系统实现源码🔥🔥的项目源码,开发语言Java,开发环境Idea/Eclipse,这个 购物车系统实现开发技术栈为JSP项目,可以作为毕业设计课程设计作业基于JSP/Servlet技术实现一个购物车系统
    2024年05月23日
    14 1 1
  • 基于Python的车牌检测和识别系统

    车牌检测和识别的Python应用软件实现 徐静 1,车牌检测和识别项目介绍 图片来源:https://www,cnblogs,com/polly333/p/7367479
    2024年05月14日
    2 1 1
  • 海滨学院班级回忆录

    这是一个🔥🔥基于SpringBoot框架的海滨学院班级回忆录设计与实现🔥🔥的项目源码,开发语言Java,框架使用的SpringBoot+vue技术,开发环境Idea/Eclipse
    2024年05月23日
    2 1 2
  • 基于springboot的办公oa系统实现源代码

    在当今数字化时代,办公自动化系统(OA)已成为企业提升运行效率,管理流程的重要工具,随着信息技术的不断发展,基于Spring Boot的办公OA系统的开发变得愈发重要,该系统集成了MySQL数据库
    2024年05月07日
    7 1 3
  • 基于Java+SSM的学生学籍管理系统

    基于Java+SSM的学生学籍管理系统在当今数字化教育环境下具有重要意义,随着信息技术的不断发展,学校管理工作面临着日益增长的挑战,传统的手工管理已无法满足实时性和效率性的需求
    2024年05月07日
    20 1 3
  • 基于 SSM 实现医院药品库存管理系统

    DIMS 数据库系统原理课程设计,DIMS,Drug Inventory Management System,基于 SSM 框架的医院药品库存管理系统, 任务分工 需求分析: 概念结构设计: 逻辑结构设计: 物理结构设计: 数据库实施: 数据库运行和维护: 应用系统设计: 测试与验收: 编写文档: 编写答辩 PPT: 数据库设计 在数据库设计过程中
    2024年05月14日
    4 1 1
  • Pythonweb之工资管理系统

    软件工程课程设计实验报告 一,项目开发 引言 编写目的 为了保证项目团队按时保质地完成项目目标,便于项目团队成员更好地了解项目情况,使项目工作开展的各个过程合理有序
    2024年05月14日
    26 1 8
  • 基于Python实现的搜索和推荐系统

    基于Python实现的搜索和推荐系统 一,引言 伴随着科技的不断进步,互联网,万维网的不断发展,我们越来越热爱万维网,也欣赏他的发展方式,20世纪90年代初
    2024年05月14日
    2 1 2

发表回复

登录后才能评论