zoukankan      html  css  js  c++  java
  • A*算法

      1 #include <stdlib.h>
      2 #include <stdio.h>
      3 #include <string.h>
      4 #include <math.h>
      5 
      6 
      7 #define NODEEQUAL(a, b) (*((unsigned int *)(a)) == *((unsigned int *)(b)))
      8 //#define GETDIST(a, b) ((abs((a)->x - (b)->x) + abs((a)->y - (b)->y)) * 10)
      9 //#define GETDIST(a, b) ((int)(10 * sqrt((float)((a)->x - (b)->x) * ((a)->x - (b)->x) + ((a)->y - (b)->y) * ((a)->y - (b)->y))))
     10 
     11 #define WORLDSIZEX 8
     12 #define WORLDSIZEY 6
     13 #define OBS ((char)1)
     14 
     15 
     16 
     17 char g_world[WORLDSIZEY][WORLDSIZEX] =
     18 {
     19     {0, 1, 0, 0, 0, 0, 0, 0},
     20     {0, 0, 1, 1, 1, 0, 0, 0},
     21     {0, 1, 1, 0, 1, 0, 0, 0},
     22     {0, 0, 0, 0, 1, 1, 1, 0},
     23     {0, 1, 1, 1, 0, 0, 1, 0},
     24     {0, 0, 0, 0, 1, 0, 0, 0}
     25 };
     26 
     27 typedef struct tag_loc
     28 {
     29     short int x, y;
     30 } loc_t, *loc_ptr;
     31 
     32 
     33 typedef struct tag_node
     34 {
     35     loc_t loc;
     36     int f, g;
     37     struct tag_node* father;
     38     struct tag_node* next;
     39 } node_t, *node_ptr;
     40 
     41 
     42 loc_t g_start = {0, 0};
     43 loc_t g_end = {7, 4};
     44 loc_t g_aroundpts[8] =
     45 {
     46     { -1, -1}, { -1, 0}, { -1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1}, {0, -1}
     47 };
     48 
     49 
     50 void print_path( node_ptr lst )
     51 {
     52     if ( lst )
     53     {
     54         print_path( lst->father );
     55         fprintf( stdout, "(%d,%d) ", lst->loc.x, lst->loc.y );
     56     }
     57 }
     58 
     59 void list_destroy( node_ptr lst )
     60 {
     61     node_ptr p;
     62 
     63     while ( lst )
     64     {
     65         p = lst->next;
     66         free( lst );
     67         lst = p;
     68     }
     69 }
     70 
     71 int get_dist( loc_ptr a, loc_ptr b )
     72 {
     73     unsigned int x, y;
     74 
     75     x = abs( a->x - b->x );
     76     y = abs( a->y - b->y );
     77 
     78     if ( x == 0 )
     79     {
     80         return 10 * y;
     81     }
     82 
     83     if ( y == 0 )
     84     {
     85         return 10 * x;
     86     }
     87 
     88     return ( x + y ) * 7;
     89 }
     90 
     91 node_ptr create_closed( loc_ptr start, loc_ptr end )
     92 {
     93     int h;
     94     node_ptr node;
     95 
     96     if ( start->x < 0 || start->x >= WORLDSIZEX || \
     97             start->y < 0 || start->y >= WORLDSIZEY || \
     98             end->x < 0 || end->x >= WORLDSIZEX || \
     99             end->y < 0 || end->y >= WORLDSIZEY )
    100     {
    101         fprintf( stderr, "起始或目标坐标非法!\n" );
    102         return NULL;
    103     }
    104 
    105     node = ( node_ptr )malloc( sizeof( node_t ) );
    106     if ( node == NULL )
    107     {
    108         fprintf( stderr, "malloc 内存不足!\n" );
    109         return NULL;
    110     }
    111 
    112     memset( node, 0, sizeof( node_t ) );
    113     memcpy( &node->loc, start, sizeof( loc_t ) );
    114     h = get_dist( &node->loc, end );
    115     //node->g = 0;
    116     node->f = node->g + h;
    117     //node->father = NULL;
    118     //node->next = NULL;
    119 
    120     return node;
    121 }
    122 
    123 static void _list_inst( node_ptr* header, node_ptr node )
    124 {
    125     node_ptr h, p;
    126 
    127     h = *header;
    128 
    129     if ( h->f >= node->f )
    130     {
    131         node->next = h;
    132         *header = node;
    133     }
    134     else
    135     {
    136         p = h->next;
    137         while ( p )
    138         {
    139             if ( p->f >= node->f )
    140             {
    141                 h->next = node;
    142                 node->next = p;
    143                 break;
    144             }
    145             h = p;
    146             p = p->next;
    147         }
    148 
    149         if ( p == NULL )
    150         {
    151             h->next = node;
    152             node->next = NULL;
    153         }
    154     }
    155 }
    156 
    157 static int _updt_opened( node_ptr* header, node_ptr node )
    158 {
    159     node_ptr h, p, tmp;
    160 
    161     if ( *header == NULL )
    162     {
    163         tmp = ( node_ptr )malloc( sizeof( node_t ) );
    164         if ( tmp == NULL )
    165         {
    166             fprintf( stderr, "malloc 内存不足!\n" );
    167             return -1;
    168         }
    169 
    170         memcpy( tmp, node, sizeof( node_t ) );
    171         *header = tmp;
    172     }
    173     else
    174     {
    175         h = *header;
    176         while ( h )
    177         {
    178             if ( NODEEQUAL( h, node ) )
    179             {
    180                 break;
    181             }
    182             p = h;
    183             h = h->next;
    184         }
    185 
    186         if ( h == NULL )
    187         {
    188             tmp = ( node_ptr )malloc( sizeof( node_t ) );
    189             if ( tmp == NULL )
    190             {
    191                 fprintf( stderr, "malloc 内存不足!\n" );
    192                 return -1;
    193             }
    194 
    195             memcpy( tmp, node, sizeof( node_t ) );
    196             _list_inst( header, tmp );
    197         }
    198         else
    199         {
    200             if ( h->g > node->g )
    201             {
    202                 if ( h != *header )
    203                 {
    204                     p->next = h->next;
    205                 }
    206                 else
    207                 {
    208                     *header = h->next;
    209                 }
    210 
    211                 memcpy( h, node, sizeof( node_t ) );
    212                 _list_inst( header, h );
    213             }
    214         }
    215     }
    216 
    217     return 0;
    218 }
    219 
    220 int insert_opened( node_ptr* opened, node_ptr closed, node_ptr father, int idx, loc_ptr end )
    221 {
    222     int h;
    223     node_t node;
    224 
    225     // 先创建点
    226     memset( &node, 0, sizeof( node_t ) );
    227 
    228     node.loc.x = father->loc.x + g_aroundpts[idx].x;
    229     node.loc.y = father->loc.y + g_aroundpts[idx].y;
    230 
    231     if ( node.loc.x < 0 || node.loc.x >= WORLDSIZE || \
    232             node.loc.y < 0 || node.loc.y >= WORLDSIZE || \
    233             world[node.loc.y][node.loc.x] == 1 )
    234     {
    235         return 0;
    236     }
    237 
    238     if ( ( idx & 1 ) == 0 && \
    239             ( world[node.loc.y][father->loc.x] == 1 || \
    240               world[father->loc.y][node.loc.x] == 1 ) )
    241     {
    242         return 0;
    243     }
    244 
    245     node.g = ( ( idx & 1 ) ? 10 : 14 ) + father->g;
    246     h = get_dist( &node.loc, end );
    247     node.f = node.g + h;
    248     node.father = father;
    249     //node.next = NULL;
    250 
    251     // 该点是否在closed中
    252     while ( closed )
    253     {
    254         if ( NODEEQUAL( &node, closed ) )
    255         {
    256             return 0;
    257         }
    258         closed = closed->next;
    259     }
    260 
    261 
    262     // 该点不在closed中, 更新opened
    263     if ( _updt_opened( opened, &node ) == -1 )
    264     {
    265         return -1;
    266     }
    267 
    268     return 0;
    269 }
    270 
    271 
    272 int main()
    273 {
    274     int i;
    275     node_ptr opened, closed;
    276     node_ptr curnode;
    277     //创建地图
    278     //.....................
    279 
    280 
    281     // 创建闭集
    282     if ( ( closed = create_closed( &g_start, &g_end ) ) == NULL )
    283     {
    284         return -1;
    285     }
    286 
    287     // 创建开集
    288     opened = NULL;
    289 
    290 
    291     // 起始点
    292     curnode = closed;
    293 
    294     // 运算
    295     while ( !NODEEQUAL( &curnode->loc, &g_end ) ) //终止条件
    296     {
    297         // 从当前点更新开集
    298         for ( i = 0; i < 8; i ++ )
    299         {
    300             if ( insert_opened( &opened, closed, curnode, i, &g_end ) == -1 )
    301             {
    302                 goto err_exit;
    303             }
    304         }
    305 
    306         // 从开集中找到当前最小值, 并加入闭集
    307         if ( opened == NULL )
    308         {
    309             fprintf( stdout, "无路\n" );
    310             goto err_exit;
    311         }
    312         curnode->next = opened;
    313         opened = opened->next;
    314         curnode = curnode->next;
    315         curnode->next = NULL;
    316     }
    317 
    318     print_path( curnode );
    319 
    320     fprintf( stdout, "\ntotal = %d\n", curnode->g );
    321 
    322     list_destroy( opened );
    323     list_destroy( closed );
    324 
    325     return 0;
    326 err_exit:
    327     list_destroy( opened );
    328     list_destroy( closed );
    329     return -1;
    330 }

    一个GUI演示程序ASTARGUI

  • 相关阅读:
    POJ 2533 Longest Ordered Subsequence(裸LIS)
    HDU 1159 Common Subsequence(裸LCS)
    HDU 1160(两个值的LIS,需dfs输出路径)
    HDU 1260 Tickets (普通dp)
    HDU 2859 Phalanx(对称矩阵 经典dp样例)
    2018年暑假ACM个人训练题7 题解报告
    HDU 1060 Leftmost Digit(求N^N的第一位数字 log10的巧妙使用)
    HDU 1071 The area(求三个点确定的抛物线的面积,其中一个点是顶点)
    HDU 1077 Catching Fish(用单位圆尽可能围住多的点)
    HDU 1099 Lottery (求数学期望)
  • 原文地址:https://www.cnblogs.com/javado/p/2986591.html
Copyright © 2011-2022 走看看