人工智能十五数码实验报告材料.doc

上传人:夺命阿水 文档编号:21949 上传时间:2022-07-13 格式:DOC 页数:17 大小:267.95KB
返回 下载 相关 举报
人工智能十五数码实验报告材料.doc_第1页
第1页 / 共17页
人工智能十五数码实验报告材料.doc_第2页
第2页 / 共17页
人工智能十五数码实验报告材料.doc_第3页
第3页 / 共17页
人工智能十五数码实验报告材料.doc_第4页
第4页 / 共17页
人工智能十五数码实验报告材料.doc_第5页
第5页 / 共17页
点击查看更多>>
资源描述

《人工智能十五数码实验报告材料.doc》由会员分享,可在线阅读,更多相关《人工智能十五数码实验报告材料.doc(17页珍藏版)》请在课桌文档上搜索。

1、目录1 实验概述22 十五数码问题分析2233问题的求解策略333.2 A*算法设计44 实验总结54.1 实验可视化界面564.3 详细代码:71 实验概述十五数码问题来源于美国的科学魔术大师萨姆.洛伊德Sam I.oyd在1978年推出的著名的“14-15智力玩具。 这个游戏曾经风靡欧美大陆 。洛伊德的发明其实只是将重排九宫即八数码问题中的3阶方阵扩大到4 阶方阵罢了。 由于这个细微的变化,十五数码问题的规模远远大于八数码问题,八数码问题的规模较小,总的状态数为9!=362880个,而十五数码问题的状态,数为16!个。 故十五数码问题更能评价一个算法的“智能水平。2 十五数码问题分析15数

2、码问题又叫移棋盘问题,是人工智能中的一个经典问题。所谓的15数码问题:就是在一个44的16宫格棋盘上,摆放有15个将牌,每一个将牌都刻有115中的某一个数码。棋盘中留有一个空格,允许其周围的某一个将牌向空格移动,这样通过移动将牌就可以不断改变将牌的布局。这种求解的问题是:给定一种初始的将牌布局或结构(称初始状态)和一个目标布局(称目标状态),问如何移动数码,实现从初始状态到目标状态的转变,如如下图所示 。问题的实质就是寻找一个合法的动作序列十五数码问题存在无解的情况,当遍历完所有可扩展的状态也没有搜索到目标状态就判断为无解。可以根据状态的逆序数来先验的判断是否有解,当初始状态的逆序数和目标状态

3、的逆序数的奇偶性一样时,问题有解;否如此问题无解。状态的逆序数是定义如下:把四行数展开排成一行,并且丢弃数字 0 不计入其中,i是第 i 个数之前比该数小的数字的个数,如此 =0+0+1+2+4+4+2+6+8+9+8+9+11+6+11=81;对于目标状态:1、2、3、4、5、6、7、8、9、10、11、12、13、14、15,其=0+1+2+3+4+5+6+7+8+9+10+11+12+13+14=105。初始状态和目标状态的奇偶性一样,故存在解路径。3问题的求解策略十五数码问题的解空间树属排列树,用于排列树搜索的方法主要有两大类:一类是盲目搜索,如深度优先搜索DFS 和广度优先搜索BFS

4、;另一类是启发式搜索,如 A* 算法。对于十五数码问题,深度优先搜索的状态空间搜索树的深度可能为无限深, 或者可能至少要比某个可承受的解答序列的深度上限还要深。 应用此策略很可能得不到解。 宽度优先搜索的优势在于当问题有解时, 一定能找到解, 且能找到最优解。但其搜索时需要保存所有的待扩展结点,这样很容易扩展那些没有用的结点,造成状态的指数增长,甚至“组合爆炸。这对宽度优先搜索很不利。这两种搜索方法的共同缺点是结点排序杂乱无章,往往在搜索了大量无关结点后才能得到目的结点,只适合于复杂度较低的问题的求解。启发式搜索利用特定问题自身所携带的启发信息在一定程度上防止了盲目搜索的不足,适合于解决十五数

5、码问题。 其核心思想是引入一个启发式函数或称为评估函数利用评估函数为生成的结点估值%并按估值的大小对结点进展排序,优先搜索估值小的结点。 该评估函数根据问题的启发信息建立,评估了解决问题所需的最小费用,其根本形式是f(n) = g(n)+h(n)。 其中g(n):从初始状态 s 到中间状态n 的最优代价g*(n)的估值,hn:从中间状态 n 到目标状态 t 的最优代价h*n的估值,利用评估函数来进展的图搜索算法称为 A算法,假如还有hn= h*n如此称为A*算法。在八数码问题中,通常gn是搜索树中当前结点n的深度,是从根结点到当前结点n的最短路径长度;hn的取值如此有多种,如错位将牌数、曼哈顿

6、距离。这里主要是hn表现了启发信息,hn设计的好坏表现了算法的“智能水平。本课设借鉴这些算法hn采用曼哈顿距离。3.2 A*算法设计1根据初始排列生成初始结点s,并判断问题的可解性。假如可解如此转2否如此退出。2初始化open,closed表,并将初始节点参加open表。3从open表中取出第一个节点。4假如是目标节点如此成功退出。5把该节点从open表删除,并添加到closed表中。6对该节点进展扩展,其生成节点mi分成三种情况,mj,mk,ml。mj:新生成的节点既不在open表中也不在closed表中,直接把生成的节点添加到open表即可。Mk:新生成的节点出现在open表中且新生成节点

7、的fn小于open表中该节点的fn,如此更改open表中的fn的值。Ml:新生成的节点在closed表中并且新生成节点的fn小于closed表中对应节点的fn的值,如此把该节点从open表中删除,添加到open表中并写该其f值为新生成节点的f值。7对open表中的节点按f值从小到大的顺序进展排列。8转到3。4 实验总结4.1 实验可视化界面初学人工智能时,最先联想到的便是机器人,一直感觉机器人是非常智能且神秘的,这也令人工智能在我的思想里笼罩了一层非同寻常的面纱,非常迫切的想要了解他的涵。经过三十多个学时的学习,我对人工智能已经有了初步的了解,也深深的被它吸引,尤其通过本次课程设计,对人工智能

8、的学习兴趣更加浓厚了!15数码问题是人工智能的一个经典的问题。本文过设计一个基于A*算法的状态空间搜索程序,对于给定的初始状态,采用f(n)=h(n)+g(n)表示以当前节点与其目标节点相应位置不一样元素的个数与搜索深度之和作为启发函数的度量,并用面相对象的编程语言java来实现该问题。在程序的设计与实现过程中,遇到了很多的问题。首先由于初学人工智能,理解上有一定的困难,对A*算法的深入学习是一个曲折的过程。其次,在程序真正的设计与实现过程中,确实需要花费大量的精力来思考,反复试验。所设计的程序能够运行,但缺陷还是非常之大的,如其中重排OPEN表时,没有进展真正意义上的重新排列,只是选出代价最

9、小的放在最先的位置,这实际上对程序的运行效率有很大的影响。 同时通过输入大量的初始状态和目标状态发现,在一般情况下都可以找到最优的动作序列。但对某些稍微复杂的初始状态虽能得到正确解却不能完全得到最短的搜索路径,对于某些极其复杂的状态,甚至得不到解。这是有待进一步学习并改良的地方。 但本程序还是有些值得肯定之处。界面设计比拟友好,容易操作。而且在程序开始时,就判断目标状态是否可达,这样可节约大量的时间。虽然很多地方设计的不尽如意,但这是针对十五数码这个具体问题的一点优化。4.3 详细代码:public class Main public static final int N = 4;static

10、 int num = 5,1,2,4,9,6,3,8,13,15,10,11,14,0,7,12;static int standard = 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0;public static void main(String args)int totalnum = 0;Node node = new Node(num);if(!Data.isDataOk(num, standard)System.out.println(此种方案无解);System.exit(-1);System.out.println(数据的变化情况如下所示:n);Nod

11、e resultnode = FifteenNum.moveManHa(node);for(int i=1; i=resultnode.getPnodes().size(); i+)Interface f = new Interface();f.P1(resultnode.getPnodes().get(i-1).data,i-1);try Thread.sleep(2000); catch (InterruptedException e) e.printStackTrace();resultnode.getPnodes().get(i-1).print();System.out.printl

12、n();System.out.println();System.out.println(第+i+步);totalnum = i;Interface f = new Interface();f.P1(resultnode.data,totalnum);resultnode.print();import java.util.ArrayList;import java.util.List;public class Node public static final int N = 4; private int f ; private int h ; private int w ; List pnode

13、s = new ArrayList(); FifteenNum.Direction last_Dirction ; int data = new intNN; public Node(int data) this.h = 0; this.w = 0; this.f = 0; this.last_Dirction = null; Data.arrayCopy(this.data, data); /pnodes.add(this); public List getPnodes() return pnodes;public FifteenNum.Direction getLast_Dirction(

14、) return last_Dirction;public void setLast_Dirction(FifteenNum.Direction lastDirction) last_Dirction = lastDirction;public int getF() return f;public void setF(int f) this.f = f;public int getH() return h;public void setH(int h) this.h = h;public int getW() return w;public void setW(int w) this.w =

15、w;public void print()System.out.println();for(int i=0; i8; i+)System.out.print(* );System.out.println();for(int i=0; iN; i+)System.out.print(* );for(int j = 0; jN; j+)if(dataij = 0)System.out.print( );else if(dataij 10)System.out.print(dataij+ );elseSystem.out.print(dataij+ );System.out.println(*);f

16、or(int i=0; i8; i+)System.out.print(* );System.out.println();public boolean isequal( Node node)boolean flag = true;for(int i=0; iN; i+)for(int j = 0; jN; j+)if(dataij != node.dataij)flag = false;break;if(!flag) break;return flag;public Node getSameStateFrom(List list)for(int i=0; ilist.size(); i+)if

17、(this.isequal(list.get(i) return list.get(i);return null;import java.util.Scanner;public class Data public static int n = Main.N;static Scanner sc = new Scanner(System.in);public static void inputNum(int num)int k=0;for(int i=0; in; i+)for(int j = 0; jn; j+)numij = sc.nextInt();public static void ar

18、rayCopy(int a, int b)for(int i=0; in; i+)for(int j = 0; jn; j+)aij = bij;public static int inverseNum(int data)int index = 0;int num = 0;int tempnum = 0;int temp = new intn*n-1;for(int i=0; in; i+)for(int j = 0; jn; j+)if(dataij != 0)tempindex = dataij;/System.out.print(tempindex+ );index+;System.ou

19、t.println();for(int i=0; in*n-1; i+)tempnum = 0;for(int j=0; ji; j+)if(tempjtempi)tempnum+;num += tempnum;return num;public static int WrongLocationNum(int temp)int count = 0;for(int i=0; in; i+)for(int j = 0; jn; j+)if(tempij != 0)if(tempij != Main.standardij)count+;return count;public static int m

20、anHa(int temp)int d = 0;boolean flag = false;for(int x1=0; x1n; x1+)for(int y1=0; y1n; y1+)if(tempx1y1 != 0)flag = false;for(int x2=0; x2n; x2+)for(int y2=0; y2n; y2+)if(tempx1y1 = Main.standardx2y2)d += Math.abs(x1 - x2) + Math.abs (y1 - y2);flag = true;if(flag ) break;if(flag ) break;return d;publ

21、ic static boolean sameOdevity(int m, int n)if(m%2 = n%2) return true;else return false;public static boolean isDataOk(int a, int b)return sameOdevity(inverseNum(a), inverseNum(b);import java.util.ArrayList;import java.util.List;public class FifteenNum public static int openNum = 0;public static int

22、closedNum = 0;public enum Direction UP,RIGHT,DOWN,LEFT;public static final int n = Main.N;static List open = new ArrayList();static List closed = new ArrayList();public static boolean changeTo(Direction direction,int i, int j, int data_temp)int temp;boolean flag = true;switch(direction)case UP: if(i

23、=1)temp = data_tempij;data_tempij = data_tempi-1j;data_tempi-1j = temp;elseflag = false;break;case RIGHT: if(j=2)temp = data_tempij;data_tempij = data_tempij+1;data_tempij+1 = temp;elseflag = false;break;case DOWN: if(i=1)temp = data_tempij;data_tempij = data_tempij-1;data_tempij-1 = temp;elseflag =

24、 false;break;return flag;public static boolean oppositeDirection(Direction d1, Direction d2)if(d1=Direction.UP & d2 = Direction.DOWN | d1=Direction.DOWN & d2 = Direction.UP)return true;else if(d1=Direction.RIGHT & d2 = Direction.LEFT | d1=Direction.LEFT & d2 = Direction.RIGHT)return true;return fals

25、e;public static Node moveManHa(Node node1)Direction direction = Direction.UP, Direction.RIGHT, Direction.DOWN, Direction.LEFT;int i = 0;int j = 0;int wrongNum;boolean isOver = false;/设定初始节点的参数node1.setH(0);node1.setW(Data.manHa(node1.data); /曼哈顿node1.setF(node1.getW()+node1.getH();Node node = null;o

26、pen.add(node1);node = open.remove(0);int a =0;while(node.getW() != 0) /定位要扩展节点的空格所在的位置for(int x=0; xn; x+)for(int y = 0; yn; y+)if(node.dataxy = 0)i = x;j = y;/System.out.println(空格的坐标=+i+j=+j);break;int temp = new intnn;/对刚刚从open表中取出的节点试探性的进展四个方向的扩展for(int dir_index = 0; dir_index 4; dir_index+)if(

27、FifteenNum.oppositeDirection(node.getLast_Dirction(), directiondir_index)continue;Data.arrayCopy(temp, node.data);if(FifteenNum.changeTo(directiondir_index, i, j,temp)wrongNum = Data.manHa(temp);/曼哈顿距离Node node_temp = new Node(temp); /由父节点生成新的节点node_temp.setH(node.getH()+1);node_temp.setW(wrongNum);

28、node_temp.setF(node_temp.getH()+node_temp.getW();node_temp.setLast_Dirction(directiondir_index);/记录该节点的的移动方向,以便其孩子节点不再与该节点移动的方向相反/* * 把新生成节点的祖先节点放入到新生成节点里 */for(int k=0; kml-mj */Node node_ml = null ;Node node_mk = null;/open表中或closed表中 与新生成的节点状态一样 的节点if(node_mk = node_temp.getSameStateFrom(open) !=

29、 null)if(node_temp.getH() node_mk.getH()open.remove(node_temp);open.add(node_temp);else if(node_ml = node_temp.getSameStateFrom( closed) != null)if(node_temp.getH() node_ml.getH()closed.remove(node_ml);open.add(node_temp);openNum+;elseopen.add(node_temp);openNum+;if(Data.manHa(node_temp.data) = 0) /

30、曼哈顿isOver = true;node = node_temp;break;else/不可达的方向,错位将牌数取为10wrongNum = 10;/for完毕if(isOver) break; /如果已经是目标状态退出程序closed.add(node); closedNum+;sort(open);node = open.remove(0);openNum-;/把open表中的第一个节点从open表中删除,添加到closed表中 /while完毕int produce = closedNum + openNum;/System.out.println(扩展节点数closednum=+cl

31、osedNum+生成节点数produce=+produce);return node;public static void sort(List list)for(int i=0; ilist.size(); i+ )int k = i;for(int j=i+1; jlist.get(j).getF()k = j;if(k != i)Node node1;Node node2;node1 = list.get(i);node2 = list.get(k);list.set(i, node2);list.set(k, node1);import java.awt.BorderLayout;imp

32、ort java.awt.Button;import java.awt.Color;import java.awt.Font;import java.awt.GridLayout;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;public class Interface extends JFrameJPanel p1 = new JPanel();JPanel p2 = new JPanel();public Interface()this.setTitle(15数码问题);this.

33、setVisible(true);this.setBounds(100, 100, 150, 150);this.setLayout(new BorderLayout();this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);public void P1(int data, int j)p1.setBackground(Color.blue);p1.setVisible(true);p1.setLayout(new GridLayout(4,4);for(int i=0; i16; i+)Button bi = new Button(+data

34、i/4i%4);if(datai/4i%4 = 0)bi.setBackground(Color.pink);Font f=new Font(华文行楷,Font.BOLD,15);/根据指定字体名称、样式和磅值大小,创建一个新 Font。bi.setFont(f);p1.add(bi);add(p1,BorderLayout.CENTER);P2(j);/* * 用来显示走步 */public void P2(int i)p2.setBackground(Color.yellow);p2.setVisible(true);add(p2,BorderLayout.SOUTH);JLabel l = new JLabel(第+i+步);p2.add(l);

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 在线阅读 > 生活休闲


备案号:宁ICP备20000045号-1

经营许可证:宁B2-20210002

宁公网安备 64010402000986号