最近人工智能课老师布置了一个八数码实验,网上看到很多八数码的启发式A*算法,但是大多数都是利用C或者C++在控制台实现的,于是我用js在网页中做了一个类似的。

首先八数码就是一个九宫格,其中有一个空格,其他八个对应数字1-8,
移动空格,使得最后状态为有序,如下图
启发式算法是指在求解时,利用启发函数将不符合规则的解节点去掉,从而缩小问题的解空间。
A*算法是利用评价函数的启发式算法,在本例中,利用当前节点状态与最终节点状态所不同的格子数来评估节点的优劣,将优越节点储存并在之后展开,将劣质节点抛弃。
利用web实现这一点首先在html中添加九个如图所示input文本框,背景图片为数码格
页面代码为
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>八数码</title>
<style type="text/css">
#result input{
display: inline-block;
font-family:"微软雅黑";
font-size: 60px;
font-weight: 900;
text-align: center;
width:100px;
height:100px;
background:url(images/0.png);
background-size:cover;
}
</style>
</head>
<body>
<div id="result">
<input type="text" id="r1">
<input type="text" id="r2">
<input type="text" id="r3"><br>
<input type="text" id="r4">
<input type="text" id="r5">
<input type="text" id="r6"><br>
<input type="text" id="r7">
<input type="text" id="r8">
<input type="text" id="r9"><br>
</div>
<button onclick="run()">求解</button>
</body>
</html>
然后利用javascript获取输入的值,并保存在二维数组中
var startArray=[[8,1,3],[0,2,4],[7,6,5]];//初始化八数码数组
//获取输入的初始状态
var cpic=1;
for(var i=0;i<N;i++){
for(var j=0;j<N;j++){
var rid='r'+cpic++;
var inputValue=getId(rid).value;
if(inputValue==""){inputValue=0;}
startArray[i][j]=parseInt(inputValue);
getId(rid).value="";
}
}
var startGraph=new Graph(startArray);
var endArray=[[ 1,2,3],[ 8,0,4 ],[ 7,6,5 ]];
var endGraph=new Graph(endArray);//目标节点
evaluateGraph(startGraph,endGraph);
showGraph(startGraph);
其中Graph类是用来来保存一个状态节点相关数据:
//节点类
var Graph = function(formData){
this.form=formData;
this.evalue=0;
this.udirect=0;
this.parent=null;
};
实现一个showGraph()函数来显示八数码状态:
function showGraph(graph) {
var c=1;
for(var i=0;i<N;i++){
for(var j=0;j<N;j++){
var s='r'+c++;
getId(s).style.backgroundImage="url(images/"+graph.form[i][j]+".png)";
}
}
}
利用评估函数evaluateGraph()评估当前节点与目标节点的差距值
//评估函数
function evaluateGraph(theGraph, endGraph){
var differ = 0;//差距数
for (var i = 0; i<N; i++)
{
for (var j = 0; j<N; j++)
{
if (theGraph.form[i][j] != endGraph.form[i][j]){differ++;}
}
}
theGraph.evalue = differ;
return differ;
}
利用moveGraph()函数来移动并返回一个新节点:
//移动数码组
function moveGraph(theGraph, direct){
var HasGetBlank = 0;//是否找到空格位置
var AbleMove = 1;//是否可移动
var i, j, t_i, t_j;
//查找空格坐标i,j
for (i = 0; i<N; i++)
{
for (j = 0; j<N; j++)
{
if (theGraph.form[i][j] == 0)
{
HasGetBlank = 1;
break;
}
}
if (HasGetBlank == 1)
break;
}
t_i = i;
t_j = j;
//移动空格
switch (direct)
{
case 1://上
t_i--;
if (t_i<0)
AbleMove = 0;//移动超过边界
break;
case 2://下
t_i++;
if (t_i >= N)
AbleMove = 0;
break;
case 3://左
t_j--;
if (t_j<0)
AbleMove = 0;
break;
case 4://右
t_j++;
if (t_j >= N)
AbleMove = 0;
break;
}
//Direct方向不能移动,返回原节点
if (AbleMove == 0)
{
return theGraph;
}
//向Direct方向移动,生成新节点
var ta=[[0,0,0],[0,0,0],[0,0,0]];
var New_graph = new Graph(ta);
for (var x = 0; x<N; x++)//复制数码组
{
for (var y = 0; y<N; y++)
{
New_graph.form[x][y] = theGraph.form[x][y];
}
}
//交换
New_graph.form[i][j] = New_graph.form[t_i][t_j];//交换空格和移动方向上的数字
New_graph.form[t_i][t_j] = 0;
return New_graph;
}
最后是搜索函数,通过从初始节点开始一层层向下搜索,直到抵达目标节点,返回子节点,从子节点一层层向上回溯父节点,便可找到解路径:
//搜索路径
function Search(beginGraph, endGraph){
var g1, g2, g;
var Step = 0;//深度
var Direct = 0;//方向
var i;
var front=-1,rear=-1;
g1=beginGraph;//初始八数码节点
while (g1)//队列不空,从close队列中拿出一个节点
{
for (i = 1; i <= 4; i++){//分别从四个方向推导出新子节点
Direct = i;
if (Direct == g1.udirect)
continue;//跳过屏蔽方向
g2=moveGraph(g1,Direct);
if (evaluateGraph(g2,g1)!=0){//数码组是否可以移动
evaluateGraph(g1,endGraph);
evaluateGraph(g2,endGraph);//评价新的节点
if (g2.evalue <= g1.evalue + 1)//利用评估值判断是否为优越节点
{ //若为优,将g2的父节点指向g1
g2.parent = g1;
//设置屏蔽方向,防止往回推
switch (Direct){
case 1://上
g2.udirect = 2;
break;
case 2://下
g2.udirect = 1;
break;
case 3://左
g2.udirect = 4;
break;
case 4://右
g2.udirect = 3;
break;
}
Qu[++rear]=g2;//把优越节点放到close队列
if (g2.evalue == 0)//为0则搜索完成
{
g = g2;
break;
}
}
else{g2 = null;}//抛弃劣质节点
}
}
//搜索完成,继续退出
if (typeof g !== 'undefined')
{
if (g.evalue == 0)
{
break;
}
}
Step++;//统计深度
if (Step>Max_Step){
alert("超过搜索深度!");
break;}
g1=Qu[++front];//从close队列中拿出一个节点继续下一轮展开
}
return g;
}
最后将解路径节点按顺序压入堆栈,每秒弹出一个节点,显示,形成动画:
var top=-1;
var G;
G = Search(startGraph, endGraph);
//解序列存入堆栈
var P=G;
while (P != null)
{
top++;
St[top] = P;
P = P.parent;
}
//动画执行
var si=setInterval(function () {
if (top>-1)
{
showGraph(St[top]);
top--;
}else {
clearInterval(si);
}
},1000);
}
以上所述是小编给大家介绍的利用JavaScript在网页实现八数码启发式A*算法动画效果,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的,在此也非常感谢大家对网站的支持!
# js八数码
# 启发式A算法
# js
# 九宫格
# PHP 双链表(SplDoublyLinkedList)简介和使用实例
# 10分钟教你用python动画演示深度优先算法搜寻逃出迷宫的路径
# tween.js缓动补间动画算法示例
# JavaScript排序算法动画演示效果的实现方法
# javascript动画算法实例分析
# 用队列模拟jquery的动画算法实例
# 看动画学算法之Java实现doublyLinkedList
# 小编
# 都是
# 在此
# 是指
# 并在
# 微软
# 我用
# 给大家
# 便可
# 弹出
# 后将
# 将不
# 所述
# 给我留言
# 跳过
# 感谢大家
# 如下图
# 文本框
# 有一个
# 中做
相关文章:
邀请函制作网站有哪些,有没有做年会邀请函的网站啊?在线制作,模板很多的那种?
建站主机选购指南与交易推荐:核心配置解析
义乌企业网站制作公司,请问义乌比较好的批发小商品的网站是什么?
定制建站价位费用解析与套餐推荐全攻略
免费制作统计图的网站有哪些,如何看待现如今年轻人买房难的情况?
javascript中的try catch异常捕获机制用法分析
如何选择高性价比服务器搭建个人网站?
专业制作网站的公司哪家好,建立一个公司网站的费用.有哪些部分,分别要多少钱?
制作网站的公司有哪些,做一个公司网站要多少钱?
建站主机是否属于云主机类型?
如何用美橙互联一键搭建多站合一网站?
香港服务器租用每月最低只需15元?
如何通过PHP快速构建高效问答网站功能?
网页制作模板网站推荐,网页设计海报之类的素材哪里好?
网站制作和推广的区别,想自己建立一个网站做推广,有什么快捷方法马上做好一个网站?
小米网站链接制作教程,请问miui新增网页链接调用服务有什么用啊?
东莞专业制作网站的公司,东莞大学生网的网址是什么?
,想在网上投简历,哪几个网站比较好?
C++中的Pimpl idiom是什么,有什么好处?(隐藏实现)
如何规划企业建站流程的关键步骤?
建站之星五站合一营销型网站搭建攻略,流量入口全覆盖优化指南
如何制作新型网站程序文件,新型止水鱼鳞网要拆除吗?
如何快速查询网站的真实建站时间?
如何在阿里云虚拟服务器快速搭建网站?
高防服务器如何保障网站安全无虞?
电脑免费海报制作网站推荐,招聘海报哪个网站多?
如何在景安服务器上快速搭建个人网站?
如何在IIS中新建站点并解决端口绑定冲突?
C++中引用和指针有什么区别?(代码说明)
c# await 一个已经完成的Task会发生什么
台州网站建设制作公司,浙江手机无犯罪记录证明怎么开?
网站代码制作软件有哪些,如何生成自己网站的代码?
北京营销型网站制作公司,可以用python做一个营销推广网站吗?
建站之星如何修改网站生成路径?
c++23 std::expected怎么用 c++优雅处理函数错误返回【详解】
制作宣传网站的软件,小红书可以宣传网站吗?
电商网站制作多少钱一个,电子商务公司的网站制作费用计入什么科目?
如何在Windows环境下新建FTP站点并设置权限?
专业网站制作企业网站,如何制作一个企业网站,建设网站的基本步骤有哪些?
如何用PHP工具快速搭建高效网站?
香港服务器网站推广:SEO优化与外贸独立站搭建策略
建站三合一如何选?哪家性价比更高?
外汇网站制作流程,如何在工商银行网站上做外汇买卖?
三星网站视频制作教程下载,三星w23网页如何全屏?
已有域名和空间如何搭建网站?
清除minerd进程的简单方法
如何生成腾讯云建站专用兑换码?
C++如何使用std::optional?(处理可选值)
攀枝花网站建设,攀枝花营业执照网上怎么年审?
网站设计制作公司地址,网站建设比较好的公司都有哪些?
*请认真填写需求信息,我们会在24小时内与您取得联系。