main.cpp
#include <stdio.h>
#include <stdlib.h>
#include "function.h"
void main()
{
int maze[ROW][COL] = { 0 };
InitMaze(maze);//初始化迷宫
DrawMaze(maze);//绘制迷宫
AImazeDijkistra(maze);//AI算法最短路径
system("pause");
}
function.h
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 1000
#define ROW 15//行
#define COL 15//列
#define OBS 70//obstacles障碍物 0-100之间 值越小,障碍物越多
typedef int VertexType;//图顶点数据类型
typedef int EdgeType;//图边的数据类型
#define INFINITY 65535//无穷大
struct vertexCur //顶点坐标
{
int i;
int j;
int d;
};
//设置图的邻接矩阵结构
typedef struct
{
//图顶点数组
vertexCur vertex[MAXSIZE];
//图边数组
EdgeType arc[MAXSIZE][MAXSIZE]; //边的值就是权重
int vertexnum, arcnum;
}AdjMarGraph;
//初始化
void InitMaze(int maze[ROW][COL]);
//绘制迷宫
void DrawMaze(int maze[ROW][COL]);
//迷宫地图转换为邻接矩阵
void ChangeAdjMaxGraph(int maze[ROW][COL]);
void AImazeDijkistra(int maze[ROW][COL]);//迷宫寻址最短路径(迷宫+迪杰斯特拉算法算法)
function.cpp
#include <stdio.h>
#include <stdlib.h>
#include "function.h"
#include <Windows.h>
#include<conio.h>
#include <time.h>
//初始化
void InitMaze(int maze[ROW][COL])
{
time_t ts;
unsigned int num = time(&ts);
srand(num);
//maze[0][0] =1;
for (int i = 0; i<ROW; i++)
for (int j = 0; j < COL; j++)
{
int sr = rand() % 100;
if (sr > OBS)//控制迷宫的阻挡数量1-10 值越小,主档数量越多
maze[i][j] = 2;
}
}
//绘制迷宫
void DrawMaze(int maze[ROW][COL])
{
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COL; j++)
{
printf("%4d", maze[i][j]);
}
printf("\n");
}
}
//首先迷宫地图转换成图的邻接矩阵结构再用迪杰斯特拉算法求出最短路径
AdjMarGraph * amg;
void ChangeAdjMaxGraph(int maze[ROW][COL])
{
amg = (AdjMarGraph*)malloc(sizeof(AdjMarGraph));
amg->arcnum = 0;
amg->vertexnum = 0;
vertexCur * p = amg->vertex;
for (int i = 0; i<ROW; i++)//邻接矩阵顶点坐标初始化
for (int j = 0; j < COL; j++)
{
p->i = i;
p->j = j;
p->d = maze[i][j];
p++;
amg->vertexnum++;
}
//初始化边;
for (int i = 0; i<amg->vertexnum; i++)//初始化边值为0
for (int j = 0; j<amg->vertexnum; j++)
{
if (i == j)
amg->arc[i][j] = 0;
else
amg->arc[i][j] = INFINITY;
}
//边赋值,arc的值为边的权重,此时都设置为1
//for(int i=0;i<amg.vertexnum;i++)
for (int j = 0; j < amg->vertexnum; j++)
{
if (amg->vertex[j].d == 0 && amg->vertex[j + 1].d == 0 && ((j + 1) % ROW) != 0)//左右链接,设置邻接矩阵的弧
{
amg->arc[j][j + 1] = 1;
amg->arc[j + 1][j] = 1;
amg->arcnum = amg->arcnum + 2;
}
if (amg->vertex[j].d == 0 && amg->vertex[j + ROW].d == 0 && ((j + 1) % ROW) != 0)//上下链接,设置邻接矩阵的弧
{
amg->arc[j][j + ROW] = 1;
amg->arc[j + ROW][j] = 1;
amg->arcnum = amg->arcnum + 2;
}
}
}
//Dijkistra最短路径
int ShortestPath(int maze[ROW][COL], AdjMarGraph *amg, int begin, int end)
{
int i, min = INFINITY, cur = 0, j;//i=begin设置从那个顶点开始,i=0表示从第一个顶点开始走;
int vertex_weight[MAXSIZE];//下标为当前顶点,值为连接当前顶点的上一个最小权重的顶点,
int path_min[MAXSIZE];//下标为顶点,值为对应顶点到第一个顶点最小路径(最小权重和)
int finish[MAXSIZE];//已经走过的路径,0为未走过,1为走过。
//初始化
for (j = 0; j<amg->vertexnum; j++)
{
vertex_weight[j] = 0;
path_min[j] = amg->arc[begin][j];//第一个开始定点连的其他定点权重
finish[j] = 0;
}
vertex_weight[begin] = 0;
path_min[begin] = 0;
finish[begin] = 1;
//循环查找路径
//int mcur=cur=0;
for (i = 1; i<amg->vertexnum; i++)
{
//从队列中查找最小的
min = INFINITY;
for (int f = 0; f<amg->vertexnum; f++)
min>path_min[f] && !finish[f] ? min = path_min[f], cur = f : 1;//mcur用来保存最小路径的坐标
finish[cur] = 1;
for (int j = 0; j<amg->vertexnum; j++)
{
if (finish[j] != 1 && amg->arc[cur][j] + min<path_min[j])//amg->arc[cur][j]!=0&&amg->arc[cur][j]!=INFINITY&&
{
path_min[j] = amg->arc[cur][j] + min;
vertex_weight[j] = cur;
}
}
}
//打印输出路径
printf("maze(%d,%d)-maze(%d,%d)的最短路径为:\n", amg->vertex[end].i, amg->vertex[end].j, amg->vertex[begin].i, amg->vertex[begin].j);
cur = end;
while (vertex_weight[cur])
{
printf("->maze(%d,%d)\n", amg->vertex[cur].i, amg->vertex[cur].j);
maze[amg->vertex[cur].i][amg->vertex[cur].j] = 1;
cur = vertex_weight[cur];
if (vertex_weight[cur] == 0 && cur != begin)
{
printf("->maze(%d,%d)\n", amg->vertex[cur].i, amg->vertex[cur].j);
maze[amg->vertex[cur].i][amg->vertex[cur].j] = 1;
}
}
printf("->maze(%d,%d)", amg->vertex[begin].i, amg->vertex[begin].j);
maze[amg->vertex[begin].i][amg->vertex[begin].j] = 1;
printf("\n");
DrawMaze(maze);
return 1;
}
void AImazeDijkistra(int maze[ROW][COL])//迷宫寻址最短路径(迷宫+迪杰斯特拉算法算法)
{
ChangeAdjMaxGraph(maze);//迷宫地图转换为邻接矩阵
ShortestPath(maze, amg, ROW*COL-1, 0);
}