草草实现的随机图产生器(邻接矩阵)和最短路径算法
来源:互联网 发布:2012sql安装包百度云 编辑:程序博客网 时间:2024/06/10 18:55
好久没有实现数据结构算法方面的东西了,前天晚上心血来潮写了这个随机图产生函数并实现了最短路径算法Dijkstra怀念一下已经远去的大学生活!对于图的生成要注意几个方面1)没有自回路,也就是说邻接矩阵的主对角线元素要全部为0;2)本程序产生的都是有向图,如果是无向图那么这个矩阵是关于对角线对称的,可以通过生成上(下)三角阵然后对称拷贝的方式生成.
比较凌乱,其中一些安全性判断代码可以放到一个函数里让程序看起来更简洁些。
/*********************************************
* File: DIJKSTRA.CPP *
* Author: Lute *
* Date: Jan, 23nd, 2005 *
* Desc: We will provide a impliention *
* of Random Graph Generator and *
* the Dijkstra Algorithm *
*********************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h> //for function memset()
#include <sys/time.h> //for function time(), as random seed. If you are using
//VS6.0, replace it as #include<time.h>
#define INFINITE 1000000
#define ALLKNOWN -2
#define MIN(a, b) (a>b?b:a)
//definition of the node of the graph
struct node{
int id; //the id of the node
int data; //the data store in node
bool known; //is known? reserve for some algorithm
};
typedef struct node Node;
//definition of the Graph structure
struct graph{
int num; //the number of node
Node* gnode; //pointer to the graph node list
int* ajcent; //pointer to the ajacent matrix, and we will store n*n
//edges'infomation in one-dimension array
};
typedef struct graph Graph;
Graph* GenRandGraph(int nodenum)
{
int i;
int adjcentnum = nodenum*nodenum;
//initialize the graph
Graph* graph = NULL;
graph = (Graph*)malloc(sizeof(Graph));
memset(graph, 0, sizeof(Graph));
if(!graph)
{
printf("GenRandGraph 1:Not enough memory to allocate!/n");
return NULL;
}
graph->num = nodenum;
graph->gnode = (Node*)malloc(sizeof(Node)*nodenum);
graph->ajcent = (int*)malloc(sizeof(int)*adjcentnum);
if(!graph->gnode)
{
printf("GenRandGraph 2:Not enough memory to allocate!/n");
free(graph); //before return we must to set what we have free!
graph = NULL;
return NULL;
}
if(!graph->ajcent)
{
printf("GenRandGraph 3:Not enough memory to allocate!/n");
free(graph->gnode);
graph->gnode = NULL;
free(graph);
graph = NULL;
return NULL;
}
//Random Seed
srand(time(NULL));
for(i=0; i<nodenum; i++)
{
graph->gnode[i].id = i;
graph->gnode[i].data = rand()%10;
graph->gnode[i].known = false;
}
for(i=0; i<adjcentnum; i++)
graph->ajcent[i] = (rand()%2)*(rand()%10);
//And the graph shuld not contain the self-loop struct so...
for(i=0; i<nodenum; i++)
graph->ajcent[i*nodenum+i] = 0;
return graph;
}
//Free all momory allocated for the graph, the
void DeleteGraph(Graph* graph)
{
if(!graph)
return;
if(graph->gnode)
{
free(graph->gnode);
graph->gnode = NULL;
}
if(graph->ajcent)
{
free(graph->ajcent);
graph->ajcent = NULL;
}
free(graph);
graph = NULL;
}
//Printing the content of the nodes and the Adjacent Matrix of the Graph
void PrintGraph(Graph* graph)
{
int i, adjacentnum;
if(!graph)
{
printf("PrintGraph 1:Graph is NULL/n");
return;
}
//Print info of nodes/Vertice
if(graph->gnode){
printf("Graph Node:");
for(i=0; i<graph->num; i++)
printf("%d-%d ", graph->gnode[i].id, graph->gnode[i].data);
}
//Print Adjacent Matrix
if(graph->ajcent){
adjacentnum = graph->num*graph->num;
printf("/n/nAjacent Matrix:/n");
for(i=0; i<adjacentnum; i++)
{
if(i%graph->num==0)
printf("/n");
printf("%d ", graph->ajcent[i]);
}
printf("/n");
}
}
//Set the Weight from vertex i to vertex j
bool SetEdgeWeight(int i, int j, int weight, Graph* graph)
{
//Graph is NULL?
if(!graph)
{
printf("SetEdgeWeight 1: Graph is NULL!/n");
return false;
}
//Graph have been initialized?
if(graph->num == 0 || !graph->gnode || !graph->ajcent)
{
printf("SetEdgeWeight 2: Graph is not initialized!/n");
return false;
}
//Parament invaild? and you notice that i==j is an condition in if(...)
//since our graph should not contian self-loop
if(i<0 || j<0 || i>=graph->num || j>=graph->num || i==j)
{
printf("SetEdgeWeight 3: Invalid verter number!/n");
return false;
}
graph->ajcent[i*graph->num+j] = weight;
return true;
}
//Get Weight from the edge (i j)
int GetEdgeWeight(int i, int j, Graph* graph)
{
//Is graph NULL?
if(!graph)
{
printf("GetEdgeWeight 1:Graph is NULL/n");
return -1;
}
//Have graph been initialized?
if(graph->num == 0 || !graph->gnode || !graph->ajcent)
{
printf("GetEdgeWeight 2:Graph is not initailized!/n");
return -1;
}
//Is the parameters invaild?
if(i<0 || j<0 || i>=graph->num || j>=graph->num)
{
printf("GetEdgeWeight 3:Invalid Parameters!/n");
return -1;
}
return graph->ajcent[i*graph->num+j];
}
/*******Function Below for Dijkstra algorithm**********/
//Have this node been known?
bool IsKnown(int i, Graph* graph)
{
//Is graph NULL?
if(!graph)
{
printf("IsKnown 1:Graph is NULL/n");
return -1;
}
//Have graph been initialized?
if(graph->num == 0 || !graph->gnode || !graph->ajcent)
{
printf("IsKnown 2:Graph is not initailized!/n");
return -1;
}
//Is the parameters invaild?
if(i<0 || i>=graph->num)
{
printf("IsKnown 3:Invalid Parameters!/n");
return -1;
}
return graph->gnode[i].known;
}
//Set graph node as known
bool SetKnown(int i, Graph* graph)
{
//Is graph NULL?
if(!graph)
{
printf("SetKnown 1:Graph is NULL/n");
return false;
}
//Have graph been initialized?
if(graph->num == 0 || !graph->gnode || !graph->ajcent)
{
printf("SetKnown 2:Graph is not initailized!/n");
return false;
}
//Is the parameters invaild?
if(i<0 || i>=graph->num)
{
printf("SetKnown 3:Invalid Parameters!/n");
return false;
}
graph->gnode[i].known = true;
return true;
}
//Get a node which is not know and have the minimum path weight
int GetMinUnkown(int *path, Graph* graph)
{
int i;
int min=INFINITE, minnode=ALLKNOWN;
//Is graph NULL?
if(!graph)
{
printf("GetMinUnkown 1:Graph is NULL/n");
return -1;
}
//Have graph been initialized?
if(graph->num == 0 || !graph->gnode || !graph->ajcent)
{
printf("GetMinUnkown 2:Graph is not initailized!/n");
return -1;
}
if(!path)
{
printf("GetMinUnkown 3:path is NULL/n");
return -1;
}
for(i=0; i<graph->num; i++)
if(!IsKnown(i, graph) && path[i]<min)
{
min = path[i];
minnode = i;
}
return minnode;
}
//Dijkstra Algorithm for single node shortest-path finding
bool Dijkstra(int i, Graph* graph)
{
int *path = NULL;
int j, temp, minnode=i, k;
//Is graph NULL?
if(!graph)
{
printf("Dijkstra 1:Graph is NULL/n");
return false;
}
//Have graph been initialized?
if(graph->num == 0 || !graph->gnode || !graph->ajcent)
{
printf("Dijkstra 2:Graph is not initailized!/n");
return false;
}
//Is the parameters invaild?
if(i<0 || i>=graph->num)
{
printf("Dijkstra 3:Invalid Parameters!/n");
return false;
}
path = (int*)malloc(sizeof(int)*graph->num);
if(!path)
{
printf("Dijkstra 4:Not enough memory to allocate!/n");
return false;
}
//Initial
for(j=0; j<graph->num; j++)
{
temp = GetEdgeWeight(i, j, graph);
if(temp)
path[j] = temp;
else
path[j] = INFINITE;
}
path[i] = 0;
SetKnown(i, graph);
for(j=0; j<graph->num; j++)
{
minnode = GetMinUnkown(path, graph);
if(minnode != ALLKNOWN && minnode !=-1)
{
SetKnown(minnode, graph);
for(k=0; k<graph->num; k++)
{
temp = GetEdgeWeight(minnode, k, graph);
if(temp!=0 && temp!=-1 && k!=minnode )
path[k] = MIN(path[k], path[minnode]+temp);
}
}
}
printf("/n/nShortest path:/n");
for(j=0; j<graph->num; j++)
{
if(j%4==0)
printf("/n");
printf("%3d-%-3d:%d ", i, j, path[j]);
graph->gnode[j].known = false;
}
printf("/n");
return true;
}
int main()
{
Graph* pgraph = GenRandGraph(36);
if(!pgraph)
{
printf("Can not Generate random graph!/n");
return -1;
}
PrintGraph(pgraph);
Dijkstra(10, pgraph);
DeleteGraph(pgraph);
system("pause");
return 0;
}
- 草草实现的随机图产生器(邻接矩阵)和最短路径算法
- 图的邻接矩阵表示与最短路径算法( Dijkstra )代码实现
- 最短路径算法之Dijkstra算法(邻接矩阵实现)
- 基于邻接矩阵存储的图的最短路径问题(Dijkstra算法)
- 最短路径(邻接矩阵)-Dijkstra算法
- Dijkstra算法-最短路径-邻接矩阵表示
- 最短路径(二)—Dijkstra算法(通过边实现松弛:邻接矩阵)
- 弗洛伊德算法求图中顶点间的最短路径 【图的邻接矩阵】
- 最短路径的部分算法实现和复杂度
- floyd最短路径算法的实现
- A*算法的最短路径实现!
- Dijkstra算法的最短路径实现
- dijkstra最短路径算法的实现
- 图的最短路径算法(Dijkstra,Floyd)的实现
- 无向图的最短路径算法(队列实现 )
- 关于最短路径图算法实现的问题
- C语言实现图的最短路径Dijkstra算法
- C语言实现图的最短路径Floyd算法
- 如何撰写sms产品方案
- 凌晨2:30 睡不找,仍在思考网站数据库的构建
- 猫的网站,设计的不错
- WINDOWS最新操作系统LONGHORN呼之欲出
- 世界500强企业网站
- 草草实现的随机图产生器(邻接矩阵)和最短路径算法
- Delphi指针(出处不详)
- DELPHI基础开发技巧(还没看#-_-)
- WTL New group
- 我觉得“很久没有写些什么了”都成了我blog的惯用标题了,很少来维护的原因!
- 网上找到的一篇java笔试文章
- 新年快乐---关于C# 的小笑话
- C#生成PDF文档
- Thinking in Current Programming Way