弗洛伊德算法(自动生成图)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
#include <time.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
clock_t start,finish;
long double duration;
#define MAX_NAME 5 // 顶点字符串的最大长度+1
#define MAX_INFO 20 // 相关信息字符串的最大长度+1
#define INFINITY INT_MAX // 用整型最大值代替∞
#define MAX_VERTEX_NUM 100 // 最大顶点个数
typedef char V ertexType[MAX_NAME]; // 顶点数据类型及长度
typedef enum{DG, DN, AG, AN} GraphKind; // {有向图,有向网,无向图,无向网}
// 邻接矩阵的数据结构
typedef struct
{
int adj; // 顶点关系类型。
对无权图,用1(是)或0(否)表示相邻否;
// 对带权图,则为权值类型
}ArcCell, AdjMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
// 图的数据结构
typedef struct
{
AdjMatrix arcs; // 邻接矩阵
int vexnum, // 图的当前顶点数
arcnum; // 图的当前弧数
GraphKind kind; // 图的种类标志
} MGraph;
typedef int PathMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM][MAX_VERTEX_NUM];
typedef int DistancMatrix[MAX_VERTEX_NUM][MAX_VERTEX_NUM];
// 采用数组(邻接矩阵)表示法,构造有向网G。
//int CreateDN(MGraph *G,FILE *F,FILE *IN)
int CreateDN(MGraph *G,FILE *F)
{
int i,j,k,w,t,m[100];
int n=0;
printf("请输入有向网G的顶点数:"
" \n");
scanf("%d%*c", &(*G).vexnum);
fprintf(F,"%ld\t ",(*G).vexnum);
// fprintf(F,"边数:%ld\t ",(*G).arcnum);
for(i=0;i<(*G).vexnum;++i) // 初始化邻接矩阵
for(j=0;j<(*G).vexnum;++j)
{
if(i==j) (*G).arcs[i][j].adj=0;
else
(*G).arcs[i][j].adj=INFINITY; // 网,边的权值初始化为无穷大}
//自动生成邻接矩阵
for(i=0;i<(*G).vexnum;i++)
{
printf("请输入第%d个数需要产生的边的个数(小于%d):\n",i,(*G).vexnum-2);
scanf("%d",&t);
for(j=0; j < t; ++j)
{
int x=0;
m[j]=int(rand()%(*G).vexnum);
while(x<j&&m[x]!=m[j]) //没找到循环
x=x+1;
if((i!=m[j])&&x==j) //没有找到同样的数或i!=j
{
(*G).arcs[i][m[j]].adj=int(rand()%(100-1))+1;
printf("(*G).arcs[i][m[j]].adj:%d\n",(*G).arcs[i][m[j]].adj);
}
else j=j-1;
}
}
/*
for(k=0;k<((*G).vexnum*(*G).vexnum);++k)
{
i = k/(*G).vexnum;
j = k%(*G).vexnum;
fscanf(IN,"%d",&w);
if(w!=0&&w!=-1) n=n+1;
(*G).arcs[i][j].adj=w; // 有向网,弧的权值为w
if((*G).arcs[i][j].adj==-1)
{
(*G).arcs[i][j].adj=INFINITY;
}
}
(*G).arcnum=n;
printf("n:%d\n",n);
printf("(*G).arcnum:%d\n",(*G).arcnum); */
printf("初始邻接矩阵:\n");
for(i=0;i<(*G).vexnum;i++)
{
for(j=0;j<(*G).vexnum;j++)
printf("%d ",(*G).arcs[i][j].adj);
printf("\n");
}
(*G).kind=DN; //有向网的种类标志
return 1;
}
long double ShortestPath_FLOYD(MGraph G,FILE *F)
{
duration=0;
start=clock();
int i,j,k;
for(k=0;k<G.vexnum;k++)
{
for(i=0;i<G.vexnum;i++)
{
for(j=0;j<G.vexnum;j++)
{
if((G.arcs[i][k].adj)+(G.arcs[k][j].adj)>0)
{
if((G.arcs[i][k].adj)+(G.arcs[k][j].adj)<(G.arcs[i][j].adj))
G.arcs[i][j].adj = G.arcs[i][k].adj+G.arcs[k][j].adj;
}
}
}
/* printf("第%d次邻接矩阵:\n",k);
for(i=0;i<G.vexnum;i++)
{
for(j=0;j<G.vexnum;j++)
printf("%d ",G.arcs[i][j].adj);
printf("\n");
} */
}
finish=clock();
duration=(double)(finish - start)/CLOCKS_PER_SEC;
printf("zuizhong矩阵:\n");
for(i=0;i<G.vexnum;i++)
{
for(j=0;j<G.vexnum;j++)
printf("%6d ",G.arcs[i][j].adj);
printf("\n");
}
for(i=0;i<G.vexnum;i++)
for(j=0;j<G.vexnum;j++)
printf("%d到%d的最短距离为%d\n",i,j,G.arcs[i][j].adj);
return duration;
}
int main()
{
MGraph g;
int i,j;
FILE *f,*out;
char file[10],file2[10];
/*
printf("输入要读入的文件名:\n");
scanf("%s",file2);
if((out=fopen(file2,"r"))==NULL){
printf("can not open the read file2!\n");
exit(0);
} */
printf("输入要生成的文件名:\n");
scanf("%s",file);
if((f=fopen(file,"w"))==NULL){
printf("can not open the file!\n");
exit(0);
}
CreateDN(&g,f);
printf("初始邻接矩阵:\n");
for(i=0;i<g.vexnum;i++)
{
for(j=0;j<g.vexnum;j++)
printf("%11d",g.arcs[i][j].adj);
printf("\n");
}
printf("------\n");
fprintf(f,"\t%f\n",ShortestPath_FLOYD(g,f));
return 0;
}。