diff --git a/Source/Graph.cpp b/Source/Graph.cpp index b44bc4c..177c4d5 100644 --- a/Source/Graph.cpp +++ b/Source/Graph.cpp @@ -1,199 +1,65 @@ #include "Graph.h" +#include "Graph.h" -void Graph::PrintIncidenceMatrix() +void Graph::Insert(int u, int v) { - for (int i = 0; i < nodes; i++) - { - for (int j = 0; j < edges; j++) - { - int val = this->matrix[i][j]; + InsertD(u, v); + InsertD(v, u); +} - if (val >= 0) - { - cout << " " << val << " "; - } - else - { - cout << val << " "; - } +void Graph::InsertD(int u, int v) +{ + adj[u].push_back(v); +} + +void Graph::Remove(int u, int v) +{ + RemoveD(u, v); + RemoveD(v, u); +} + +void Graph::RemoveD(int u, int v) +{ + auto iv = find(adj[u].begin(), adj[u].end(), v); + *iv = -1; +} + +Graph *Graph::Clone() +{ + Graph *graph = new Graph(length); + + for (auto i = 0; i < length; i++) + { + for (auto j = adj[i].begin(); j != adj[i].end(); j++) + { + graph->InsertD(i, *j); + } + } + + return graph; +} + +void Graph::Print() +{ + for (auto i = 0; i < length; i++) + { + cout << "[" << i << "]: "; + + for (auto j = adj[i].begin(); j != adj[i].end(); j++) + { + cout << *j << " "; } cout << endl; } - - cout << endl; } -void Graph::PrintAdjacencyMatrix() -{ - Graph::_PrintAdjacencyMatrix(this->GetAdjacencyMatrix()); -} - -void Graph::AddEdge(int u, int v) -{ - this->matrix[u][this->edges] = 1; - this->matrix[v][this->edges] = -1; - this->edges++; -} - -vector> Graph::GetAdjacencyMatrix() -{ - vector> adjacency(this->nodes, vector(this->nodes, 0)); - - // Converte uma matriz de incidência para de adjacência. - for (int j = 0; j < this->edges; j++) - { - int u = -1, v = -1; - - for (int i = 0; i < this->nodes; i++) - { - if (this->matrix[i][j] == 1) - { - if (u == -1) - { - u = i; - } - } - else if (this->matrix[i][j] == -1) - { - if (v == -1) - { - v = i; - } - } - } - - if (u != -1 && v != -1) - { - adjacency[u][v] = 1; - } - } - - return adjacency; -} - -vector> Graph::GetIncidenceMatrix() -{ - vector> incidence(this->nodes); - - for (int i = 0; i < this->nodes; i++) - { - for (int j = 0; j < this->edges; j++) - { - incidence[i].push_back(this->matrix[i][j]); - } - } - - return incidence; -} - -Graph *Graph::ToTransitiveClosure() -{ - auto closure = this->GetAdjacencyMatrix(); - - // Calcula o fecho transitivo do grafo. - for (auto k = 0; k < this->nodes; k++) - { - for (auto i = 0; i < this->nodes; i++) - { - for (auto j = 0; j < this->nodes; j++) - { - if (i == j) - { - closure[i][j] = 1; - } - else - { - closure[i][j] = closure[i][j] || (closure[i][k] && closure[k][j]); - } - } - } - } - - cout << "TC:" << endl; - Graph::_PrintAdjacencyMatrix(closure); - - return new Graph(closure, closure.size()); -} - -void Graph::TransitiveReduction() -{ - auto closure = this->GetAdjacencyMatrix(); - - cout << "G1:" << endl; - Graph::_PrintAdjacencyMatrix(closure); - - for (auto k = 0; k < this->nodes; k++) - { - for (auto i = 0; i < this->nodes; i++) - { - for (auto j = 0; j < this->nodes; j++) - { - if (i == j) - { - closure[i][j] = 1; - } - else - { - closure[i][j] = closure[i][j] || (closure[i][k] && closure[k][j]); - } - } - } - } - - cout << "TC:" << endl; - Graph::_PrintAdjacencyMatrix(closure); - - auto reduction = this->GetAdjacencyMatrix(); - - for (auto j = 0; j < this->nodes; j++) - { - for (auto i = 0; i < this->nodes; i++) - { - if (reduction[i][j] == 1) - { - for (auto k = 0; k < this->nodes; k++) - { - if (reduction[j][k] == 1) - { - reduction[i][k] = 0; - } - } - } - } - } - - cout << "G2:" << endl; - Graph::_PrintAdjacencyMatrix(reduction); - - for (auto k = 0; k < this->nodes; k++) - { - for (auto i = 0; i < this->nodes; i++) - { - for (auto j = 0; j < this->nodes; j++) - { - if (i == j) - { - reduction[i][j] = 1; - } - else - { - reduction[i][j] = reduction[i][j] || (reduction[i][k] && reduction[k][j]); - } - } - } - } - - cout << "TC:" << endl; - Graph::_PrintAdjacencyMatrix(reduction); -} - -/* void Graph::TransitiveClosure() { int m1[length][length]; int m2[length][length]; int m3[length][length]; + int gt[length][length]; // Populate matrix @@ -293,13 +159,13 @@ void Graph::TransitiveClosure() { for (auto j = 0; j < length; j++) { - if (m1[i][j] >= 1 && m3[i][j] >= 1) + if (m1[i][j] == 1 && m3[i][j] == 1) { - m3[i][j] = 0; + gt[i][j] = 1; } else { - m3[i][j] = m1[i][j]; + gt[i][j] = 0; } } } @@ -310,10 +176,9 @@ void Graph::TransitiveClosure() { for (auto j = 0; j < length; j++) { - cout << m3[i][j] << " "; + cout << gt[i][j] << " "; } cout << endl; } } -*/ diff --git a/Source/Graph.h b/Source/Graph.h index c9abda3..4ec66f6 100644 --- a/Source/Graph.h +++ b/Source/Graph.h @@ -1,7 +1,6 @@ #pragma once #include -#include #include #include #include @@ -13,125 +12,30 @@ using namespace std; -const int MATRIX_LENGTH = 100; - class Graph { private: - int nodes, edges; - array, MATRIX_LENGTH> matrix; + int length; + list *adj; public: - Graph(int nodes) + Graph(int length) { - this->nodes = nodes; - this->edges = 0; - this->matrix.fill(array{}); + this->length = length; + this->adj = new list[length]; } - Graph(const Graph &other) + ~Graph() { - this->nodes = other.nodes; - this->edges = other.edges; - this->matrix = other.matrix; - } - - Graph(const vector> &incidence) - { - this->nodes = incidence.size(); - this->edges = incidence[0].size(); - this->matrix.fill(array{}); - - for (int i = 0; i < this->nodes; i++) - { - for (int j = 0; j < this->edges; j++) - { - this->matrix[i][j] = incidence[i][j]; - } - } - } - - Graph(const vector> &adjacency, int nodes) - { - this->nodes = nodes; - this->edges = 0; - this->matrix.fill(array{}); - - for (int i = 0; i < this->nodes; i++) - { - for (int j = 0; j < this->nodes; j++) - { - if (adjacency[i][j] == 1) - { - this->AddEdge(i, j); - } - } - } - } - - Graph *Clone() const - { - return new Graph(*this); + delete[] adj; } public: - void PrintIncidenceMatrix(); - - void PrintAdjacencyMatrix(); - - void AddEdge(int u, int v); - - vector> GetAdjacencyMatrix(); - - vector> GetIncidenceMatrix(); - - Graph *ToTransitiveClosure(); - - void TransitiveReduction(); - -public: - static vector> MultiplyIncidenceMatrix(const vector> &matrix1, const vector> &matrix2) - { - int rows1 = matrix1.size(); - int cols1 = matrix1[0].size(); - int rows2 = matrix2.size(); - int cols2 = matrix2[0].size(); - - // Cria uma matriz resultante com o tamanho apropriado - vector> result(rows1, vector(cols2, 0)); - - // Realiza a multiplicação das matrizes - for (auto i = 0; i < rows1; i++) - { - for (auto j = 0; j < cols2; j++) - { - result[i][j] = 0; - - for (auto k = 0; k < rows1; k++) - { - result[i][j] += matrix1[i][k] * matrix2[k][j]; - } - } - } - - return result; - } - -private: - void _PrintAdjacencyMatrix(const vector> &adjacency) - { - int nodes = adjacency.size(); - - for (int i = 0; i < nodes; i++) - { - for (int j = 0; j < nodes; j++) - { - cout << adjacency[i][j] << " "; - } - - cout << endl; - } - - cout << endl; - } + void Print(); + void Insert(int u, int v); + void InsertD(int u, int v); + void Remove(int u, int v); + void RemoveD(int u, int v); + void TransitiveClosure(); + Graph *Clone(); }; diff --git a/Source/Main.cpp b/Source/Main.cpp index 07a4f75..7524510 100644 --- a/Source/Main.cpp +++ b/Source/Main.cpp @@ -5,18 +5,19 @@ int main() int nodes = 6; Graph *g1 = new Graph(nodes); - g1->AddEdge(0, 1); - g1->AddEdge(0, 2); - g1->AddEdge(0, 3); - g1->AddEdge(1, 2); - g1->AddEdge(1, 3); - g1->AddEdge(1, 5); - g1->AddEdge(2, 3); - g1->AddEdge(3, 5); - g1->AddEdge(4, 0); - g1->AddEdge(4, 2); + g1->InsertD(0, 1); + g1->InsertD(0, 2); + g1->InsertD(0, 3); + g1->InsertD(1, 2); + g1->InsertD(1, 3); + g1->InsertD(1, 5); + g1->InsertD(2, 3); + g1->InsertD(3, 5); + g1->InsertD(4, 0); + g1->InsertD(4, 2); - g1->TransitiveReduction(); + cout << "-- TRANSITIVE CLOSURE --" << endl; + g1->TransitiveClosure(); // cout << "M1:" << endl; // g1->PrintIncidenceMatrix();