最短経路と行列乗算
10494 ワード
#include <iostream>
#include <stdexcept>
#include <vector>
#include <algorithm>
#include <memory>
#include <map>
namespace{
enum:int{
MAXVALUE = 9999
};
}
template<typename T>
class Node{
private:
T key_;
public:
typedef T key_type;
// .
template<typename Ty>
Node(const Ty& key);
// .
template<typename Ty>
Node(const Node<Ty>& otherNode_);
// .
template<typename Ty>
Node(Node<Ty>&& otherNode_);
// .
Node() = default;
// .
~Node();
template<typename Ty>
Node<Ty>& operator*()const;
//== .
template<typename Ty>
friend bool operator==(const Node<Ty>& first_, const Node<Ty>& second_);
//< .
template<typename Ty>
friend bool operator<(const Node<Ty>& first_, const Node<Ty>& second_);
// .
const Node<T>& operator=(const Node<T>& otherNode_);// .
//<< .
template<typename Ty>
friend std::ostream& operator<<(std::ostream& os, const Node<Ty>& node_);
// .
template<typename Ty>
void operator=(Node<Ty>&& otherNode_);
};
template<typename T>
template<typename Ty>
Node<T>::Node(const Ty& key)
:key_(key)
{
//std::cout<<"constructor function."<<std::endl;
}
template<typename T>
template<typename Ty>
Node<T>::Node(const Node<Ty>& otherNode_)
:key_(otherNode_.key_)
{
std::cout<<"copy for constructor"<<std::endl;
}
template<typename T>
Node<T>::~Node()
{
//
}
template<typename Ty>
bool operator==(const Node<Ty>& first_, const Node<Ty>& second_)
{
return (first_.key_ == second_.key_) ? true : false;
}
template<typename T>
const Node<T>& Node<T>::operator=(const Node<T>& otherNode_) // .
{
this->key_ = otherNode_.key_;
std::cout<<"copy function"<<std::endl;
}
template<typename T>
template<typename Ty>
Node<Ty>& Node<T>::operator*()const
{
return *this;
}
template<typename Ty>
bool operator<(const Node<Ty>& first_, const Node<Ty>& second_)
{
//std::cout<<"<"<<std::endl;
return (first_.key_ < second_.key_) ? true : false;
}
template<typename Ty>
std::ostream& operator<<(std::ostream& os, const Node<Ty>& node_)
{
os<<node_.key_<<std::endl;
return os;
}
template<typename T>
template<typename Ty>
void Node<T>::operator=(Node<Ty>&& otherNode_)
{
std::cout<<"operator move"<<std::endl;
this->key_ = otherNode_.key_;
}
template<typename T>
class Map{
private:
//class in class.
class Compare{
public:
template<typename Ty>
bool operator()(const Node<Ty>& first_, const Node<Ty>& second_);
};
//class in class.
class Container{
public:
template<typename Ty>
bool operator()(Map<Ty>* temp_map, typename Map<Ty>::cv_iter currentIter_first, typename Map<Ty>::v_iter currentIter_second);
};
std::map<Node<T>, std::map<Node<T>, int>> graph_; //
static std::map<Node<T>, std::vector<Node<T>>> adjList_;
std::map<Node<T>, std::map<Node<T>, int>> temp_graph_;
unsigned int nodeNumber_;
typename Map<T>::Graph extend_shortest_paths();
const int& min(const int& first_, const int& second_);
public:
typedef std::map<Node<T>, std::map<Node<T>, int>> Graph;
using v_iter = typename std::vector<Node<T>>::const_iterator;// .
using cv_iter = typename std::map<Node<T>, std::vector<Node<T>>>::const_iterator;
template<typename Ty>
using cmm_iter = typename std::map<Node<Ty>, std::map<Node<Ty>, int>>::const_iterator;// .
template<typename Ty>
using cm_iter = typename std::map<Node<Ty>, int>::const_iterator;
template<typename Ty, unsigned int N>
Map(const Ty (&edge)[N][3]);
~Map();
Map()=default;
void slow_all_pairs_shortest_paths();
void print();
};
template<typename T>
std::map<Node<T>, std::vector<Node<T>>> Map<T>::adjList_;
template<typename T>
template<typename Ty, unsigned int N>
Map<T>::Map(const Ty (&edges)[N][3])
:nodeNumber_(N)
{
if(N == 0){
throw std::runtime_error(std::string("there is nothing in graph"));
}
for(int i =0; i<N; ++i){ // 。
Node<Ty> first_(edges[i][0]);
Node<Ty> second_(edges[i][2]);
this->graph_[first_][second_] = edges[i][1];
//this->temp_graph_[first_][second_] = ::MAXVALUE;
this->adjList_[first_].push_back(second_); // : A vector .
//std::cout<<"first: "<<first_<<std::endl;
//std::cout<<"second: "<<second_<<std::endl;
}
cv_iter iter_first = this->adjList_.cbegin();
for(; iter_first != this->adjList_.cend(); ++iter_first){
v_iter iter_second = this->adjList_[iter_first->first].cbegin();
for(; iter_second != this->adjList_[iter_first->first].cend(); ++iter_second){
std::cout<<"iter_first: "<<iter_first->first<<std::endl;
std::cout<<"iter_second: "<<*iter_second<<std::endl;
}
}
}
template<typename T>
typename Map<T>::Graph Map<T>::extend_shortest_paths()
{
Container jundge_;
cv_iter first_ = this->adjList_.cbegin();
Graph l_graph_;
for(; first_ != this->adjList_.cend(); ++first_){
//std::cout<<"first_->first"<<first_->first<<std::endl;
v_iter second_ = this->adjList_[first_->first].cbegin();
for(; second_ != this->adjList_[first_->first].cend(); ++second_){
//std::cout<<"second_: "<< *second_ <<std::endl;
l_graph_[first_->first][*second_] = ::MAXVALUE;
cv_iter third_ = this->adjList_.cbegin();
for(; third_ != this->adjList_.cend(); ++third_){
bool boolean = jundge_(this, third_, second_);
if(boolean == false){
continue;
}
std::cout<<"first_:"<<(first_->first)<<std::endl;
std::cout<<"second_: "<<*second_<<std::endl;
std::cout<<"third_: "<<third_->first<<std::endl;
l_graph_[first_->first][*second_] = this->min(l_graph_[first_->first][*second_], this->temp_graph_[first_->first][third_->first]+this->graph_[third_->first][*second_]);
}
}
}
return l_graph_;
}
template<typename T>
void Map<T>::slow_all_pairs_shortest_paths()
{
for(int i=1; i<this->nodeNumber_; ++i){
this->temp_graph_ = this->extend_shortest_paths();
}
}
template<typename T>
template<typename Ty>
bool Map<T>::Compare::operator()(const Node<Ty>& first_, const Node<Ty>& second_)
{
return first_ < second_ ? true : false;
}
template<typename T>
const int& Map<T>::min(const int& first_, const int& second_)
{
return (first_ < second_) ? first_ : second_;
}
template<typename T>
template<typename Ty>
bool Map<T>::Container::operator()(Map<Ty>* temp_map, typename Map<Ty>::cv_iter currentIter_first, typename Map<Ty>::v_iter currentIter_second)
{
if(temp_map->adjList_[currentIter_first->first].empty()){
return false;
}else{
typename Map<Ty>::v_iter first_ = temp_map->adjList_[currentIter_first->first].cbegin();
typename Map<Ty>::v_iter second_ = temp_map->adjList_[currentIter_first->first].cend();
typename Map<Ty>::v_iter third_;
third_=std::find_if(first_, second_, [currentIter_second](const Node<Ty>& temp_)->bool { return (temp_ == *currentIter_second) ? true : false; });
if(third_ == second_){
return false;
}else{
return true;
}
}
}
template<typename T>
void Map<T>::print()
{
if(this->temp_graph_.empty()){
std::cout<<"there is nothing/n"<<std::endl;
return;
}else{
cmm_iter<T> begin = this->temp_graph_.cbegin();
for(; begin != this->temp_graph_.cend(); ++begin){
Node<T> temp_node = begin->first;
cm_iter<T> begin_ = this->temp_graph_[temp_node].cbegin();
for(; begin_ != this->temp_graph_[temp_node].cend(); ++begin_){
std::cout<< (begin->first) <<"<->"<<begin_->second<<"<->"<<begin_->first<<std::endl;
}
}
}
}
template<typename T>
Map<T>::~Map()
{
if(!this->graph_.empty()){
this->graph_.clear();
}
if(!this->adjList_.empty()){
this->adjList_.clear();
}
if(!this->temp_graph_.empty()){
this->temp_graph_.clear();
}
}
int main()
{
/*Node<int> one_(20);
Node<int> two_(30);
Node<int> three_;
three_ = one_;
one_ = two_;
std::cout<<one_;
three_ = std::move(one_);
std::cout<<std::boolalpha<< (one_<two_ )<<std::endl;*/
int graph[9][3]={
{1, 3, 2},//node--weighting--node.
{1, 8, 3},
{1, -4, 5},
{2, 7, 5},
{2, 1, 4},
{3, 4, 2},
{4, 2, 1},
{4, -5, 3},
{5, 6, 4}
};
Map<int> myGraph(graph);
myGraph.slow_all_pairs_shortest_paths();
myGraph.print();
return 0;
}