求A* 算法C语言源程序

求A* 算法C语言源程序,第1张

#include <string.h>

#include <stdio.h>

#include <malloc.h>

#include <time.h>

#define NULL 0

const int nmax = 200

const int nend = 99 /*终点坐标的代表点*/

static char achar[10][10]

static int npayo = 0 /*0 表示空 1为非空*/

static int npayc = 0 /*0 表示空 1为非空*/

static int npay_x = 0/*起点*/

static int npay_y = 0

static int nend_x = 9/*终点*/

static int nend_y = 9

static int nnewpay_x

static int nnewpay_y

static int ndian = 101

static int nh

static long i = 10000000L

struct Spaydian

{

int ng

int nf /*路径评分*/

int nmy_x/*自己位置*/

int nmy_y

int nfatherx /*父节点*/

int nfathery

int nflag /* 0 wei O1 wei @ */

}

static struct Spaydian spaydian[200]

/* open close list 表 */

typedef struct spaylist

{

int n_f

int n_x

int n_y

int nfather_x

int nfather_y

struct spaylist *next

}

static struct spaylist *open_list, *close_list

static void smline()

static int sjudge(int nx,int ny,int i) /*判断在第nx列ny行向第i个方向走是否可以,可以返回1否则返回0。

i=1表示向右,2表示向下,3表示向左,4表示向上*/

static void spath()

static void spayshow(int nxx,int nyy)

static int sifopen( int nx,int ny) /*判断点是否在 open 表上*/

static int sifclose(int nx,int ny) /*判断点是否在 close 表上*/

static int snewx(int nx,int i)

static int snewy(int ny,int i)

static spaylist *creat() /*建立链表*/

static spaylist *del(spaylist *head,int num_x,int num_y) /*删除链表的结点*/

static spaylist *snewdianx(spaylist *head)/*新的点*/

static spaylist *snewdiany(spaylist *head)

static spaylist *insert(spaylist *head,int ndian) /* 点插入链表 */

static spaylist *srebirth(spaylist *head,int ndian) /*更新表*/

int main()

{

FILE *fp

char ach

int ni = 0 /*统计个数*/

int nii = 0 /*achar[nii][njj]*/

int njj = 0

if ((fp=fopen("route.txt","rt")) == NULL) /* 判断打开文件是否为空 */

{

printf("文件为空!~\n")

return 0

/* exit(1)*/

}

ach = fgetc(fp)

while(ach != EOF)

{

if(ach == 'O' || ach == '@')/*当值为@或O时候*/

{

spaydian[ni].ng = 0

spaydian[ni].nf = nmax

spaydian[ni].nmy_x = njj

spaydian[ni].nmy_y = nii

spaydian[ni].nfathery = -1

spaydian[ni].nfatherx = -1

if(ach == '@')

{

spaydian[ni].nflag = 1

}

else if(ach == 'O')

{

spaydian[ni].nflag = 0

}

ni++

achar[nii][njj] = ach

njj++

if(njj == 10)

{

nii++

njj = 0

}

} /*end if*/

ach = fgetc(fp)

}/*end while*/

smline() /* a*算法 */

fp=fopen("answer.txt","w")

for(int i=0i<10i++ )

{ for(int j=0j<10j++ )

{

printf("%c",achar[i][j])

if(j==9)

printf("\n")

fprintf(fp,"%c",achar[i][j])

if (j==9)

fprintf(fp,"\n")

}

}

fclose(fp)

return 0

}

/* a* 算法 */

static void smline()

{ close_list = open_list = NULL

open_list = creat()

while(open_list != NULL) /* 当open 表不为空时 */

{

open_list = del(open_list,npay_x,npay_y) /*删除open 链表的结点*/

if(npay_x == 9 &&npay_y == 9)

{

achar[9][9] = '='

spath() /*寻找并画出路径*/

break

}

for (int i=1i<=4i++) /*四个方向逐个行走,i=1向右 2向下 3向左 4向上*/

{

if (sjudge(npay_x,npay_y,i))

{

nnewpay_x = snewx(npay_x,i)

nnewpay_y = snewy(npay_y,i)

if(open_list != NULL)

npayo = sifopen(nnewpay_x,nnewpay_y)/*判断点是否在 open 表中*/

else

npayo = 0

if(close_list != NULL)

npayc = sifclose(nnewpay_x,nnewpay_y) /*判断点是否在 close 表中*/

else

npayc = 0

ndian = 10*nnewpay_x+nnewpay_y

if (npayo == 0 &&npayc == 0 ) /*点不在open表也不在close表中*/

{

spaydian[ndian].ng = spaydian[10*npay_x+npay_y].ng + 1 /*更新点的基本信息*/

nh = (nend - ndian)/10 + (nend - ndian)%10

spaydian[ndian].nf = spaydian[ndian].ng+nh

spaydian[ndian].nfathery = npay_y

spaydian[ndian].nfatherx = npay_x

spaydian[ndian].nmy_y = nnewpay_y

spaydian[ndian].nmy_x = nnewpay_x

open_list = insert(open_list,ndian)/*点插入open 表中*/

}

else if (npayo == 1) /*点在open表中*/

{

spaydian[ndian].ng = spaydian[10*npay_x+npay_y].ng + 1

nh = (nend - ndian)/10 + (nend - ndian)%10

if(spaydian[ndian].nf >(spaydian[ndian].ng+nh) &&spaydian[ndian].nf != nmax)

{

spaydian[ndian].nf = spaydian[ndian].ng+nh

open_list = srebirth(open_list,ndian)/*点插入open 表中*/

}

}

else if(npayc == 1) /*新生成的点在close表中*/

{

spaydian[ndian].ng = spaydian[10*npay_x+npay_y].ng + 1

nh = (nend - ndian)/10 + (nend - ndian)%10

if(spaydian[ndian].nf >(spaydian[ndian].ng+nh) &&spaydian[ndian].nf != nmax)

{

spaydian[ndian].nf = spaydian[ndian].ng+nh

close_list = srebirth(close_list,ndian)

close_list = del(close_list,nnewpay_x,nnewpay_y) /*删除close链表的结点*/

open_list = insert(open_list,ndian)/*点插入open 表中*/

}

}/*end else if*/

}/*end if*/

}/*end for*/

close_list = insert(close_list,(10*npay_x+npay_y))/*点插入close 表中*/

if(open_list != NULL)

{

npay_x = open_list->n_x

npay_y = open_list->n_y

}

}/*end while*/

if(open_list == NULL)

{printf("无路可走 \n")}

}

/*建立链表*/

spaylist *creat(void)

{

spaylist *head

spaylist *p1

int n=0

p1=(spaylist*)malloc(sizeof(spaylist))

p1->n_f = 18

p1->n_x = 0

p1->n_y = 0

p1->nfather_x = -1

p1->nfather_x = -1

p1->next = NULL

head = NULL

head=p1

return(head)

}

/*删除结点*/

spaylist *del(spaylist *head,int num_x,int num_y)

{

spaylist *p1, *p2

if(head == NULL)

{

printf("\nlist null!\n")

return (head)

}

p1 = head

while((num_y != p1->n_y ||num_x != p1->n_x )&&p1->next != NULL)

{

p2=p1

p1=p1->next

}

if(num_x == p1->n_x &&num_y == p1->n_y )

{

if(p1==head)

head=p1->next

else

p2->next=p1->next

}

return (head)

}

/*输出*/

static void spath()

{

int nxx

int nyy

nxx = spaydian[nend].nfatherx

nyy = spaydian[nend].nfathery

spayshow(nxx,nyy)

}

/*递归*/

void spayshow(int nxx,int nyy)

{ achar[nxx][nyy] = '='

if( nxx != 0 || nyy != 0 )

{

int nxxyy = 10*nxx+nyy

nxx = spaydian[nxxyy].nfatherx

nyy = spaydian[nxxyy].nfathery

spayshow(nxx,nyy)

}

}

/* 判断周围四个点是否可行 */

static int sjudge(int nx,int ny,int i)

{

if (i==1) /*判断向右可否行走*/

{

if (achar[nx][ny+1]=='O' &&ny<9)

{

return 1

}

else

return 0

}

else if (i==2) /*判断向下可否行走*/

{

if (achar[nx+1][ny]=='O' &&nx<9)

{

return 1

}

else

return 0

}

else if (i==3)/*判断向左可否行走 */

{

if (ny >0&&achar[nx][ny-1]=='O')

{

return 1

}

else

return 0

}

else if (i==4)/*判断向上可否行走 */

{

if (nx >0&&achar[nx-1][ny]=='O')

{

return 1

}

else

return 0

}

else

return 0

}

/* 求新的x点 */

static int snewx(int nx,int i)

{

if(i == 1)

nx = nx

else if(i == 2)

nx = nx+1

else if(i == 3)

nx = nx

else if(i == 4)

nx = nx-1

return nx

}

/* 求新的y点 */

static int snewy(int ny, int i)

{

if(i == 1)

ny = ny+1

else if(i == 2)

ny = ny

else if(i == 3)

ny = ny-1

else if(i == 4)

ny = ny

return ny

}

/*判定点是否在open表中*/

int sifopen(int nx,int ny)

{

spaylist *p1, *p2

p1 = open_list

while((ny != p1->n_y || nx != p1->n_x )&&p1->next != NULL)

{

p2 = p1

p1 = p1->next

}

if(nx == p1->n_x &&ny == p1->n_y)

return 1

else

return 0

}

/*判定点是否在close表中*/

int sifclose(int nx,int ny)

{

spaylist *p1, *p2

p1 = close_list

while((ny != p1->n_y ||nx != p1->n_x )&&p1->next != NULL)

{

p2=p1

p1=p1->next

}

if(nx == p1->n_x &&ny == p1->n_y)

return 1

else

return 0

}

/*插入结点*/

spaylist * insert(spaylist *head,int ndian)

{

spaylist *p0,*p1,*p2

p1=head

p0=(spaylist*)malloc(sizeof(spaylist))

p0->n_f = spaydian[ndian].nf

p0->n_x = spaydian[ndian].nmy_x

p0->n_y = spaydian[ndian].nmy_y

p0->nfather_x = spaydian[ndian].nfatherx

p0->nfather_x = spaydian[ndian].nfathery

p0->next = NULL

if(head==NULL)

{

head=p0

p0->next=NULL

}

else

{

while((p0->n_f >p1->n_f)&&(p1->next!=NULL))

{

p2=p1

p1=p1->next

}

if(p0->n_f <= p1->n_f)

{

if(head==p1)

head=p0

else

p2->next=p0

p0->next=p1

}

else

{

p1->next=p0

p0->next=NULL

}

}

return (head)

}

/* 更新链表 */

spaylist * srebirth(spaylist *head,int ndian)

{

spaylist *p1, *p2

p1=head

while(spaydian[ndian].nmy_x!=p1->n_x&&spaydian[ndian].nmy_x!=p1->n_x&&p1->next!=NULL)

{

p2=p1

p1=p1->next

}

if(spaydian[ndian].nmy_x==p1->n_x&&spaydian[ndian].nmy_x==p1->n_x)

{

p1->n_f = spaydian[ndian].nf

}

return (head)

}

1#include <iostream>

2#include <queue>

3usingnamespace std

4

5struct knight{

6int x,y,step

7int g,h,f

8booloperator<(const knight &k) const{ //重载比较运算符

9return f >k.f

10}

11}k

12bool visited[8][8] //已访问标记(关闭列表)

13int x1,y1,x2,y2,ans //起点(x1,y1),终点(x2,y2),最少移动次数ans

14int dirs[8][2]={{-2,-1},{-2,1},{2,-1},{2,1},{-1,-2},{-1,2},{1,-2},{1,2}}//8个移动方向

15priority_queue<knight>que //最小优先级队列(开启列表)

16

17boolin(const knight &a){ //判断knight是否在棋盘内

18if(a.x<0|| a.y<0|| a.x>=8|| a.y>=8)

19returnfalse

20returntrue

21}

22int Heuristic(const knight &a){//manhattan估价函数

23return (abs(a.x-x2)+abs(a.y-y2))*10

24}

25void Astar(){ //A*算法

26knight t,s

27while(!que.empty()){

28t=que.top(),que.pop(),visited[t.x][t.y]=true

29if(t.x==x2 &&t.y==y2){

30ans=t.step

31break

32}

33for(int i=0i<8i++){

34s.x=t.x+dirs[i][0],s.y=t.y+dirs[i][1]

35if(in(s) &&!visited[s.x][s.y]){

36s.g = t.g +23//23表示根号5乘以10再取其ceil

37s.h = Heuristic(s)

38s.f = s.g + s.h

39s.step = t.step +1

40que.push(s)

41}

42}

43}

44}

45int main(){

46char line[5]

47while(gets(line)){

48x1=line[0]-'a',y1=line[1]-'1',x2=line[3]-'a',y2=line[4]-'1'

49memset(visited,false,sizeof(visited))

50k.x=x1,k.y=y1,k.g=k.step=0,k.h=Heuristic(k),k.f=k.g+k.h

51while(!que.empty()) que.pop()

52que.push(k)

53Astar()

54printf("To get from %c%c to %c%c takes %d knight moves.\n",line[0],line[1],line[3],line[4],ans)

55}

56return0

57}

58


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/yw/11126703.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-13
下一篇2023-05-13

发表评论

登录后才能评论

评论列表(0条)

    保存