floyd_warshallアルゴリズム
7309 ワード
#include <iostream>
#include <map>
#include <memory>
#include <new>
#include <stdexcept>
namespace{
enum : int{
MAXVALUE = 9999
};
}
template<typename T>
class Graph{
private:
std::map<T, std::map<T, int>> graph_; // .
std::map<T, std::map<T, T>> path_; // .
std::map<T, std::map<T, int>> distance_; // .
unsigned int node_number_;
void floyd_warshall()noexcept;
template<typename Ty>
void print_path(const Ty& start_, const Ty& end_);
public:
using map_type = std::map<T, std::map<T, int>>;
using map_iter = typename std::map<T, std::map<T, int>>::const_iterator;
using iter = typename std::map<T, int>::const_iterator;
template<typename Ty, unsigned int N>
Graph(const Ty (&edges)[N][3]);
~Graph();
template<typename Ty>
void print(const Ty& start, const Ty& end);
};
template<typename T>
template<typename Ty, unsigned int N>
Graph<T>::Graph(const Ty (&edges)[N][3])
:node_number_(N)
{
if(N == 0){
throw std::runtime_error(std::string("there is nothing"));
}
/*for(int i=0; i<N; ++i){
for(int j=0; j<N; ++j){
(this->*graph_)[i][j] = (i == j) ? 0 : ::MAXVALUE; // 0.
}
}*/
for(int j =0; j<N; ++j){
(this->graph_)[edges[j][0]][edges[j][1]] = edges[j][2];
}
map_iter first_ = (this->graph_).cbegin();
for(; first_ != (this->graph_).cend(); ++first_){
map_iter second_ = (this->graph_).cbegin();
for(; second_ != (this->graph_).cend(); ++second_){
if(first_->first == second_->first){
(this->graph_)[first_->first][second_->first] = 0;
}else if((this->graph_)[first_->first][second_->first] > 0){
continue;
}else{
(this->graph_)[first_->first][second_->first] = ::MAXVALUE;
}
}
}
std::cout<<"successful constructor
";
/*map_iter iter_first = this->graph_.cbegin();
for(; iter_first != this->graph_.cend(); ++iter_first){
std::cout<<iter_first->first<<": ";
iter iter_second = this->graph_[iter_first->first].cbegin();
for(; iter_second != this->graph_[iter_first->first].cend(); ++iter_second){
std::cout<<iter_second->first<<"--"<<iter_second->second<<" ";
}
std::cout<<std::endl;
}*/
}
template<typename T>
void Graph<T>::floyd_warshall()noexcept
{
if(this->node_number_ == 0){
throw std::runtime_error(std::string("there nothing in graph"));
}
// :
//first_, second_, first_ second_ .
map_iter first_ = (this->graph_).cbegin();
for(; first_ != (this->graph_).cend(); ++first_){
map_iter second_ = (this->graph_).cbegin();
for(; second_ != (this->graph_).cend(); ++second_){
//std::cout<<"dis_: "<<(this->graph_)[first_->first][second_->first]<<std::endl;
this->distance_[first_->first][second_->first] = (this->graph_)[first_->first][second_->first];
this->path_[first_->first][second_->first] = 0;
}
}
/*std::cout<<'
'<<"distance_"<<std::endl;
map_iter x = this->distance_.cbegin();
for(; x != this->distance_.cend(); ++x){
std::cout<<x->first<<": ";
iter y = (this->distance_)[x->first].cbegin();
for(; y != (this->distance_)[x->first].cend(); ++y){
std::cout<<y->first<<"--"<<y->second<<" ";
}
std::cout<<std::endl;
}*/
// third_ forth_ fifth_ . .
map_iter third_ = (this->graph_).cbegin();
for(; third_ != (this->graph_).cend(); ++third_){
map_iter forth_ = (this->graph_).cbegin();
for(; forth_ != (this->graph_).cend(); ++forth_){
map_iter fifth_ = (this->graph_).cbegin();
for(; fifth_ != (this->graph_).cend(); ++fifth_){
/*std::cout<<"i-k:"<<(this->distance_)[forth_->first][third_->first]<<" ";
std::cout<<"k-j:"<<(this->distance_)[third_->first][fifth_->first]<<" ";
std::cout<<"i-j:"<<(this->distance_)[forth_->first][fifth_->first]<<"
"; */
/*std::cout<<"i: "<<forth_->first<<" ";
std::cout<<"j: "<<fifth_->first<<" ";
std::cout<<"k: "<<third_->first<<"
";*/
if((this->distance_)[forth_->first][third_->first]+(this->distance_)[third_->first][fifth_->first] < (this->distance_)[forth_->first][fifth_->first]){
std::cout<<"enter"<<std::endl;
(this->distance_)[forth_->first][fifth_->first] = this->distance_[forth_->first][third_->first] + this->distance_[fifth_->first][third_->first];
(this->path_)[forth_->first][fifth_->first] = third_->first; //path forth_ fifth_ .
}
}
}
}
/*typename std::map<T, std::map<T, T>>::const_iterator begin_ = (this->path_).begin();
for(; begin_ != (this->path_).cend(); ++begin_){
std::cout<<begin_->first<<": ";
typename std::map<T, T>::const_iterator end_ = (this->path_)[begin_->first].cbegin();
for(; end_ != (this->path_)[begin_->first].cend(); ++end_){
std::cout<<end_->first<<"--"<<end_->second<<" ";
}
std::cout<<std::endl;
}*/
}
template<typename T>
template<typename Ty>
void Graph<T>::print(const Ty& start, const Ty& end)
{
this->floyd_warshall();
this->print_path(start, end);
}
template<typename T>
template<typename Ty>
void Graph<T>::print_path(const Ty& start_, const Ty& end_)
{
if(start_ == end_){
throw std::runtime_error(std::string("there is no way"));
}
if(this->path_[start_][end_] == 0){
std::cout<<end_<<" ";
}else{
this->print_path(start_, this->path_[start_][end_]);
this->print_path(this->path_[start_][end_], end_);
}
}
template<typename T>
Graph<T>::~Graph()
{
if(!this->graph_.empty()){
this->graph_.clear();
}
if(!this->path_.empty()){
this->path_.clear();
}
if(!this->distance_.empty()){
this->distance_.clear();
}
}
int main()
{
int edges[15][3]={
{1, 2, 2},
{1, 4, 20},
{2, 5, 1},
{3, 1, 3},
{4, 3, 8},
{4, 6, 6},
{4, 7, 4},
{5, 3, 4},
{5, 8, 3},
{6, 3, 1},
{7, 8, 1},
{8, 6, 2},
{8, 10, 2},
{9, 7, 2},
{10, 9, 1}
};
Graph<int> my_graph(edges);
my_graph.print(1, 3);
return 0;
}