Floyd建图是图论中运用最广的算法,也是图论的经典范例。网上此种代码为数不少,但是都比较零散且缺乏封装性,对于新接触的人来说学习起来耗时耗力。由于前段时间开始搞数模,所以我自己将这些代码进行封装整理,便于大家运用学习,绝对原创。
CFloyd_MakeMap.h文件:
/*Floyd算法建立最短路径*/
#ifndef CFloyd_MakeMap_h_
#define CFloyd_MakeMap_h_
#pragma warning(disable : 4786) //屏蔽标准库的编译错误
#include "map"
#include "vector"
#define Maxm 1001
struct Point{
Point(){};
Point(int x,int y)
{
source=x;
target=y;
};
int source; //原城市
int target; //目标城市
friend bool operator < (const struct Point &ls, const struct Point &rs);
};
inline bool operator < (const struct Point &ls, const struct Point &rs)
{return (ls.source < rs.source || (ls.source == rs.source && ls.target < rs.target));}
typedef std::map<Point,std::vector<int> >::iterator Iter_Map;
typedef std::vector<int>::iterator Iter_Vector;
class CFloyd_MakeMap
{
public:
CFloyd_MakeMap();
~CFloyd_MakeMap();
void Initial();
void Floyd_in(char *filename,int size); //读入题目所给数据
void Floyd_Trans_out(char*filename); //将加权图保存到文件
void Floyd_out(char *filename); //将最短路径图保存到文件
void MakeMap(); //建立最短路径图
void MakePoint(int a,int b); //建立最短节点图
void Point_out(char*filename); //将最短节点图保存到文件
std::map<Point,std::vector<int> > m_point; //保存最优节点
int (*m_Dist)[Maxm]; //保存最短距离(从下标1,1开始)
int m_Vertex; //个数
private:
void Root(int p,int q); //递归改变输出次数k(如果有的话)
int (*m_Path)[Maxm]; //保存递归时需要的节点
int *m_Line;
int p,q,k,m;
};
#endif
CFloyd_MakeMap.cpp文件:
#include "CFloyd_MakeMap.h"
#include "fstream"
#include "iostream"
using namespace std;
CFloyd_MakeMap::CFloyd_MakeMap()
{
Initial();
}
CFloyd_MakeMap::~CFloyd_MakeMap()
{
delete []m_Dist;
delete []m_Path;
delete []m_Line;
}
void CFloyd_MakeMap::Initial()
{
m_Path=new int[Maxm][Maxm];
m_Dist=new int[Maxm][Maxm];
m_Line=new int[Maxm];
memset(m_Path,0,sizeof(m_Path));
memset(m_Dist,0,sizeof(m_Dist));
memset(m_Line,0,sizeof(m_Line));
m_Vertex=0;
p=0;q=0;k=0;m=0;
}
void CFloyd_MakeMap::Floyd_in(char*filename,int size)
{
m_Vertex=size;
ifstream fin(filename);
if(!fin)
{
cerr<<"Don't find file for read in!"<<endl;
exit(1);
}
for(p=1;p<=m_Vertex;p++)
{
for(q=1;q<=m_Vertex;q++)
fin >> m_Dist[p][q];
}
fin.close();
}
void CFloyd_MakeMap::MakeMap()
{
for(k=1;k<=m_Vertex;k++) //k为插入的节点
{
for(p=1;p<=m_Vertex;p++)
if (m_Dist[p][k]>0)
for(q=1;q<=m_Vertex;q++)
if (m_Dist[k][q]>0)
{
if (((m_Dist[p][q]>m_Dist[p][k]+m_Dist[k][q])||(m_Dist[p][q]==0))&&(p!=q))
{
m_Dist[p][q]=m_Dist[p][k]+m_Dist[k][q];
m_Path[p][q]=k; //保存插入的节点
}
}
}
}
void CFloyd_MakeMap::Floyd_Trans_out(char* filename)
{
ofstream fout_trans(filename);
if(!fout_trans)
{
cerr<<"Can't set the file!"<<endl;
exit(1);
}
for(p=1;p<=m_Vertex;p++)
{
for(q=1;q<=m_Vertex;q++)
{
fout_trans<<m_Dist[q][p]<<" ";
}
fout_trans<<endl;
}
fout_trans.close();
}
void CFloyd_MakeMap::Floyd_out(char *filename)
{
ofstream fout_result(filename);
if(!fout_result)
{
cerr<<"Can't set the file!"<<endl;
exit(1);
}
for(p=1;p<=m_Vertex;p++)
{
for(q=1;q<=m_Vertex;q++)
{
fout_result<<m_Dist[p][q]<<" ";
}
fout_result<<endl;
}
fout_result.close();
}
void CFloyd_MakeMap::Root(int p,int q) //递归改变输出次数k(如果有的话)
{
if (m_Path[p][q]>0)
{
Root(p,m_Path[p][q]);
Root(m_Path[p][q],q);
}
else
{
this->m_Line[k]=q;
k++;
}
}
void CFloyd_MakeMap::MakePoint(int a,int b)
{
m_point.clear();
for(p=a;p<=b;p++)
{
for(q=a;q<=b;q++)
{
if(p==q)continue;
Point temp_position;
temp_position.source=p;
temp_position.target=q;
vector<int> temp_point;
temp_point.push_back(p);
k=2;
Root(p,q);
for(m=2;m<=k-1;m++)
temp_point.push_back(m_Line[m]);
m_point.insert(make_pair(temp_position,temp_point));
}
}
}
void CFloyd_MakeMap::Point_out(char* filename)
{
ofstream fout_point(filename);
if(!fout_point)
{
cerr<<"Can't set file to save!"<<endl;
exit(1);
}
Iter_Map iter;
Iter_Vector iter_temp;
for(iter=m_point.begin();iter!=m_point.end();++iter)
{
fout_point<<iter->first.source<<"->"<<iter->first.target<<" 路程为:"
<<m_Dist[iter->first.source][iter->first.target]<<endl;
for(iter_temp=iter->second.begin();iter_temp<iter->second.end();++iter_temp)
fout_point<<*iter_temp<<" ";
fout_point<<endl<<endl;
}
fout_point.close();
}
main.cpp测试文件:
//
// main.cpp
// CFloyd_MakeMap
//
// Created by yaoshun on 13-6-10.
// Copyright (c) 2013年 yaoshun. All rights reserved.
//
#include <iostream>
#include "time.h"
#include "CFloyd_MakeMap.h"
using namespace std;
int main(int argc, const char * argv[])
{
//计时
clock_t timeBegin, timeEnd;
timeBegin = clock();
CFloyd_MakeMap Floyd_map;
Floyd_map.Floyd_in("data1.txt", 919);
//将邻接矩阵翻转输出
Floyd_map.Floyd_Trans_out("Floyd_Trans.xls");
//建立Floyd图
Floyd_map.MakeMap();
//建立详细Floyd路径信息
Floyd_map.MakePoint(1,34);
//将结果保存输出
Floyd_map.Floyd_out("Floyd_Result.xls");
Floyd_map.Point_out("Floyd_path.out");
timeEnd = clock();
cout<<"花费的总时间为:"<<(double)(timeEnd-timeBegin)/ CLOCKS_PER_SEC<<"秒"<<endl;
system("pause");
return 0;
}
欢迎大家交流讨论改错。