题目:基于最短路径算法的物流中心选址
要求:包含迪杰斯特拉(Dijkstra)算法和弗洛德(Floyd)算法
最短路算法包含Dijkstra算法和Flody算法,也就是顶点对间的最短路的算法和全部顶点之间的最短路算法。Dijkstra算法在物流的配送运输中能够合理的进行决策和分析而Flody算法比较适合选择合理的物流中心从而使物流的总费用达到最少的效果但是在选择物流中心时,由于一些约束的条件限制, 导致选择物流位置只能在特定的一些区域,同时物流运输的费用与物流运输的距离呈非线性的关系。
已知定点①、②、③、④, 各点间的费用如图所示在四个点中选定一个点为物流的中心使得该点到其他每个点的费用是最小的
基于最短路径算法的物流中心选址。方便物流人员管理物流中心,以及管理人员寻找最短路径。最短路算法包含Dijkstra算法和Flody算法,也就是顶点对间的最短路的算法和全部顶点之间的最短路算法。Dijkstra算法在物流的配送运输中能够合理的进行决策和分析而Flody算法比较适合选择合理的物流中心从而使物流的总费用达到最少的效果但是在选择物流中心时,由于一些约束的条件限制, 导致选择物流位置只能在特定的一些区域,同时物流运输的费用与物流运输的距离呈非线性的关系。
#include
#include
#define MaxVer 100
#define ElemType int
#define VertexType int
typedef struct{//邻接矩阵存储
ElemType Vertices[MaxVer]; //顶点信息的数组
ElemType Edge[MaxVer][MaxVer]; //边信息的数组
int vexnum; //顶点数
int arcnum;//边数
}MGraph;
//最短路径记录矩阵
void CreateMGraph(MGraph &G){
int vnum,anum;
printf("输入顶点数和边数:");
scanf_s("%d%d",&vnum,&anum);
G.vexnum=vnum;
G.arcnum=anum;
printf("\n图的初始化\n");
for(int i=0;i
for(int j=0;j G.Edge[i][j]=0; } } for(int i=0;i printf("输入第%d个顶点的信息:",(i+1)); scanf_s("%d",&(G.Vertices[i])); } printf("\n"); for(int i=0;i printf("输入边的信息(起 终 权):"); int v1,v2,w; scanf_s("%d%d%d",&v1,&v2,&w); //无向图 G.Edge[v1-1][v2-1]=w; // G.Edge[v2][v1-1]=w; }} //打印邻接矩阵的方法 void display2(MGraph &G){ printf(" "); for(int i=0;i<(G.vexnum);i++){ printf("%d ",G.Vertices[i]); } printf("\n"); for(int i=0;i<(G.vexnum);i++)//顶点 { printf("%d ",G.Vertices[i]); for(int j=0;j<(G.vexnum);j++){//边 if(G.Edge[i][j]==0) {printf("∞");} else{ printf("%d ",G.Edge[i][j]);} } printf("\n"); } printf("\n"); } //迪杰斯特拉算法全局变量 bool S[MaxVer]; //顶点集 BOOL是 布尔型变量,也就是逻辑型变量的定义符, int D[MaxVer]; //到各个顶点的最短路径 int Pr[MaxVer]; //记录前驱 //最短路径 - Dijkstra算法:起始遍历点v void Dijkstra(MGraph G, int v) { //初始化 int n = G.vexnum;//n为图的顶点个数 for (int i = 0; i < n; i++) { S[i] = false; //S[]为顶点集 D[i] = G.Edge[v][i]; //D[]为最短路径 Pr[]记录前驱 if (D[i] < M)Pr[i] = v; //将v设为前驱 else Pr[i] = -1; } S[v] = true; int temp=0; //初始化结束,求最短路径,并加入S集 for (int j = 1; j < n; j++) { int min = M; int temp=0; for (int w = 0; w < n; w++) if (!S[w] && D[w] < min) //某点temp未加入s集,且为当前最短路径 { temp = w; min = D[w]; } S[temp] = true; //更新从源点出发至其余点的最短路径 通过temp for (int p = 0; p < n; p++) if (!S[p] && D[temp] + G.Edge[temp][p] < D[p]) { D[p] = D[temp] + G.Edge[temp][p]; Pr[p] = temp; } } } //弗洛伊德算法全局变量 int F_D[MaxVer][MaxVer]; //Floyd的D矩阵 记录最短路径 int P[MaxVer][MaxVer]; //最短路径 - Floyd算法:计算不含负圈的最短路径 bool Floyd(MGraph G) { //初始化 for (int i = 0; i for (int j = 0; j < G.vexnum; j++) { if (i == j) F_D[i][j] = 0; else F_D[i][j] = G.Edge[i][j]; P[i][j] = -1; } //初始化结束,开始运算 for(int k=0;k for (int i = 0; i for (int j = 0; j if (F_D[i][j] > F_D[i][k] + F_D[k][j]) { F_D[i][j] = F_D[i][k] + F_D[k][j]; //F_D[][]记录最短路径值 P[i][j] = k; //P[][]记录最短路径 } bool flag = true; //判断有无负圈 for (int l = 0; l < G.vexnum; l++) for (int j = 0; j < G.vexnum; j++) if (l==j&&F_D[l][j] < 0) { flag = false; break; } return flag; } //输出最短路径 void Path(MGraph G, int v) { if (Pr[v] == -1) return; Path(G, Pr[v]); printf(" %d->",G.Vertices[Pr[v]]); } // 输出Floyd最短路径 v是终点 void F_Path(MGraph G, int v, int w) { printf("->%d ",G.Vertices[P[v][w]]); if (P[v][w] == -1) return; F_Path(G, v,P[v][w]); } //调用最短路径-Dijkstra算法 void Shorted_Dijkstra(MGraph &G) { int vname; printf( "请输入物流中心起点名称: \n"); scanf_s("%d",&vname); for (int i = 0; i < G.vexnum; i++) if (G.Vertices[i] == vname)v = i; if (v == -1) { printf("没有找到该起点! \n"); return; } Dijkstra(G, v);//调用函数 printf("目标中心 最少费用 所走路径 \n"); for (int j = 0; j < G.vexnum; j++) { if (j!= v){ printf("%d\t",G.Vertices[j]); printf("%d\t",D[j]); printf("->%d\n",G.Vertices[j]); } } } //调用最短路径- Floyd算法 void Shorted_Floyd(MGraph &G) { if (Floyd(G))//调用函数 { printf("最少费用 所走路径\n"); for (int i = 0; i for (int j = 0; j < G.vexnum; j++) { if( i == j) continue; printf(" %d\t",F_D[i][j]); printf("%d",G.Vertices[i]); F_Path(G, i,j);//输出路径 printf("%d\n",G.Vertices[j]); } } else { printf("输入的图中含有负圈,不能使用该算法!") ; }}//调用展示最短路径及顶点 void Shorted_Distance(MGraph G) { int t1 = 0, t2; if(Floyd(G)) { for(int k= 0; k < G.vexnum; k++) { t1=F_D[0][k]+t1; //将第一个顶点到其他顶点的总路径赋值给t1 } for(int i = 1; i < G.vexnum; i++) //找出最短路径t1 { t2=0; for (int j = 0;j < G.vexnum; j++) { t2 = F_D[i][j]+t2; } if( t2 < t1 ) { t1 = t2; } } printf("到其它物流中心费用最小的点为 \n"); for(int l = 0; l < G.vexnum; l++) //找出最短路径t1所在起点 { t2=0; for (int m = 0;m < G.vexnum; m++) { t2 = F_D[l][m] +t2; } if( t2 == t1 ) { printf("%d ",G.Vertices[l]); } } printf("\n"); printf("最少费用为 %d \n",t1);} else { printf("无最短路径! \n"); } } //菜单 void menu() { printf("——————————————————————————————\n" ); printf( "|| <欢迎来到最短路径算法> ||\n" ); printf( "|| 1.构造选址模型 ||\n" ); printf( "|| 2.打印模型 ||\n" ); printf( "|| 3.迪杰斯特拉算法 ||\n" ); printf( "|| 4.弗洛伊德算法 ||\n" ); printf( "|| 5.最短路径算法 ||\n" ); printf( "|| 0.退出模拟 ||\n" ); printf("——————————————————————————————\n" ); } int main(){ int choice = 0; MGraph G; while (1) { menu(); printf("请输入你要进行的操作序号:\n"); scanf("%d",&choice); if (choice==0) break; switch (choice) { case 1: printf("邻接矩阵创建图\n");CreateMGraph(G); break; case 2: printf("邻接矩阵为\n");display2(G);; break; case 3:Shorted_Dijkstra(G); break; case 4:Shorted_Floyd(G); break; case 5:Shorted_Distance(G);break; default:printf("输入错误\n"); break; } } return 0; }