您的位置:首页 > 其它

狄克斯特拉算法求解村庄问题

2016-01-02 20:59 274 查看
问题:

给定n个村庄之间的交通图。若村庄i和j之间有路可通,则i和j用边连接,边上的权值Wij表示这条道路的长度。现打算在这n个村庄中选定一个村庄建一所医院。编写如下算法:

(1) 求出该医院应建在哪个村庄,才能使距离医院最远的村庄到医院的路程最短。

(2) 求出该医院应建在哪个村庄,能使其它所有村庄到医院的路径总和最短。



完成项目代码如下:

resource.h头文件

//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by Resource.rc

// 新对象的下一组默认值
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE        101
#define _APS_NEXT_COMMAND_VALUE         40001
#define _APS_NEXT_CONTROL_VALUE         1001
#define _APS_NEXT_SYMED_VALUE           101
#endif
#endif


targetver.h头文件

#pragma once

// 包括 SDKDDKVer.h 将定义可用的最高版本的 Windows 平台。

// 如果要为以前的 Windows 平台生成应用程序,请包括 WinSDKVer.h,并将
// WIN32_WINNT 宏设置为要支持的平台,然后再包括 SDKDDKVer.h。

#include <SDKDDKVer.h>


stdafx.h头文件

// stdafx.h : 标准系统包含文件的包含文件,
// 或是经常使用但不常更改的
// 特定于项目的包含文件
//

#pragma once

#include "targetver.h"

#include <stdio.h>
#include <tchar.h>

// TODO:  在此处引用程序需要的其他头文件
#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
using namespace std;

const int MAX_N = 100;//定义最大存储空间
const int INF = 65535;//定义为无穷大

//数据节点
//顶点信息
class Vertex
{
public:
int vername;//顶点名
int number;//顶点下标
};

//图信息
class MatrixGraph
{
public:
int edges[MAX_N][MAX_N];//边
int Tvertex, Tedges;//总顶点,总边数
Vertex vert[MAX_N];//顶点信息
int weight[MAX_N];//边权重
};

class Graph
{
public:

//构造
Graph();
//析构
~Graph();
//读取文件->图信息
void getInfo(string );
//创建图
void CreateGraphMatrix();
//求任意二者间最短距离
void solveMin();
//求解问题
void solveQuestion();

private:
MatrixGraph graph;
string vertex;//顶点
string weight;//权重
string edges[MAX_N];//边
int Tedges;//边数
stringstream sstr;//string类型转换变量
int disMin[MAX_N][MAX_N];//最短距离

//获取下标
int location(MatrixGraph , int );
//初始化邻接矩阵
void InitMatrix();
//初始化距离数组和路径数组
void InitDist();

};


stdafx.cpp文件

// stdafx.cpp : 只包括标准包含文件的源文件
// solveGraphQuestion.pch 将作为预编译头
// stdafx.obj 将包含预编译类型信息

#include "stdafx.h"

// TODO:  在 STDAFX.H 中
// 引用任何所需的附加头文件,而不是在此文件中引用

//构造
Graph::Graph()
{
Graph::InitMatrix();//初始化矩阵
Graph::InitDist();//初始化距离
}

//析构
Graph::~Graph(){}

//搜索下标
int Graph::location(MatrixGraph g, int index)
{
for (int i = 0; i < g.Tvertex; i++)
{
if (index == g.vert[i].number)
{
return i;
}
}
return -1;
}

//邻接矩阵初始化
void Graph::InitMatrix()
{
{
for (int i = 0; i < MAX_N; i++)
{
for (int j = 0; j < MAX_N; j++)
{
graph.edges[i][j] = INF;//初始化为无穷大
}
}
}
}

//村庄间距离初始化
void Graph::InitDist()
{
for (int i = 0; i < MAX_N; i++)
{
for (int j = 0; j < MAX_N; j++)
{
disMin[i][j] = INF;//初始化为无穷大
}
}
}

//读取文件->图信息
void Graph::getInfo(string filename)
{
ifstream readfile;
readfile.open(filename, ios::in);
getline(readfile, vertex);//读取顶点
getline(readfile, weight);//读取权重
//读取边
int i = 0;
while (!readfile.eof())
{
if (getline(readfile, edges[i]).good())//边值正常
{
i++;
}
}
readfile.close();
Tedges = i;//总边数
}

//创建图
void Graph::CreateGraphMatrix()
{
int edge1, edge2;
graph.Tvertex = vertex.length();//顶点数
graph.Tedges = Tedges;//边数

//处理顶点
for (int i = 0; i < graph.Tvertex; i++)
{
//转换
sstr.clear();//清空内存
sstr << vertex[i];//写入一个顶点
sstr >> graph.vert[i].vername;//获取一个顶点
graph.vert[i].number = i;//定义顶点编号
}

//处理边
for (int i = 0; i < graph.Tedges; i++)
{
//转换
sstr.clear();//清空内存
sstr << weight[i];//写入权重
sstr >> graph.weight[i];//获取权重
sstr.clear();
sstr << edges[i][0];//获取一条边始点
sstr >> edge1;
sstr.clear();
sstr << edges[i][1];//获取一条边终点
sstr >> edge2;
int p1 = location(graph, edge1);//获取始点边下标
int p2 = location(graph, edge2);//获取终点边下标
graph.edges[p1][p2] = graph.edges[p2][p1] = graph.weight[i];//写入该边权重->无向
}
}

//求任意村庄间最短距离
void Graph::solveMin()
{
//默认最短距离
for (int i = 0; i < graph.Tvertex; i++)
{
for (int j = 0; j < graph.Tvertex; j++)
{
disMin[i][j] = graph.edges[i][j];
}
}

//求最短距离
for (int k = 0; k < graph.Tvertex; k++)
{
for (int i = 0; i < graph.Tvertex; i++)
{
for (int j = 0; j < graph.Tvertex; j++)
{
if (disMin[i][j]>disMin[i][k] + disMin[k][j])
{
disMin[i][j] = disMin[i][k] + disMin[k][j];//修改最短距离
}
}
}
}
}

//求解问题
void Graph::solveQuestion()
{
int min[MAX_N];//某村庄到其他村庄的最短距离中的最大距离
int totalMin[MAX_N] = { 0 };//某村庄到其他村庄的最短距离之和

//遍历求村庄到其他村庄的最短距离中的最大距离
//以及到其他村庄的最短距离之和
for (int i = 0; i < graph.Tvertex; i++)
{
min[i] = disMin[i][0];//默认距离最大
for (int j = 0; j<graph.Tvertex; j++)
{
//若存在更大值,则更新
if (min[i] < disMin[i][j])
{
min[i] = disMin[i][j];//修改最大值
}

totalMin[i] += disMin[i][j];//距离之和
}
}

//求解问题
int ques_1 = min[0], loc_1 = 0;//问题一最小值以及村庄下标
int ques_2 = totalMin[0], loc_2 = 0;//问题二最小值以及村庄下标

for (int i = 0; i < graph.Tvertex; i++)
{
//存在更小距离
if (ques_1>min[i])
{
ques_1 = min[i];//修改距离
loc_1 = i;//修改村庄下标
}
//存在更小距离之和
if (ques_2 > totalMin[i])
{
ques_2 = totalMin[i];//修改距离
loc_2 = i;//修改下标
}
}

//输出结果
cout << "question 1->村庄标号 " << loc_1 << ", 最短距离 " << ques_1 << endl;
cout << "question 2->村庄标号 " << loc_2 << ", 最短距离 " << ques_2 << endl;
}


solveGraphQuestion.cpp文件

// solveGraphQuestion.cpp : 定义控制台应用程序的入口点。
//
//代码所解决问题说明见readMe.txt

#include "stdafx.h"

int _tmain(int argc, _TCHAR* argv[])
{
Graph g;
g.getInfo("data.txt");//读图
g.CreateGraphMatrix();//创建临接矩阵
g.solveMin();//求所有最短路径
g.solveQuestion();//求解问题
return 0;
}


data.txt文件信息

012345
5873459561
01
02
03
05
12
23
25
34
35
45


运行结果:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: