人工智能A*算法C实现

这篇博客详细介绍了如何使用C语言实现A*搜索算法。作者首先阐述了实验背景和A*算法的基本原理,接着讲解了算法的设计过程,包括OPEN和CLOSED表的使用,以及如何根据F(n)值选择节点。文章提到了使用结构体表示节点和边,并通过六个函数来管理节点的开放和关闭状态,以及进行节点的后继结点分析和排序。最后,作者提供了算法的伪代码部分。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

实验前,其实是想创建三个文件,如C++ primer plus中的,一个头文件,一个函数的实现文件,一个是具体使用的文件,但这样有点问题没解决,只好都放在一个文件当中。
一、实验内容
对下图所示的状态空间图用A*算法进行搜索:
其中A为起始节点,E为目标节点,各节点的启发值表示在括号内。
这里写图片描述

二、实验设计(原理分析及流程)
A* 是启发式搜索算法。该算法创建两个表:OPEN(类似于回溯算法中的NSL,它列出已经产生但其孩子还未被分析的状态)和CLOSED(记录已经分析了的状态,为回溯算法中的DE与SL列表的联合)。
算法预先将初始节点放入OPEN表,从初始节点开始分析,若该节点是目标节点,则成功并返回.否则,分析初始节点的每个子节点,通过比较它们的F(n)函数值以及是否在OPEN,CLOSED表中来进行节点在这两个表的移动,之后对OPEN表中的子节点按F(n)大小进行排序,下一次循环选取OPEN表的第一个节点进行分析,直到最后选取到目标节点结束算法.
算法以每次循环从OPEN表中选取的节点为目标路径的节点,我将它们用一个静态数组存储起来,最后打印数组中的节点得到答案.
我的算法使用了两个结构体,分别代表节点,其成员包括:名字,FN,GN,HN;边,其成员包括:第一个节点,第二个节点,后继结点,权重。
使用六个函数,其中两个为节点进出OPEN表,两个为节点进出CLOSED表,一个为分析选取节点的后继结点的函数,还有一个使用插入排序对OPEN表的节点进行排序。
伪代码:

Best_First_Search()
{
Open = [起始节点]; Closed = [];
while ( Open表非空 )
{
从Open中取得一个节点X,并从OPEN表中删除。
if (X是目标节点)
{
求得路径PATH;返回路径PATH;
}
for (每一个X的子节点Y)
{
if( Y不在OPEN表和CLOSE表中 )
{
求Y的估价值;并将Y插入OPEN表中;//还没有排序
}
else
if( Y在OPEN表中 )
{
if( Y的估价值小于OPEN表的估价值 )
更新OPEN表中的估价值;
}
else //Y在CLOSE表中
{
if( Y的估价值小于CLOSE表的估价值 )
{
更新CLOSE表中的估价值;
从CLOSE表中移出节点,并放入OPEN表中;
}
}
将X节点插入CLOSE表中;
按照估价值将OPEN表中的节点排序;
}//end for
}//end while
}//end func

代码:

// A*算法实现
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <stdbool.h>
#define NodeNum 8
#define EdgeNum 11
#define MaxNodeNum 4

// edges and nodes structures
struct Edge
{
    int Weight;
    char FirstNode;
    char SecondNode;
    char Successor;
};

struct Node
{
    char name;
    int HN;
    int GN;
    int FN;
    //struct Edge LEdge[];
};

int ReFromOpen ( struct Node a, struct Node * OPEN )
{
    int i = 0, j, k;
    printf ( "Remove %c from the OPEN list!\n", OPEN->name );
    while ( OPEN[i].name != 0 && OPEN[i].name != a.name )
        i++;
    if ( OPEN[i+1].name == 0 )
        {
            OPEN[i].name = 0, OPEN[i].HN = 0, OPEN[i].GN = 0, OPEN[i].FN = 0;
            return 1;
        }
    else
    {
        for ( k = i; OPEN[k].name !=0; k++ ) // the total of nodes in OPEN
            ;
        for ( j = k-1; j > i; j-- ) // assignment
             OPEN[j-1].name = OPEN[j].name, OPEN[j-1].FN = OPEN[j].FN,
                      OPEN[j-1].GN = OPEN[j].GN, OPEN[j-1].HN = OPEN[j].HN;
        OPEN[k-1].name = 0, OPEN[k-1].HN = 0, OPEN[k-1].GN = 0, OPEN[k-1].FN = 0;
    }
    return 1;
}

int ReFromClosed ( struct Node a, struct Node * CLOSED )
{
    int i = 0, j, k;
    printf ( "Remove %c from the CLOSED list!\n", CLOSED->name );
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值