图搜索算法

很多游戏、实际问题等的结构都和图有关,在图结构中寻找最优解也就是在图结构中进行搜索。有搜索自然就有广度优先、深度优先和启发式搜索三种方式。

广度优先

顾名思义,先从广度开始:检查完一个结点的全部后继结点才会开始搜索新的结点的后继结点。在实际实施过程中,经常使用队列结构来存储访问结点(先进先出)
一般使用CLOSED表存储已经访问过的结点,使用OPEN表存储待访问的结点列表。以下是C语言队列实现方式,基本操作包括初始化、入队、出队、判空等。

#define MAX_QUEUE_SIZE 1000
#define OK 1
#define ERROR 0

typedef int Status;

struct Queue{
	ElemType Elem[MAX_STACK_SIZE];
	int front;
	int rear;
	int length;
}; 

Status InitQueue(struct Queue &Q)
{
	Q.front=0;
	Q.rear=0;
	Q.length=0;
	return OK;
}

bool QueueEmpty(struct Queue Q)
{
	return (Q.length==0);
}

Status EnQueue(struct Queue &Q, ElemType e)
{
	if(Q.length>=MAX_QUEUE_SIZE)
		return ERROR; 
	Q.Elem[Q.rear]=e;
	Q.rear=(Q.rear+1)%MAX_QUEUE_SIZE;
	Q.length++;
	return OK; 
}

Status DeQueue(struct Queue &Q, ElemType &e)
{
	if(Q.length==0)
		return ERROR;
	e=Q.Elem[Q.front];
	Q.front=(Q.front+1)%MAX_QUEUE_SIZE;
	Q.length--;
	return OK; 
}

深度优先

顾名思义,访问完一个结点的全部后继(一路走到底)然后再开始走新路。同样需要两个表来记录待访问结点和已访问结点,此时使用的是栈结构先进后出
以下是C语言栈结构实现方式,包括初始化、判空、入栈、出栈等。

struct Stack{
	ElemType Elem[MAX_STACK_SIZE];
	int top;
}; 

Status InitStack(struct Stack &S)
{
	S.top=0;
	return OK;
}

bool StackEmpty(struct Stack S)
{
	if(S.top==0)
		return true;
	else
		return false;
}

Status Push(struct Stack &S, ElemType e)
{
	if(S.top>=MAX_STACK_SIZE)
		return ERROR;
	S.Elem[S.top]=e;
	S.top++;
	
	return OK;
}

Status Pop(struct Stack &S, ElemType &e)
{
	if(S.top==0)
		return ERROR;
	e=S.Elem[S.top-1];
	S.top--;
	
	return OK;
}

A算法和A*算法

上述提及的两种算法是组织全搜索的方式,顺序是固定的,实际搜索时灵活性不太好。采用启发式的方法搜索可以大大加快搜索速率,搜索空间比较好的时候也可以很快找到优质解。
A算法是增加节点信息量,加入当前结点到达目标结点的估计费用(被称为启发函数),增加一个排序的过程,每次选择离目标更近的结点进行扩展。
A*算法在A算法的基础上还增加了原始结点到当前结点的路径费用,来丰富启发函数的内容,同样增加了一个排序的过程,每次选择启发值最小的结点进行扩展。

代码实现逻辑如下

1. 初始化存储未访问和已访问结点列表,分别为初始点和空集。
2. 判断当前结点是否为目标结点,不是则继续扩展。
3. 扩展结点,根据启发函数值进行对结点进行排序(排序的时候要记清楚该结点的父结点,方便之后寻找最短路径)。之后根据当前路径访问后继结点重复2-3步。

C语言代码实现如下,包括初始化、判空、排序、入“队”、出“队”

posted @ 2021-11-08 20:29  芋圆院长  阅读(346)  评论(0编辑  收藏  举报