用c++代码写一个BIT*算法
时间: 2023-05-23 12:05:37 浏览: 205
BIT*算法是指Binary Indexed Tree Search算法,它是A*算法的改进版本,在搜索树的数据结构中加入了启发式信息以提高搜索的效率。下面是用C语言实现的BIT*算法代码:
```
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <stdbool.h>
#define MAX_SIZE 100 // 定义最大节点数
#define INF 0x3f3f3f3f // 定义无穷大
typedef struct {
int id; // 节点ID
int parent; // 父节点ID
int gn; // 已走路径的耗费
int fn; // 启发式函数值
} Node;
Node node[MAX_SIZE]; // 节点数组
int map[MAX_SIZE][MAX_SIZE];// 地图
int open_list[MAX_SIZE]; // OPEN表
int close_list[MAX_SIZE]; // CLOSE表
int map_size; // 地图大小
int start, goal; // 起点和终点的ID
/* 初始化节点 */
void initNode(int id)
{
node[id].id = id;
node[id].parent = -1;
node[id].gn = INF;
node[id].fn = INF;
}
/* 判断节点是否存在 */
bool isExist(int id)
{
if (id < 0 || id >= map_size) {
return false;
}
if (map[start][id] == INF) {
return false;
}
return true;
}
/* 计算启发式函数值 */
int calcHeuristic(int id)
{
// 此处为简化版的曼哈顿距离
int x1 = id % map_size;
int y1 = id / map_size;
int x2 = goal % map_size;
int y2 = goal / map_size;
return abs(x1 - x2) + abs(y1 - y2);
}
/* 获取OPEN表中估价函数最小的节点 */
int getMinFValue()
{
int min_f = INF;
int min_id = -1;
for (int i = 0; i < map_size; i++) {
if (open_list[i] != -1 && node[i].fn < min_f) {
min_f = node[i].fn;
min_id = i;
}
}
return min_id;
}
/* 更新节点 */
void updateNode(int id, int pid, int gn)
{
if (node[id].gn > gn) {
node[id].gn = gn;
node[id].fn = gn + calcHeuristic(id);
node[id].parent = pid;
for (int i = 0; i < map_size; i++) {
if (open_list[i] == id) {
return;
}
}
open_list[id] = id;
}
}
/* 获取邻接节点 */
void getNeighbor(int id, int neighbor[])
{
int x = id % map_size;
int y = id / map_size;
int count = 0;
if (isExist(id - map_size)) {
neighbor[count++] = id - map_size;
}
if (isExist(id + map_size)) {
neighbor[count++] = id + map_size;
}
if (isExist(id - 1) && (x != 0)) {
neighbor[count++] = id - 1;
}
if (isExist(id + 1) && (x != map_size - 1)) {
neighbor[count++] = id + 1;
}
}
/* 进行搜索 */
void search()
{
// 初始化
for (int i = 0; i < map_size; i++) {
initNode(i);
open_list[i] = -1;
close_list[i] = -1;
}
node[start].gn = 0;
node[start].fn = calcHeuristic(start);
open_list[start] = start;
// 迭代搜索
while (true) {
int id = getMinFValue(); // 获取OPEN表中估价函数最小的节点
if (id == -1) { // 搜索失败
printf("Fail to Find the Path!\n");
return;
}
if (id == goal) { // 搜索成功
printf("Find the Path: ");
int p = goal;
while (true) {
printf("%d ", node[p].id);
if (p == start) {
break;
}
p = node[p].parent;
}
printf("\n");
return;
}
open_list[id] = -1; // 将该节点从OPEN表中删除
close_list[id] = id; // 放入CLOSE表中
int neighbor[4];
getNeighbor(id, neighbor); // 获取邻接节点
for (int i = 0; i < 4; i++) {
int neighbor_id = neighbor[i];
if (neighbor_id == -1 || close_list[neighbor_id] != -1) { // 如果邻接节点不存在或者已经访问过
continue;
}
int gn = node[id].gn + map[id][neighbor_id]; // 计算已走路径的耗费
updateNode(neighbor_id, id, gn); // 更新邻接节点
}
}
}
/* 主函数 */
int main()
{
// 初始化地图
printf("Please Input the Map Size: ");
scanf("%d", &map_size);
printf("Please Input the Map:\n");
for (int i = 0; i < map_size; i++) {
for (int j = 0; j < map_size; j++) {
scanf("%d", &map[i][j]);
if (map[i][j] == 0) {
map[i][j] = INF;
}
}
}
// 输入起点和终点
printf("Please Input the Start and Goal Point:\n");
scanf("%d%d", &start, &goal);
// 进行搜索
search();
return 0;
}
```
说明:该代码实现的是一个简单的二维地图搜索,可以通过输入地图大小和地图内容来进行搜索操作。其中启发式函数使用的是曼哈顿距离,更新节点时使用的是起点到该节点的祖先节点的距离和。在搜索过程中,将OPEN表中估价函数最小的节点移出OPEN表并放入CLOSE表中进行访问,根据邻接节点的距离更新节点,直到搜索成功或者搜索结束。
阅读全文