`
huxiaoheihei
  • 浏览: 174597 次
  • 性别: Icon_minigender_2
  • 来自: 吉林
社区版块
存档分类
最新评论

用 A* 解决八数码问题

 
阅读更多

Description

The 15-puzzle has been around for over 100 years; even if you don't know it by that name, you've seen it. It is constructed with 15 sliding tiles, each with a number from 1 to 15 on it, and all packed into a 4 by 4 frame with one tile missing. Let's call the missing tile 'x'; the object of the puzzle is to arrange the tiles so that they are ordered as: 
 1  2  3  4 

 5  6  7  8 

 9 10 11 12 

13 14 15  x 

where the only legal operation is to exchange 'x' with one of the tiles with which it shares an edge. As an example, the following sequence of moves solves a slightly scrambled puzzle: 
 1  2  3  4    1  2  3  4    1  2  3  4    1  2  3  4 

 5  6  7  8    5  6  7  8    5  6  7  8    5  6  7  8 

 9  x 10 12    9 10  x 12    9 10 11 12    9 10 11 12 

13 14 11 15   13 14 11 15   13 14  x 15   13 14 15  x 

           r->           d->           r-> 

The letters in the previous row indicate which neighbor of the 'x' tile is swapped with the 'x' tile at each step; legal values are 'r','l','u' and 'd', for right, left, up, and down, respectively. 

Not all puzzles can be solved; in 1870, a man named Sam Loyd was famous for distributing an unsolvable version of the puzzle, and 
frustrating many people. In fact, all you have to do to make a regular puzzle into an unsolvable one is to swap two tiles (not counting the missing 'x' tile, of course). 

In this problem, you will write a program for solving the less well-known 8-puzzle, composed of tiles on a three by three 
arrangement. 

Input

You will receive a description of a configuration of the 8 puzzle. The description is just a list of the tiles in their initial positions, with the rows listed from top to bottom, and the tiles listed from left to right within a row, where the tiles are represented by numbers 1 to 8, plus 'x'. For example, this puzzle 
 1  2  3 

 x  4  6 

 7  5  8 

is described by this list: 
 1 2 3 x 4 6 7 5 8 

Output

You will print to standard output either the word ``unsolvable'', if the puzzle has no solution, or a string consisting entirely of the letters 'r', 'l', 'u' and 'd' that describes a series of moves that produce a solution. The string should include no spaces and start at the beginning of the line.

Sample Input

 2  3  4  1  5  x  7  6  8 

Sample Output

ullddrurdllurdruldr

 

 

 

 

  1. #include <iostream>8 s% W2 b- F3 j$ Y4 o
  2. #include <cstdio>3 _  h, ^$ P9 ?/ ?
  3. #include <cstring>

  4. using namespace std;
  5. 9 S+ n& Q  g  R4 y
  6. #define HEAP_PARENT(i)                        (i >> 1); n- q# z9 x0 {. O) L) c2 Q
  7. #define HEAP_LEFT(i)                        (i << 1)
  8. #define HEAP_RIGHT(i)                        ((i << 1) + 1)
  9. #define HEAP_KEY(i)                                (heap[i].key)3 u: O+ O/ {; {+ T

  10. const int heap_max = 400000;% U9 m4 p4 [+ F4 ^/ N+ s3 ?2 e
  11. struct heap_data {  A$ }. b  n& m& F6 t) L9 Q  b
  12.         int step; // depth
  13.         int key; // f5 o, v. P/ t, \3 _' h" B
  14.         int v; // node8 F/ m+ u1 [/ a: `
  15.         unsigned int path[4]; // path
  16. } heap[heap_max] = {0};" j: r$ A- F) R0 L. j# `# T" U+ K
  17. 9 r. o  ?# L1 S& @  D5 B0 a
  18. class class_heap {
  19. private:
  20.         int heap_size;6 ~1 u9 ~8 s, d$ @

  21.         void swap(heap_data &arg1, heap_data &arg2)
  22.         {
  23.                 heap_data temp_heap;        ' J# i5 _0 ~1 r6 f- \
  24.                 temp_heap = arg1; arg1 = arg2; arg2 = temp_heap;
  25.         }

  26.         int heap_min_up(int node)$ R) v: _, }. G! s6 \7 p/ w
  27.         {: \1 }4 o  @  |8 k2 g3 F5 ]
  28.                 int parent;
  29. - E- R* q. z; a+ q- m; |
  30.                 parent = HEAP_PARENT(node);% ?  I! b) g( P+ y6 V3 w( g
  31.                 if (node > 1 && HEAP_KEY(parent) > HEAP_KEY(node)) {% o5 a1 i/ j8 m! M& w/ h" V6 ~% b
  32.                         swap(heap[parent], heap[node]);. K, R  `8 l: g: K) {
  33.                         return heap_min_up(parent);: t2 F9 `* [2 K* Y4 ~. C- {
  34.                 } 
  35.                 return node;
  36.         }

  37.         int heap_min_down(int node)
  38.         {
  39.                 int left, right;
  40.                 int smallest = node;( l" d  t3 R) u5 x

  41.                 left = HEAP_LEFT(node);! I1 P8 ]+ r- b5 h+ e: D# f
  42.                 right = HEAP_RIGHT(node);- ~  o& P. {- h* N. m
  43.                 if (left <= heap_size && HEAP_KEY(left) < HEAP_KEY(node)) {
  44.                         smallest = left;
  45.                 }9 b3 I. \- X: R% C, i
  46.                 if (right <= heap_size && HEAP_KEY(right) < HEAP_KEY(smallest)) {" C6 o( c1 N5 N; t/ z
  47.                         smallest = right;$ ~" S# E. C! R; ]3 m
  48.                 }
  49.                 if (smallest != node) {
  50.                         smallest = 0;' M/ Y. ^" t- Q  x
  51.                         if (left <= heap_size) {7 A* k  X( e+ l
  52.                                 smallest = left;
  53.                         }  R7 W) p# a2 X
  54.                         if (right <= heap_size && HEAP_KEY(right) < HEAP_KEY(left)) {
  55.                                 smallest = right;
  56.                         }
  57.                         if (smallest) {
  58.                                 swap(heap[smallest], heap[node]);7 L4 D6 I4 E' o. E; T
  59.                                 return heap_min_down(smallest);
  60.                         }/ i" V) y8 e8 N" K; `  d5 f2 e1 k
  61.                 }
  62.                 return node;* o/ ?+ {: ]: {  ?
  63.         }
  64. 2 y. g$ I% L0 B% L( C( F4 w
  65. public:" C: u! Z9 C( v
  66.         class_heap() { heap_size = 0; }2 Y: _4 R# |: C$ n
  67. / j- }* e3 i( }
  68.         void insert(heap_data key)
  69.         {; h/ X& Q' {7 y1 O- ?& G" O
  70.                 heap[++heap_size] = key;/ K+ `2 F( @  r' V! n/ \: {
  71.                 heap_min_up(heap_size);
  72.         }

  73.         heap_data extract_min()  s0 ^: M7 L! t) a8 t
  74.         {
  75.                 heap_data result = heap[1];

  76.                 swap(heap[1], heap[heap_size--]);
  77.                 heap_min_down(1);+ t1 w0 h- ^$ N* h+ h/ k& {3 B, H
  78.                 return result;
  79.         }6 _! L1 z9 g1 I
  80. ( U7 Z+ H! N3 R) R( A8 `% k
  81.         bool empty()
  82.         {9 C$ P( T' x, [6 q: i
  83.                 return (heap_size == 0);
  84.         }1 N4 [# g' t) {: x6 O2 I
  85. };5 |5 y; U6 r: K( e2 x

  86. class_heap heap_table;
  87. bool hash[400000] = {0};- t! b% r! Z, I7 v
  88. const int dstst = 123456780;4 L3 \; X. i6 ?
  89. const int table[10] = {0, 100000000, 10000000, 1000000, 100000, 10000, 1000, 100, 10, 1};. ?, l- h; `. q6 N. @9 `/ s
  90. const int markl[10][5] = {  ' D! W7 i9 @0 N' v. s- Q
  91.         {0, 0, 0, 0, 0},/ b( {- e/ u% m$ `+ l2 q: W
  92.         {0, 2, 0, 0, 4},
  93.         {0, 3, 1, 0, 5},' [- `3 w/ d% q, ?8 }# ?
  94.         {0, 0, 2, 0, 6},9 {; X' `8 w( \5 E$ O. n$ j) ^
  95.         {0, 5, 0, 1, 7},
  96.         {0, 6, 4, 2, 8},
  97.         {0, 0, 5, 3, 9}," t7 B1 ~) i8 \  I- |2 Y
  98.         {0, 8, 0, 4, 0},
  99.         {0, 9, 7, 5, 0},- J! w' f5 C2 l0 g6 z  s
  100.         {0, 0, 8, 6, 0}0 C6 L; x: F, E+ t
  101. };* l9 Z: A. Y" }9 J0 k* a1 ^  a9 L
  102. const char markc[5] = {0, 'r', 'l', 'u', 'd'};
  103. const int fac[10] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320};
  104. 1 S. z2 g1 D8 w0 \6 @+ W
  105. int calc_hash(int key)
  106. {6 j# d4 F& }) \, D- u  |4 J
  107.         int result = 0;! U. v( ~! ^0 B' r& ^6 R+ R
  108.         int decode[10] = {0};' s1 h+ T6 [" P2 g" M2 H

  109.         for (int i = 9; i > 0; --i) {
  110.                 decode[i] = key % 10;
  111.                 key /= 10;# a/ D9 v+ ~9 X3 O
  112.         }7 H' C  h/ u  |) ^) ?
  113.         for (int i = 1; i <= 9; ++i) {+ t4 V3 p2 g, L, `7 q0 m( J
  114.                 for (int j = i + 1; j <= 9; ++j) {# u" `$ T; F% U5 G2 k( ]
  115.                         if (decode[j] < decode[i]) {8 N+ X4 l: I; `5 T3 B) |8 G
  116.                                 result += fac[9 - i];8 [0 G. M$ v8 j
  117.                         }! B( U; g( [- g
  118.                 }                . }8 C5 U3 x1 [1 p2 g4 ?
  119.         }' Q, ?8 i& @0 O% E* D5 I
  120.         return result;4 v% N' W5 z# r; i4 L
  121. }9 z! Q/ v- M8 i& q# i2 M
  122. 1 i1 o, g* g5 Q2 o, M& F, A* Z
  123. int calc_h(int key)
  124. {$ i. F* [' z3 w: K7 @: o
  125.         int key1, key2, result;. _, e# h# y! U# L6 n' t& e
  126. 8 ?. o* w- i  ]$ ]/ U
  127.         key1 = dstst; key2 = key; result = 0;
  128.         for (int i = 1; i <= 9; ++i) {; V6 `6 h; d2 m! z- O
  129.                 if ((key1 % 10 != key2 % 10) && (key2 % 10 != 0)) {% s8 ~3 S  A1 b5 }: y1 q+ l+ S# }
  130.                         ++result;
  131.                 }
  132.                 key1 /= 10;$ z* j+ T4 A0 U3 z2 E; t
  133.                 key2 /= 10;
  134.         }9 h: ]7 [/ m+ q- V
  135.         return result;1 N3 @( D) H. P: F5 l/ @
  136. }

  137. void expand_node(heap_data old_state)
  138. {
  139.         int i, n, k, t, h;+ R! I' T3 R* V! A/ D, i8 Y$ h
  140.         int decode[10] = {0};
  141.         heap_data new_state;
  142. & G, _5 B& d2 h" e2 @/ \
  143.         t = old_state.v;
  144.         for (i = 9; i > 0; --i) {- O. h/ i: [/ ?1 B0 \) V+ k' k
  145.                 decode[i] = t % 10;7 |$ x" v# @1 S5 r% n/ B
  146.                 t /= 10;
  147.                 if (decode[i] == 0) {
  148.                         k = i;& [/ D. D$ s5 h2 E
  149.                 }
  150.         }  P' j1 S* ]$ b: ~( O
  151.         for (i = 1; i <= 4; ++i) {7 b! X% b! m. O+ H1 o
  152.                 n = markl[k][i];* e. C4 N5 O4 ^! Q$ s3 M
  153.                 if (n != 0) {) p8 y1 @0 E$ `, X. z' J3 v+ p- a2 |' I
  154.                         t = old_state.v;
  155.                         t -= table[n] * decode[n];( r$ }* [0 k  [+ |( ]
  156.                         t += table[k] * decode[n];                        ) I0 |  D3 a3 @# c
  157.                         h = calc_hash(t);
  158.                         if (!hash[h]) {
  159.                                 new_state.v = t;. l! t1 f' p( U
  160.                                 new_state.key = old_state.step + calc_h(t);                                
  161.                                 new_state.step = old_state.step + 1;
  162.                                 memcpy(new_state.path, old_state.path, 16);
  163.                                 new_state.path[old_state.step / 16] |= ((i - 1) << old_state.step % 16 * 2);
  164.                                 hash[h] = true;
  165.                                 heap_table.insert(new_state);% H  l4 q0 a8 |5 }) A+ ^9 ^! x
  166.                         }# ?: _9 e& |2 Y' R( H9 k
  167.                 }
  168.         }( A+ A( m8 @. K' C, X5 D. @( m
  169. }
  170. + g, }3 M7 Y; k/ o: m% F
  171. void astar_search()7 E8 [( s4 ^* P+ m, ?1 n
  172. {
  173.         heap_data node;1 a" v6 c# |% A. ?5 ]7 K
  174.         int flag = false;

  175.         while (!heap_table.empty()) {; A7 n6 `+ r! z; p
  176.                 node = heap_table.extract_min();3 y" m- j( U, g% ~1 J5 {( W; Y, v
  177.                 if (node.v == dstst) {" W, ]2 }0 w. S8 w
  178.                         for (int i = 0; i < node.step; ++i) {
  179.                                 cout<<markc[node.path[i / 16] % 4 + 1];
  180.                                 node.path[i / 16] >>= 2;. ]  a- {3 y/ ^' f% I' C
  181.                         }$ n$ `( H6 ?# I' a  T4 K
  182.                         flag = true;
  183.                         break;
  184.                 } else {- X4 f" N" ?5 q
  185.                         expand_node(node);
  186.                 }/ x+ Y$ t) j0 c% W& [* Q6 i: N$ X
  187.         }* ?/ M6 L+ n: m& U
  188.         if (!flag) {
  189.                 cout<<"unsolvable"<<endl;# O7 y4 a1 i. I8 P0 m# C8 f* g8 i
  190.         }4 ~/ i9 \" b) L+ T2 Z# v! p( C
  191. }

  192. int main()
  193. {
  194.         int src = 0;6 r! \5 ]3 {: {
  195.         char ch;% l0 `8 c! ]. {$ O# b+ I" u* u, t; V$ m" y
  196.         heap_data srcst;

  197.         for (int i = 1; i <= 9; ++i) {
  198.                 cin>>ch;5 j3 I, e& Q4 a2 }' G5 i# s
  199.                 if (ch != 'x') {
  200.                         ch -= '0';
  201.                         src += table[i] * ch;
  202.                 }
  203.         }
  204.         hash[calc_hash(src)] = true;9 Z2 s+ N& x& e+ M- e! g
  205.         srcst.v = src; 8 w" Q- z2 g- H1 A, D2 O) d8 z( m
  206.         srcst.key = calc_h(src); ( I+ P  ]3 e7 ]/ }3 R$ x
  207.         srcst.step = 0; 
  208.         memset(srcst.path, 0, 16);
  209.         heap_table.insert(srcst);4 X6 s8 I/ I  o( b% q
  210.         astar_search();
  211.         return 0;
  212. }

 

 

 

 

 

 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    A*算法解决八数码问题(C++)

    A*算法是路径搜索领域中一种非常高效的启发式搜索算法,它在解决八数码问题时表现出色。八数码问题,又称滑动拼图游戏,是一个经典的计算机科学问题,玩家需要通过移动空格来重新排列一组数字,使得它们最终形成一个...

    A*算法解决八数码问题

    人工智能作业,用python实现A*算法搜索解决八数码问题,测试通过

    人工智能A*算法解决八数码问题

    2. **八数码问题**:八数码问题是一个二维网格上的问题,每个格子包含一个数字(0表示空格),目标是通过最少的移动将数字排列成特定顺序。移动规则是每次只能将一个数字沿着上、下、左、右四个方向滑动,空格可以被...

    A*算法解决八数码问题_C#_VS2015

    在实际开发中,八数码问题的A*算法实现需要考虑如何有效地存储和操作棋盘状态,如何实现启发式函数,以及如何用C#的编程特性优化代码结构和性能。VS2015作为开发环境,提供了丰富的调试工具和IDE支持,可以帮助...

    A* (A STAR)算法解决八数码问题

    A* 算法解决八数码问题 A* 算法是一种启发式搜索算法,常用于解决复杂的问题。八数码问题是经典的搜索问题,目的是从初始状态到达目标状态,通过交换空格和数字达到目标状态。A* 算法可以高效地解决八数码问题。 A...

    JAVA实现a*算法八数码问题

    2. **八数码**: 八数码游戏是一种经典的NP完全问题,适合用来展示搜索算法的效果,例如深度优先搜索、宽度优先搜索以及启发式搜索算法如A*。 3. **JAVA**: Java是一种面向对象的编程语言,具有跨平台的特性,常用于...

    用A*算法解决八数码问题

    用A*算法解决八数码问题。给定任意初始状态,若有解,则用A*算法计算出最优路径,并计算所需时间和所需步骤。若无解,则提示无解。

    a*算法实现八数码问题

    《使用A*算法解决八数码问题的深度解析》 八数码问题,又称15拼图或滑块拼图,是一个经典的计算机科学问题,其目标是通过最少的移动次数将一个打乱的数字面板恢复到标准顺序。在这个问题中,我们通常会用到搜索算法...

    Java-A*算法解决八数码问题算法源码

    用A*算法(人工智能或者数据结构与算法课程可能会学)解决八数码问题: 初始状态 目标状态 2 8 3 1 2 3 1 6 4 8 4 7 5 7 6 5 java实现方法在源码中。

    C++实现解决八数码问题的A*算法

    用C++实现的一个解决八数码问题的A*算法。仅供大家学习讨论。

    八数码问题(8皇后问题)的A*算法求解(Python实现)

    **八数码问题(8皇后问题)** 八数码问题,又称为8皇后问题,是一个经典的回溯法和搜索算法的应用实例。在这个问题中,目标是在一个8×8的棋盘上放置八个皇后,使得任何两个皇后都无法在同一行、同一列或同一对角线...

    java A*算法解决八数码、十五数码

    在这个项目中,A*算法被用来解决经典的八数码和十五数码问题,这两个都是著名的滑动拼图游戏。 八数码游戏,也被称为“15拼图”或“滑动拼图”,通常在一个3x3的网格上进行,初始状态有一个空白格和7个数字(1到8)...

    用A*研究八数码

    我自己写了一个WinForm八数码研究软件,研究A*算法。 我用了SQL Server数据库来保存程序运行过程中所产生的状态。所以,执行之前要附加上数据库。 想请教大家一下:(1)A*算法运算过程中产生的大量的状态如何保存...

    A*解决8数码问题Java版

    java版 A*解决八数码问题,注释详细并有博客对相关分析过程讲解 利己利人 http://blog.csdn.net/hiphopmattshi/article/details/7538012

    A*算法解决8数码问题(Python实现)

    算法课程实验、大作业

    八数码问题A*算法代码

    《八数码问题与A*算法实现详解》 八数码问题,又称滑动拼图或15拼图,是一个经典的计算机科学问题,属于图灵完全问题的范畴。它涉及到在一个3x3的网格上,通过空格与其他数字进行交换,使得初始布局最终转变为预设...

    C语言实现:使用A*算法来解决15数码问题

    15数码问题是在4×4方格盘上,放有15个数码,剩下一个位置为空(方便起见,用0表示空),每一空格其上下左右的数码可移至空格。本问题给定初始位置和目标位置,要求通过一系列的数码移动,将初始状态转化为目标状态...

    A*算法实现15数码问题

    通过以上步骤,我们就可以用A*算法有效地解决15数码问题。在提供的压缩包文件中,可能包含了C#语言的源代码实现,这些代码可以帮助我们更好地理解和应用A*算法。通过学习和分析这些代码,我们可以掌握如何将理论知识...

    A*算法求解八数码问题_C#语言

    A*算法求解八数码问题 1、A*算法基本思想: 1)建立一个队列,计算初始结点的估价函数f,并将初始结点入队,设置队列头和尾指针。 2)取出队列头(队列头指针所指)的结点,如果该结点是目标结点,则输出路径,程序...

Global site tag (gtag.js) - Google Analytics