超简单的方法实现Floyd算法从而实现医院选址问题

一、问题描述

 

有n个村庄,现要从这n个村庄中选择一个村庄新建一所医院,使其余的村庄到这所医院的距离总体来说较短,设计较合理。

可以用Floyd算法实现。

二、简单声明

N表示村庄所有数量(村庄1,村庄2,村庄3....村庄N)

maps[N][N]是村庄之间的距离,如下图,村庄1到村庄2距离为12,村庄1到村庄6距离为16等。

                                                    图示例 maps[N][N]

shorts[N][N]是存村庄之间最短距离,如下图,村庄1到村庄3最短距离为22,村庄2到村庄6最短距离为7

三、存储数据

存储数据到maps里可以采取读取文件或者自行输入,均可。

1.读取文件数据

文件内容:

1 2 12
1 6 16
1 7 14
2 3 10
2 6 7
3 4 3
3 5 5
3 6 6
4 5 4
5 6 2
5 7 8
6 7 9
0
void Out_datas(){
	FILE *fp;
	fp=fopen("test.txt","r");
	int i,j,cost;
	fscanf(fp,"%d%d%d",&i,&j,&cost);
	while(i!=0){
		maps[i][j]=cost;
		maps[j][i]=cost;
		fscanf(fp,"%d%d%d",&i,&j,&cost);
	}
}

2.自己输入数据

void Scanf_datas(){
	printf("依次输入位置n1和位置n2以及距离(以 0 0 0 结束):\n");
	int i,j,cost;
	while(i!=0){
		scanf("%d%d%d",&i,&j,&cost);
		maps[i][j]=cost;
		maps[j][i]=cost;
	}
}

四、最短距离

Floyd核心算法

void Floyd(){
	int i,j,k,min;
	for(i=1;i<=N;i++){
		for(j=1;j<=N;j++)
			shorts[i][j]=maps[i][j];
	}
	for(k=1;k<=N;k++){
		for(i=1;i<=N;i++){
			for(j=1;j<=N;j++){
				min=shorts[i][j];
				if(i==j) continue;
				if(shorts[i][k]+shorts[k][j]<min){
					min=shorts[i][k]+shorts[k][j];
					shorts[i][j]=min;
				}
					
			}
		}
	}
}

五、其余函数

void Dis_datas(){
	for(int i=1;i<=N;i++){
		for(int j=1;j<=N;j++){
			printf("%3d\t",maps[i][j]);
		}	
		printf("\n");
	}
	printf("\n");
}
void Dis_shorts(){
	for(int i=1;i<=N;i++){
		for(int j=1;j<=N;j++){
			printf("%3d\t",shorts[i][j]);
		}	
		printf("\n");
	}
	printf("\n");
}

六、总代码

#include<stdio.h>
#include<stdlib.h>

#define N 7

int maps[N+1][N+1];
int shorts[N+1][N+1];

void Init_datas(){
	for(int i=0;i<=N;i++){
		for(int j=0;j<=N;j++){
			maps[i][j]=999;
		}
	}
}
void Init_shorts(){
	for(int i=0;i<=N;i++){
		for(int j=0;j<=N;j++){
			shorts[i][j]=999;
		}
	}
}
void Out_datas(){
	FILE *fp;
	fp=fopen("test.txt","r");
	int i,j,cost;
	fscanf(fp,"%d%d%d",&i,&j,&cost);
	while(i!=0){
		maps[i][j]=cost;
		maps[j][i]=cost;
		fscanf(fp,"%d%d%d",&i,&j,&cost);
	}
}
void Scanf_datas(){
	printf("依次输入位置n1和位置n2以及距离(以 0 0 0 结束):\n");
	int i,j,cost;
	while(i!=0){
		scanf("%d%d%d",&i,&j,&cost);
		maps[i][j]=cost;
		maps[j][i]=cost;
	}
}
void Dis_datas(){
	for(int i=1;i<=N;i++){
		for(int j=1;j<=N;j++){
			printf("%3d\t",maps[i][j]);
		}	
		printf("\n");
	}
	printf("\n");
}
void Dis_shorts(){
	for(int i=1;i<=N;i++){
		for(int j=1;j<=N;j++){
			printf("%3d\t",shorts[i][j]);
		}	
		printf("\n");
	}
	printf("\n");
}
void Floyd(){
	int i,j,k,min;
	for(i=1;i<=N;i++){
		for(j=1;j<=N;j++)
			shorts[i][j]=maps[i][j];
	}
	for(k=1;k<=N;k++){
		for(i=1;i<=N;i++){
			for(j=1;j<=N;j++){
				min=shorts[i][j];
				if(i==j) continue;
				if(shorts[i][k]+shorts[k][j]<min){
					min=shorts[i][k]+shorts[k][j];
					shorts[i][j]=min;
				}
					
			}
		}
	}
}
int Choose(){
	int tmp,min=999;
	int all[N+1];
	for(int i=1;i<=N;i++){
		int sum=0;
		for(int j=1;j<=N;j++){
			if(i==j) continue;
			sum=sum+shorts[i][j];
		}
		all[i]=sum;
		if(sum<min){
			min=sum;
			tmp=i;
		}
	}
	for(i=1;i<=N;i++)
		printf("所有到第%d个地方距离为:%d\n",i,all[i]);
	return tmp;
}
int main(){
	int flag=0;
	while(flag!=99){
		printf("**************************************************\n");
		printf("1.读取文件数据\n");
		printf("2.自己输入数据\n");
		printf("3.求每个顶点到其余顶点的最短距离(Floyd算法)\n");
		printf("4.求选择合理的医院\n");
		printf("99.退出\n");
		printf("**************************************************\n");
		printf("请输入:");
		scanf("%d",&flag);
		printf("**************************************************\n");
		switch(flag){
		case 1:
			Init_datas();
			Out_datas();
			Dis_datas();
			break;
		case 2:
			Init_datas();
			Scanf_datas();
			Dis_datas();
			break;
		case 3:
			Init_shorts();
			Floyd();
			Dis_shorts();
			break;
		case 4:
			int tmp;
			tmp=Choose();
			printf("选择%d\n",tmp);
			break;
		case 99:
			break;
		}
	}
	return 0;
}

七、结果分析

输入1,调用Out_datas()函数,先读取文件内容,存到maps[N][N]

输入3,调用Floyd()函数,求得每对村庄之间的最短距离,存入shorts[N][N]

输入4,选择其余村庄到某个村庄总距离最小的村庄,上面数据测得是村庄5,故选村庄5作为医院,可以使得距离总体最小。

  • 8
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
以下是根据题目描述实现的完整代码,注释中有详细解释: ```python # 定义一个带权有向图类 class WeightedDigraph: def __init__(self, vertices): self.vertices = vertices self.num_vertices = len(vertices) self.adj_matrix = [[0] * self.num_vertices for _ in range(self.num_vertices)] def add_edge(self, start_vertex, end_vertex, weight): start_idx = self.vertices.index(start_vertex) end_idx = self.vertices.index(end_vertex) self.adj_matrix[start_idx][end_idx] = weight def floyd(self): # 初始化路径矩阵和距离矩阵 dist = self.adj_matrix.copy() path = [[None] * self.num_vertices for _ in range(self.num_vertices)] for i in range(self.num_vertices): for j in range(self.num_vertices): if dist[i][j] != float('inf') and i != j: path[i][j] = i # Floyd算法核心代码 for k in range(self.num_vertices): for i in range(self.num_vertices): for j in range(self.num_vertices): if dist[i][j] > dist[i][k] + dist[k][j]: dist[i][j] = dist[i][k] + dist[k][j] path[i][j] = path[k][j] return dist, path # 输入各单位名称、距离和频度数据 units = ['A', 'B', 'C', 'D', 'E'] distances = {'A': 3, 'B': 5, 'C': 7, 'D': 9, 'E': 2} frequencies = {'A': 10, 'B': 5, 'C': 3, 'D': 2, 'E': 8} # 构建带权有向图 graph = WeightedDigraph(units) # 添加边及边权值 for start_vertex in units: for end_vertex in units: if start_vertex != end_vertex: weight = distances[end_vertex] * frequencies[end_vertex] graph.add_edge(start_vertex, end_vertex, weight) # 调用Floyd算法求解最短路径 dist, path = graph.floyd() # 找出总权值最小的单位 min_row_sum = float('inf') min_row_idx = -1 for i in range(graph.num_vertices): row_sum = sum(dist[i]) if row_sum < min_row_sum: min_row_sum = row_sum min_row_idx = i optimal_unit = units[min_row_idx] print("市最优选址为:", optimal_unit) ``` 以上代码中,我们定义了一个`WeightedDigraph`类作为带权有向图的数据结构,并实现了添加边及边权值的方法Floyd算法求解最短路径的方法。在构建带权有向图时,我们先根据题目给出的距离和频度数据定义了节点,然后根据每个节点到其他节点的距离和频度计算出边的权值,并将边添加到带权有向图中。 接下来,我们调用Floyd算法求解最短路径,并找出总权值最小的单位,即为市最优选址。最后将市最优选址输出。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值