Last active
December 15, 2019 00:13
-
-
Save caotic123/d6b3d502ace458c9547c31a06cafc164 to your computer and use it in GitHub Desktop.
Graph datatype - Krustal and Prim Implementation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <functional> | |
#include <map> | |
#include <list> | |
#include <vector> | |
#include <tuple> | |
#include <algorithm> | |
struct Empyth { | |
enum { isEmyth = 1 }; | |
}; | |
template <typename T> | |
struct graph { | |
graph(T x) | |
: a(x) | |
{ | |
em_ = 1; | |
} | |
graph operator[](unsigned int x) | |
{ | |
std::get<0>(self) = x; | |
return *this; | |
} | |
std::pair<unsigned int, std::list<graph<T>*> > self; | |
T a; | |
int em_; | |
}; | |
template <> | |
struct graph<Empyth> { | |
graph() { em_ = 0; } | |
graph operator[](unsigned int x) | |
{ | |
std::get<0>(self) = x; | |
return *this; | |
} | |
std::pair<unsigned int, std::list<graph<Empyth>*> > self; | |
int em_; | |
}; | |
template <typename T> | |
using graph_s = std::vector<graph<T>*>; | |
template <typename T> | |
struct graph_ { | |
graph_s<T> __; | |
graph_<T> InsertVertex(graph_<T> G, graph<T>* graf_) | |
{ | |
(*graf_) = (*graf_)[G.__.size()]; | |
G.__.push_back(graf_); | |
return G; | |
} | |
graph_<T> insertEdge(graph_<T> G, int v, int w) | |
{ | |
auto f = [](graph_<T> G, int v, int w) { | |
std::get<1>(G.__[v]->self).push_back(G.__[w]); | |
return G; | |
}; | |
return f(f(G, w, v), v, w); | |
} | |
std::list<unsigned int> search_d(graph<T> _, std::vector<bool> __t, | |
std::list<unsigned int> __) | |
{ | |
using list_graph = std::list<graph<T>*>; | |
__t[std::get<0>(_.self)] = true; | |
list_graph t = (std::get<1>(_.self)); | |
__.push_back(std::get<0>(_.self)); | |
for (auto i = t.begin(); i != t.end(); i++) { | |
if (!__t[std::get<0>((*i)->self)]) { | |
return search_d((**i), __t, __); | |
} | |
} | |
return __; | |
}; | |
std::function<std::list<unsigned int>(graph<T>, std::list<unsigned int>)> | |
search_l = [&](graph<T> _, std::list<unsigned int> __t) { | |
using d = typename std::list<std::pair<graph<T>, bool> >::iterator; | |
std::function<d(d, d, graph<T>)> p = [&]( | |
typename std::list<std::pair<graph<T>, bool> >::iterator x_, | |
typename std::list<std::pair<graph<T>, bool> >::iterator e_, | |
graph<T> y_) { | |
return (x_ == e_) ? e_ : (((*x_).first.self).first == y_.self.first) | |
? x_ | |
: p(++x_, e_, y_); | |
}; | |
typename std::list<std::pair<graph<T>, bool> > f_list = { | |
std::make_pair(_, false) | |
}; | |
typename std::list<std::pair<graph<T>, bool> >::iterator x__ = f_list.begin(); | |
using list_graph = std::list<graph<T>*>; | |
list_graph __; | |
typename std::list<std::pair<graph<T>, bool> >::iterator p__; | |
while (x__ != f_list.end()) { | |
__ = (((*x__).first).self).second; | |
__t.push_back((((*x__).first).self).first); | |
for (auto i = __.begin(); i != __.end() && (*x__).second == false; | |
i++) { | |
p__ = p(f_list.begin(), f_list.end(), (*(*i))); | |
if (p__ == f_list.end() || (std::get<1>(*p__) != true && ((((*x__).first).self).first) == (((**i).self).first))) { | |
f_list.push_back(std::make_pair(*(*i), false)); | |
} | |
} | |
std::get<1>(*x__) = true; | |
x__++; | |
} | |
return __t; | |
}; | |
void printDFS(graph_<T> t) | |
{ | |
std::list<unsigned int> s_ = search_d(*t.__[0], std::vector<bool>(t.__.size(), false), | |
std::list<unsigned int>()); | |
for_each(s_.begin(), s_.end(), | |
[](unsigned int x) { std::cout << x << " "; }); | |
std::cout << std::endl; | |
} | |
void printBFS(graph_<T> t) | |
{ | |
std::list<unsigned int> s_ = search_l(*t.__[0], std::list<unsigned int>()); | |
for_each(s_.begin(), s_.end(), | |
[](unsigned int x) { std::cout << x << " "; }); | |
std::cout << std::endl; | |
} | |
auto removeVertex(graph_<T> t, int v) -> typename std::list< | |
typename decltype(std::declval<decltype(t)>().__)::value_type>::iterator | |
{ | |
typename std::list<typename decltype( | |
std::declval<decltype(t)>().__)::value_type>::iterator d; | |
t.__.erase(t.__.begin() + v); | |
for (typename std::vector<graph<T>*>::iterator i = t.__.begin(); | |
i != t.__.end(); i++) { | |
d = std::remove_if((((**i).self).second).begin(), | |
(((**i).self).second).end(), | |
[&](graph<T>* _) { return ((*_).self).first == v; }); | |
} | |
return d; | |
} | |
auto removeEdge(graph_<T> t, int v) -> typename std::list< | |
typename decltype(std::declval<decltype(t)>().__)::value_type>::iterator | |
{ | |
typename std::list<typename decltype( | |
std::declval<decltype(t)>().__)::value_type>::iterator d; | |
for (typename std::vector<graph<T>*>::iterator i = t.__.begin(); | |
i != t.__.end(); i++) { | |
d = std::remove_if((((**i).self).second).begin(), | |
(((**i).self).second).end(), | |
[&](graph<T>* _) { return ((*_).self).first == v; }); | |
} | |
return d; | |
} | |
std::list<graph<T>*> EndVertice(graph_<T> t, int v) | |
{ | |
std::list<graph<T>*> f; | |
for (typename std::vector<graph<T>*>::iterator i = t.__.begin(); | |
i != t.__.end(); i++) { | |
std::for_each(((**i).self).second.begin(), (((**i).self).second).end(), | |
[&](graph<T>* _) { | |
if (((*_).self).first == v) { | |
f.push_back(_); | |
} | |
}); | |
} | |
return f; | |
} | |
bool areAdjacent(graph_<T> t, int v, int w) | |
{ | |
std::pair<bool, bool> fx = std::make_pair(false, false); | |
std::for_each(((*t.__[v]).self).second.begin(), | |
(((*t.__[v]).self).second).end(), [&](graph<T>* _) { | |
if (((*_).self).first == w) { | |
std::get<0>(fx) = true; | |
} | |
}); | |
std::for_each(((*t.__[w]).self).second.begin(), | |
((*t.__[w]).self).second.end(), [&](graph<T>* _) { | |
if (((*_).self).first == v) { | |
std::get<1>(fx) = true; | |
} | |
}); | |
return std::get<0>(fx) == true && std::get<1>(fx) == true; | |
} | |
graph<T>* opposite(graph_<T> t, graph<T> v, int w) | |
{ | |
graph<T>* op; | |
std::for_each((v.self).second.begin(), ((v.self).second).end(), | |
[&](graph<T>* _) { | |
if (((*_).self).first == w) { | |
op = _; | |
} | |
}); | |
return op; | |
} | |
}; | |
int main() | |
{ | |
graph_<Empyth> t; // Cria um grafo "vazio" sem pesos ou informação | |
graph_<int> d; // Cria um grafo que armazena um inteiro | |
graph_<std::string> graph_str; // Grafico de String | |
graph_<std::string> bolo; | |
t = t.InsertVertex( | |
t.InsertVertex(t.InsertVertex(t.InsertVertex(t, new graph<Empyth>()), | |
new graph<Empyth>()), | |
new graph<Empyth>()), | |
new graph<Empyth>()); // Cria um grafo com tamanho de 4 vertices | |
t = t.insertEdge(t, 0, 1); // Liga o 0 -> 1 (Arestas) | |
t = t.insertEdge(t, 1, 3); // Liga 1 -> 3 | |
t = t.insertEdge(t, 3, 0); // Liga 3 -> 0 | |
t.printBFS(t); // Printa o grafo t usando a largura | |
t.removeVertex(t, 1); // Remove o vertice e arestas correspondetes (1) | |
d = d.InsertVertex( | |
d.InsertVertex(d.InsertVertex(d, new graph<int>(4)), new graph<int>(4)), | |
new graph<int>(10)); | |
d = d.insertEdge(d, 2, 1); | |
d = d.insertEdge(d, 0, 1); | |
d.printDFS(d); // Printa usando profundidade | |
graph_str = graph_str.InsertVertex(graph_str, new graph<std::string>("Ovo")); | |
graph_str = graph_str.InsertVertex(graph_str, new graph<std::string>("Clara")); | |
bolo = bolo.insertEdge(graph_str, 0, 1); | |
bolo.printDFS(bolo); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <fstream> | |
#include <list> | |
#include "dirent.h" | |
#include <chrono> | |
#include <vector> | |
#include <thread> | |
#include <algorithm> | |
#include <array> | |
#include <tuple> | |
#include <stack> | |
struct graph__ { | |
std::list<std::pair<graph__*, int>> fx; | |
int d_; | |
}; | |
graph__* new__graph() { | |
return new graph__; | |
} | |
int getGraphAmoung(std::string t) { | |
std::ifstream file(t); | |
std::string s; | |
int d; | |
while(s != "contains") { | |
file >> s; | |
} | |
file >> d; | |
return d; | |
} | |
std::list<std::string> all_file_graph() { | |
DIR* dir; | |
struct dirent* ent; | |
std::ifstream file; | |
std::list<std::string> files_; | |
if ((dir = opendir("./graph")) != NULL) { | |
while ((ent = readdir(dir)) != NULL) { | |
file.open(("graph/" + std::string(ent->d_name)).c_str()); | |
if (file.is_open() && std::string(ent->d_name).length() > 6) { | |
files_.push_back(("graph/" + std::string(ent->d_name)).c_str()); | |
} | |
file.close(); | |
} | |
closedir(dir); | |
} | |
return files_; | |
} | |
bool cicle(std::vector<graph__*> graph_s, int l) { | |
auto dfs_ = [](std::vector<graph__*> graph_s, int n, int len) { | |
using T = decltype(std::declval<graph__>().fx); | |
std::stack<int> stack__; | |
bool visited[n], pilha_rec[n]; | |
bool found; | |
T::iterator it; | |
for (int i = 1; i <= len; i++) { | |
visited[i] = false; | |
pilha_rec[i] = false; | |
} | |
while(true) { | |
found = true; | |
if (!visited[n]) { | |
stack__.push(n); | |
visited[n] = true; | |
pilha_rec[n] = true; | |
} | |
for (it = graph_s[n]->fx.begin(); it != graph_s[n]->fx.end(); it++) { | |
if (pilha_rec[(*it).first->d_]) {return true;} | |
else if (visited[(*it).first->d_]) {found = true; break;} | |
} | |
if (!found) { | |
std::cout << stack__.top() << std::endl; | |
pilha_rec[stack__.top()] = false; | |
stack__.pop(); | |
if (stack__.empty()) { | |
break; | |
} | |
n = stack__.top(); | |
} | |
if (it == graph_s[n]->fx.end()) {return false;} | |
else {n = (*it).first->d_;} | |
} | |
return false; | |
}; | |
for (int i=1; i <= l; i++) { | |
if (dfs_(graph_s, graph_s[i]->d_, l)) {return true;} | |
} | |
return false; | |
} | |
void krustal__(std::vector<graph__*> f_, int n) { | |
using T = decltype(std::declval<graph__>().fx); | |
std::vector<graph__*> new_graph(n); | |
for (int i=0; i <= n; i++) { | |
new_graph[i] = new__graph(); | |
new_graph[i]->d_ = i; | |
} | |
std::vector<bool> v_(n, false); | |
auto less_path = [&](std::vector<graph__*> f_, int n) { | |
auto l_path = [](graph__* x){ | |
T::iterator _ = x->fx.begin(); | |
for (T::iterator i = x->fx.begin(); i != x->fx.end(); i++) { | |
if ((*i).second > (*_).second) { | |
_ = i; | |
} | |
} | |
return (*_); | |
}; | |
T::value_type min = *(f_[1]->fx.begin()); | |
T::value_type dd_; | |
int w; | |
for (int i=1; i <=n-1; i++) { | |
std::cout << i << std::endl; | |
dd_ = l_path(f_[i]); | |
if (min.second > dd_.second && !v_[dd_.first->d_]) { | |
v_[dd_.first->d_] = true; | |
min = dd_; | |
w = f_[i]->d_; | |
} | |
} | |
return make_pair(min, w); | |
}; | |
std::cout << cicle(f_, n) << std::endl; | |
auto f = less_path(f_, n); | |
while(!cicle(new_graph, n)) { | |
std::cout << std::get<1>(f) << std::endl; | |
new_graph[std::get<1>(f)]->fx.push_back(std::get<0>(f)); | |
f = less_path(f_, n); | |
} | |
} | |
void primm__(graph__* actual, int n_) { | |
auto f = std::vector<std::tuple<bool, bool, int, graph__*>>(n_, std::make_tuple(false, false, 0, (graph__*)NULL)); | |
f[actual->d_] = std::make_tuple(true, false, 0, actual); | |
decltype(f)::value_type s_ = f[actual->d_]; | |
using T = decltype(std::declval<graph__>().fx); | |
auto walk_path = [&](graph__* a_) { | |
std::get<1>(f[a_->d_]) = true; // has been visited | |
for (T::iterator ___i = a_->fx.begin(); ___i != a_->fx.end(); ___i++) { | |
f[(*___i).first->d_] = std::make_tuple(true, std::get<1>(f[(*___i).first->d_]), (*___i).second, (*___i).first); | |
} | |
return f[a_->d_]; | |
}; | |
bool b; | |
while (b) { | |
s_ = walk_path(std::get<3>(s_)); | |
b = false; | |
std::for_each(f.begin(), f.end(), [&](decltype(f)::value_type __f){if ((std::get<0>(__f) && !std::get<1>(__f) && (std::get<2>(s_) > std::get<2>(__f))) || (std::get<1>(s_) && std::get<0>(__f) && !std::get<1>(__f))) {b = true; s_ = __f;} }); | |
} | |
} | |
int main() { | |
std::list<std::string> graph_ = all_file_graph(); | |
std::vector<std::vector<graph__*>> data__; | |
std::vector<graph__*> f_; | |
std::ifstream file_graph; | |
std::string f_s; | |
int d[3]; | |
for (std::list<std::string>::iterator i = graph_.begin(); i != graph_.end(); i++) { | |
for (int _ = (getGraphAmoung(*i)+1); _ >= 0; _--) { | |
f_.push_back(new__graph()); | |
} | |
file_graph.open(*i); | |
while(file_graph >> f_s) { | |
if (f_s == "a") { | |
file_graph >> d[1]; | |
file_graph >> d[2]; | |
file_graph >> d[3]; | |
f_[d[1]]->fx.push_back(std::make_pair(f_[d[2]], d[3])); | |
(*f_[d[1]]).d_ = d[1]; | |
} | |
} | |
file_graph.close(); | |
primm__(f_[1], getGraphAmoung(*i)+1); | |
krustal__(f_, getGraphAmoung(*i)+1); | |
f_.clear(); | |
break; | |
// std::this_thread::sleep_for(std::chrono::milliseconds(1000*2)); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment