From de86edabb13309988195e3ec2b162c436a449564 Mon Sep 17 00:00:00 2001 From: ZigRazor Date: Fri, 16 Jul 2021 11:11:19 +0200 Subject: [PATCH] Documentation Update (#31) * Updated Doxygen Documentation * [CodeFactor] Apply fixes to commit 11a9528 Co-authored-by: codefactor-io --- docs/html/annotated.html | 9 +- docs/html/classes.html | 4 +- docs/html/d0/df2/classCXXGRAPH_1_1Graph.html | 25 +- ...CXXGRAPH_1_1PartitioningStats__struct.html | 144 + docs/html/d3/dd2/classCXXGRAPH_1_1Node.html | 2 +- .../d4/d32/classCXXGRAPH_1_1Partition.html | 71 +- ...assCXXGRAPH_1_1UndirectedWeightedEdge.html | 2 +- docs/html/d7/d2a/classCXXGRAPH_1_1Edge.html | 2 +- .../d7/d7f/classCXXGRAPH_1_1Edge-members.html | 2 +- .../classCXXGRAPH_1_1Partition-members.html | 12 +- ...APH_1_1UndirectedWeightedEdge-members.html | 2 +- ...assCXXGRAPH_1_1UndirectedEdge-members.html | 2 +- .../d8/d91/classCXXGRAPH_1_1Node-members.html | 2 +- docs/html/d9/d69/Graph_8hpp_source.html | 3241 +++++++++-------- ...APH_1_1DijkstraResult__struct-members.html | 2 +- ...classCXXGRAPH_1_1DirectedWeightedEdge.html | 2 +- ..._1_1PartitioningStats__struct-members.html | 98 + ...GRAPH_1_1DirectedWeightedEdge-members.html | 2 +- .../db/d54/classCXXGRAPH_1_1Weighted.html | 2 +- ...classCXXGRAPH_1_1DirectedEdge-members.html | 2 +- .../classCXXGRAPH_1_1Weighted-members.html | 2 +- ...uctCXXGRAPH_1_1DijkstraResult__struct.html | 11 +- .../d77/classCXXGRAPH_1_1Graph-members.html | 8 +- .../de/df5/classCXXGRAPH_1_1DirectedEdge.html | 2 +- .../d71/classCXXGRAPH_1_1UndirectedEdge.html | 2 +- .../dir_d44c64559bbebec7f509842c48db8b23.html | 2 +- docs/html/files.html | 2 +- docs/html/functions.html | 16 +- docs/html/functions_enum.html | 2 +- docs/html/functions_eval.html | 2 +- docs/html/functions_func.html | 13 +- docs/html/functions_type.html | 5 +- docs/html/graph_legend.html | 2 +- docs/html/hierarchy.html | 11 +- docs/html/index.html | 2 +- docs/html/inherit_graph_0.map | 2 +- docs/html/inherit_graph_0.md5 | 2 +- docs/html/inherit_graph_1.md5 | 2 +- docs/html/inherit_graph_4.map | 3 + docs/html/inherit_graph_4.md5 | 1 + docs/html/inherit_graph_4.png | Bin 0 -> 2991 bytes docs/html/inherits.html | 9 +- docs/html/search/all_3.js | 6 +- docs/html/search/all_4.js | 8 +- docs/html/search/all_5.js | 2 +- docs/html/search/all_6.js | 6 +- docs/html/search/all_7.js | 2 +- docs/html/search/all_8.js | 5 +- docs/html/search/all_9.js | 4 +- docs/html/search/all_a.js | 4 +- docs/html/search/classes_0.js | 6 +- docs/html/search/classes_1.js | 2 +- docs/html/search/classes_2.js | 2 +- docs/html/search/classes_3.js | 2 +- docs/html/search/classes_4.js | 3 +- docs/html/search/classes_5.js | 4 +- docs/html/search/classes_6.js | 2 +- docs/html/search/enums_0.js | 4 +- docs/html/search/enumvalues_0.js | 2 +- docs/html/search/enumvalues_1.js | 4 +- docs/html/search/functions_0.js | 2 +- docs/html/search/functions_1.js | 4 +- docs/html/search/functions_2.js | 5 +- docs/html/search/functions_3.js | 4 +- docs/html/search/functions_4.js | 2 +- docs/html/search/functions_5.js | 2 +- docs/html/search/functions_6.html | 37 + docs/html/search/functions_6.js | 4 + docs/html/search/functions_7.html | 37 + docs/html/search/functions_7.js | 4 + docs/html/search/searchdata.js | 4 +- docs/html/search/typedefs_0.js | 2 +- docs/html/search/typedefs_1.html | 37 + docs/html/search/typedefs_1.js | 4 + docs/latex/annotated.tex | 3 +- docs/latex/d0/df2/classCXXGRAPH_1_1Graph.tex | 23 +- ...tCXXGRAPH_1_1PartitioningStats__struct.tex | 67 + .../d4/d32/classCXXGRAPH_1_1Partition.tex | 47 +- ...ructCXXGRAPH_1_1DijkstraResult__struct.tex | 12 + docs/latex/hierarchy.tex | 1 + docs/latex/refman.tex | 3 +- 81 files changed, 2450 insertions(+), 1651 deletions(-) create mode 100644 docs/html/d2/def/structCXXGRAPH_1_1PartitioningStats__struct.html create mode 100644 docs/html/da/d62/structCXXGRAPH_1_1PartitioningStats__struct-members.html create mode 100644 docs/html/inherit_graph_4.map create mode 100644 docs/html/inherit_graph_4.md5 create mode 100644 docs/html/inherit_graph_4.png create mode 100644 docs/html/search/functions_6.html create mode 100644 docs/html/search/functions_6.js create mode 100644 docs/html/search/functions_7.html create mode 100644 docs/html/search/functions_7.js create mode 100644 docs/html/search/typedefs_1.html create mode 100644 docs/html/search/typedefs_1.js create mode 100644 docs/latex/d2/def/structCXXGRAPH_1_1PartitioningStats__struct.tex diff --git a/docs/html/annotated.html b/docs/html/annotated.html index 4fef7ea6e..3d87922a8 100644 --- a/docs/html/annotated.html +++ b/docs/html/annotated.html @@ -23,7 +23,7 @@ Logo
CXXGraph -  0.1.2 +  0.1.3
CXXGraph is a small library, header only, that manages the Graph and it's algorithm in C++
@@ -78,9 +78,10 @@  CDirectedWeightedEdge  CUndirectedWeightedEdge  CGraph - CDijkstraResult_struct - CWeighted - CPartition + CPartition + CDijkstraResult_structStruct that contains the information about Dijsktra's Algorithm results + CPartitioningStats_structStruct that contains the information about the partitioning statistics + CWeighted diff --git a/docs/html/classes.html b/docs/html/classes.html index 43f4cdba7..f87af87b1 100644 --- a/docs/html/classes.html +++ b/docs/html/classes.html @@ -23,7 +23,7 @@ Logo
CXXGraph -  0.1.2 +  0.1.3
CXXGraph is a small library, header only, that manages the Graph and it's algorithm in C++
@@ -84,7 +84,7 @@
Node (CXXGRAPH)
P
-
Partition (CXXGRAPH)
+
Partition (CXXGRAPH)
PartitioningStats_struct (CXXGRAPH)
U
UndirectedEdge (CXXGRAPH)
UndirectedWeightedEdge (CXXGRAPH)
diff --git a/docs/html/d0/df2/classCXXGRAPH_1_1Graph.html b/docs/html/d0/df2/classCXXGRAPH_1_1Graph.html index d00f79ffa..f09512aeb 100644 --- a/docs/html/d0/df2/classCXXGRAPH_1_1Graph.html +++ b/docs/html/d0/df2/classCXXGRAPH_1_1Graph.html @@ -23,7 +23,7 @@ Logo
CXXGraph -  0.1.2 +  0.1.3
CXXGraph is a small library, header only, that manages the Graph and it's algorithm in C++
@@ -100,13 +100,15 @@ , ALG_1 , ALG_2 } + Specify the Partition Algorithm. More...
  typedef enum CXXGRAPH::Graph::E_InputOutputFormat InputOutputFormat  Specify the Input/Output format of the Graph for Import/Export functions.
  -typedef enum CXXGRAPH::Graph::E_PartitionAlgorithm PartitionAlgorithm +typedef enum CXXGRAPH::Graph::E_PartitionAlgorithm PartitionAlgorithm + Specify the Partition Algorithm.
  +const AdjacencyMatrix< T >  + @@ -159,9 +162,9 @@ - - - + + +

@@ -133,7 +135,8 @@ const std::optional< const Edge< T > * > 

getEdge (unsigned long edgeId) const
 
-const AdjacencyMatrix< T > getAdjMatrix () const
getAdjMatrix () const
 This function generate a list of adjacency matrix with every element of the matrix contain the node where is directed the link and the Edge corrispondent to the link.
 
const DijkstraResult dijkstra (const Node< T > &source, const Node< T > &target) const
 Function runs the dijkstra algorithm for some source node and target node in the graph and returns the shortest distance of target from the source. More...
int readFromFile (InputOutputFormat format=InputOutputFormat::STANDARD_CSV, const std::string &workingDir=".", const std::string &OFileName="graph", bool compress=false, bool readNodeFeat=false, bool readEdgeWeight=false)
 This function write the graph in an output file. More...
 
std::map< unsigned int, Partition< T > * > partitionGraph (PartitionAlgorithm algorithm, unsigned int numberOfPartitions) const
 This function partition a graph in a set of partitions. More...
 
PartitionMap< T > partitionGraph (PartitionAlgorithm algorithm, unsigned int numberOfPartitions) const
 This function partition a graph in a set of partitions. More...
 
@@ -210,6 +213,8 @@

+ +

Specify the Partition Algorithm.

Friends

@@ -373,8 +378,8 @@

-

◆ partitionGraph()

+ +

◆ partitionGraph()

@@ -382,9 +387,9 @@

- + - + diff --git a/docs/html/d2/def/structCXXGRAPH_1_1PartitioningStats__struct.html b/docs/html/d2/def/structCXXGRAPH_1_1PartitioningStats__struct.html new file mode 100644 index 000000000..88b9950e4 --- /dev/null +++ b/docs/html/d2/def/structCXXGRAPH_1_1PartitioningStats__struct.html @@ -0,0 +1,144 @@ + + + + + + + +CXXGraph: CXXGRAPH::PartitioningStats_struct Struct Reference + + + + + + + + + +
+
+
Enumerator
GREEDY_VC 

A Greedy Vertex-Cut Algorithm.

std::map< unsigned int, Partition< T > * > CXXGRAPH::Graph< T >::partitionGraph PartitionMap< T > CXXGRAPH::Graph< T >::partitionGraph (PartitionAlgorithm PartitionAlgorithm  algorithm,
+ + + + + + +
+
CXXGraph +  0.1.3 +
+
CXXGraph is a small library, header only, that manages the Graph and it's algorithm in C++
+
+ + + + + + + + + +
+
+ + +
+ +
+ +
+ +
+ +
+
CXXGRAPH::PartitioningStats_struct Struct Reference
+
+
+ +

Struct that contains the information about the partitioning statistics. + More...

+ +

#include <Graph.hpp>

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +

+Public Attributes

+unsigned int numberOfPartitions
 
+unsigned int numberOfNodes
 
+unsigned int replicatedNodesCount
 
+unsigned int numberOfEdges
 
+unsigned int replicatedEdgesCount
 
+unsigned int maxEdgesLoad
 
+unsigned int minEdgesLoad
 
+unsigned int maxNodesLoad
 
+unsigned int minNodesLoad
 
+double balanceEdgesFactor
 
+double balanceNodesFactor
 
+double nodesReplicationFactor
 
+double edgesReplicationFactor
 
+ + + +

+Friends

+std::ostream & operator<< (std::ostream &os, const PartitioningStats_struct &partitionStats)
 
+

Detailed Description

+

Struct that contains the information about the partitioning statistics.

+

The documentation for this struct was generated from the following file: +
+ + + + diff --git a/docs/html/d3/dd2/classCXXGRAPH_1_1Node.html b/docs/html/d3/dd2/classCXXGRAPH_1_1Node.html index 5c40c65ee..15eaef2b1 100644 --- a/docs/html/d3/dd2/classCXXGRAPH_1_1Node.html +++ b/docs/html/d3/dd2/classCXXGRAPH_1_1Node.html @@ -23,7 +23,7 @@ Logo
CXXGraph -  0.1.2 +  0.1.3
CXXGraph is a small library, header only, that manages the Graph and it's algorithm in C++
diff --git a/docs/html/d4/d32/classCXXGRAPH_1_1Partition.html b/docs/html/d4/d32/classCXXGRAPH_1_1Partition.html index b83cfb320..301951be3 100644 --- a/docs/html/d4/d32/classCXXGRAPH_1_1Partition.html +++ b/docs/html/d4/d32/classCXXGRAPH_1_1Partition.html @@ -23,7 +23,7 @@ Logo
CXXGraph -  0.1.2 +  0.1.3
CXXGraph is a small library, header only, that manages the Graph and it's algorithm in C++
@@ -105,11 +105,11 @@  Partition (unsigned int partitionId, const std::list< const Edge< T > * > &edgeSet)   - -unsigned int getPartitionId () const +unsigned int getPartitionId () const + Get the Partition ID. More...
  - -void setPartitionId (unsigned int partitionId) +void setPartitionId (unsigned int partitionId) + Set the Partition ID. More...
  - Public Member Functions inherited from CXXGRAPH::Graph< T > @@ -134,7 +134,8 @@ const std::optional< const Edge< T > * > getEdge (unsigned long edgeId) const   -const AdjacencyMatrix< T > getAdjMatrix () const +const AdjacencyMatrix< T > getAdjMatrix () const + This function generate a list of adjacency matrix with every element of the matrix contain the node where is directed the link and the Edge corrispondent to the link.
  const DijkstraResult dijkstra (const Node< T > &source, const Node< T > &target) const  Function runs the dijkstra algorithm for some source node and target node in the graph and returns the shortest distance of target from the source. More...
@@ -160,9 +161,9 @@ int readFromFile (InputOutputFormat format=InputOutputFormat::STANDARD_CSV, const std::string &workingDir=".", const std::string &OFileName="graph", bool compress=false, bool readNodeFeat=false, bool readEdgeWeight=false)  This function write the graph in an output file. More...
  -std::map< unsigned int, Partition< T > * > partitionGraph (PartitionAlgorithm algorithm, unsigned int numberOfPartitions) const - This function partition a graph in a set of partitions. More...
-  +PartitionMap< T > partitionGraph (PartitionAlgorithm algorithm, unsigned int numberOfPartitions) const + This function partition a graph in a set of partitions. More...
+  @@ -178,15 +179,65 @@ , ALG_1 , ALG_2 } + +typedef enum CXXGRAPH::Graph::E_PartitionAlgorithm  +

Additional Inherited Members

 Specify the Partition Algorithm. More...
 
typedef enum CXXGRAPH::Graph::E_InputOutputFormat InputOutputFormat
 Specify the Input/Output format of the Graph for Import/Export functions.
 
-typedef enum CXXGRAPH::Graph::E_PartitionAlgorithm PartitionAlgorithm
PartitionAlgorithm
 Specify the Partition Algorithm.
 
+

Member Function Documentation

+ +

◆ getPartitionId()

+ +
+
+
+template<typename T >
+ + + + +
unsigned int CXXGRAPH::Partition< T >::getPartitionId
+
+ +

Get the Partition ID.

+
Returns
The ID of the partition
+ +
+
+ +

◆ setPartitionId()

+ +
+
+
+template<typename T >
+ + + + + + + + +
void CXXGRAPH::Partition< T >::setPartitionId (unsigned int partitionId)
+
+ +

Set the Partition ID.

+
Parameters
+ + +
partitionIdthe ID to set
+
+
+ +
+

The documentation for this class was generated from the following file: diff --git a/docs/html/d7/d24/classCXXGRAPH_1_1UndirectedWeightedEdge.html b/docs/html/d7/d24/classCXXGRAPH_1_1UndirectedWeightedEdge.html index 2169c9eb3..6e6206d10 100644 --- a/docs/html/d7/d24/classCXXGRAPH_1_1UndirectedWeightedEdge.html +++ b/docs/html/d7/d24/classCXXGRAPH_1_1UndirectedWeightedEdge.html @@ -23,7 +23,7 @@ Logo
CXXGraph -  0.1.2 +  0.1.3
CXXGraph is a small library, header only, that manages the Graph and it's algorithm in C++
diff --git a/docs/html/d7/d2a/classCXXGRAPH_1_1Edge.html b/docs/html/d7/d2a/classCXXGRAPH_1_1Edge.html index 313c62a30..44fc66925 100644 --- a/docs/html/d7/d2a/classCXXGRAPH_1_1Edge.html +++ b/docs/html/d7/d2a/classCXXGRAPH_1_1Edge.html @@ -23,7 +23,7 @@ Logo
CXXGraph -  0.1.2 +  0.1.3
CXXGraph is a small library, header only, that manages the Graph and it's algorithm in C++
diff --git a/docs/html/d7/d7f/classCXXGRAPH_1_1Edge-members.html b/docs/html/d7/d7f/classCXXGRAPH_1_1Edge-members.html index 7ae62f6f1..ad9f87dd9 100644 --- a/docs/html/d7/d7f/classCXXGRAPH_1_1Edge-members.html +++ b/docs/html/d7/d7f/classCXXGRAPH_1_1Edge-members.html @@ -23,7 +23,7 @@ Logo
CXXGraph -  0.1.2 +  0.1.3
CXXGraph is a small library, header only, that manages the Graph and it's algorithm in C++
diff --git a/docs/html/d7/dc4/classCXXGRAPH_1_1Partition-members.html b/docs/html/d7/dc4/classCXXGRAPH_1_1Partition-members.html index 43726e9ce..307531052 100644 --- a/docs/html/d7/dc4/classCXXGRAPH_1_1Partition-members.html +++ b/docs/html/d7/dc4/classCXXGRAPH_1_1Partition-members.html @@ -23,7 +23,7 @@ Logo
CXXGraph -  0.1.2 +  0.1.3
CXXGraph is a small library, header only, that manages the Graph and it's algorithm in C++
@@ -83,11 +83,11 @@ dijkstra(const Node< T > &source, const Node< T > &target) constCXXGRAPH::Graph< T > E_InputOutputFormat enum nameCXXGRAPH::Graph< T > E_PartitionAlgorithm enum nameCXXGRAPH::Graph< T > - getAdjMatrix() const (defined in CXXGRAPH::Graph< T >)CXXGRAPH::Graph< T > + getAdjMatrix() constCXXGRAPH::Graph< T > getEdge(unsigned long edgeId) const (defined in CXXGRAPH::Graph< T >)CXXGRAPH::Graph< T > getEdgeSet() const (defined in CXXGRAPH::Graph< T >)CXXGRAPH::Graph< T > getNodeSet() const (defined in CXXGRAPH::Graph< T >)CXXGRAPH::Graph< T > - getPartitionId() const (defined in CXXGRAPH::Partition< T >)CXXGRAPH::Partition< T > + getPartitionId() constCXXGRAPH::Partition< T > Graph()=default (defined in CXXGRAPH::Graph< T >)CXXGRAPH::Graph< T > Graph(const std::list< const Edge< T > * > &edgeSet) (defined in CXXGRAPH::Graph< T >)CXXGRAPH::Graph< T > GREEDY_VC enum valueCXXGRAPH::Graph< T > @@ -101,12 +101,12 @@ Partition(unsigned int partitionId) (defined in CXXGRAPH::Partition< T >)CXXGRAPH::Partition< T > Partition(const std::list< const Edge< T > * > &edgeSet) (defined in CXXGRAPH::Partition< T >)CXXGRAPH::Partition< T > Partition(unsigned int partitionId, const std::list< const Edge< T > * > &edgeSet) (defined in CXXGRAPH::Partition< T >)CXXGRAPH::Partition< T > - PartitionAlgorithm typedef (defined in CXXGRAPH::Graph< T >)CXXGRAPH::Graph< T > - partitionGraph(PartitionAlgorithm algorithm, unsigned int numberOfPartitions) constCXXGRAPH::Graph< T > + PartitionAlgorithm typedefCXXGRAPH::Graph< T > + partitionGraph(PartitionAlgorithm algorithm, unsigned int numberOfPartitions) constCXXGRAPH::Graph< T > readFromFile(InputOutputFormat format=InputOutputFormat::STANDARD_CSV, const std::string &workingDir=".", const std::string &OFileName="graph", bool compress=false, bool readNodeFeat=false, bool readEdgeWeight=false)CXXGRAPH::Graph< T > removeEdge(unsigned long edgeId) (defined in CXXGRAPH::Graph< T >)CXXGRAPH::Graph< T > setEdgeSet(std::list< const Edge< T > * > &edgeSet) (defined in CXXGRAPH::Graph< T >)CXXGRAPH::Graph< T > - setPartitionId(unsigned int partitionId) (defined in CXXGRAPH::Partition< T >)CXXGRAPH::Partition< T > + setPartitionId(unsigned int partitionId)CXXGRAPH::Partition< T > STANDARD_CSV enum valueCXXGRAPH::Graph< T > STANDARD_TSV enum valueCXXGRAPH::Graph< T > writeToFile(InputOutputFormat format=InputOutputFormat::STANDARD_CSV, const std::string &workingDir=".", const std::string &OFileName="graph", bool compress=false, bool writeNodeFeat=false, bool writeEdgeWeight=false) constCXXGRAPH::Graph< T > diff --git a/docs/html/d7/de2/classCXXGRAPH_1_1UndirectedWeightedEdge-members.html b/docs/html/d7/de2/classCXXGRAPH_1_1UndirectedWeightedEdge-members.html index d53fca88b..2a49b73cd 100644 --- a/docs/html/d7/de2/classCXXGRAPH_1_1UndirectedWeightedEdge-members.html +++ b/docs/html/d7/de2/classCXXGRAPH_1_1UndirectedWeightedEdge-members.html @@ -23,7 +23,7 @@ Logo
CXXGraph -  0.1.2 +  0.1.3
CXXGraph is a small library, header only, that manages the Graph and it's algorithm in C++
diff --git a/docs/html/d8/d8c/classCXXGRAPH_1_1UndirectedEdge-members.html b/docs/html/d8/d8c/classCXXGRAPH_1_1UndirectedEdge-members.html index 697913ffb..8f41eb668 100644 --- a/docs/html/d8/d8c/classCXXGRAPH_1_1UndirectedEdge-members.html +++ b/docs/html/d8/d8c/classCXXGRAPH_1_1UndirectedEdge-members.html @@ -23,7 +23,7 @@ Logo
CXXGraph -  0.1.2 +  0.1.3
CXXGraph is a small library, header only, that manages the Graph and it's algorithm in C++
diff --git a/docs/html/d8/d91/classCXXGRAPH_1_1Node-members.html b/docs/html/d8/d91/classCXXGRAPH_1_1Node-members.html index 3d8d5c536..fae8b0d9d 100644 --- a/docs/html/d8/d91/classCXXGRAPH_1_1Node-members.html +++ b/docs/html/d8/d91/classCXXGRAPH_1_1Node-members.html @@ -23,7 +23,7 @@ Logo
CXXGraph -  0.1.2 +  0.1.3
CXXGraph is a small library, header only, that manages the Graph and it's algorithm in C++
diff --git a/docs/html/d9/d69/Graph_8hpp_source.html b/docs/html/d9/d69/Graph_8hpp_source.html index 3df5a7ff3..6b4f54875 100644 --- a/docs/html/d9/d69/Graph_8hpp_source.html +++ b/docs/html/d9/d69/Graph_8hpp_source.html @@ -23,7 +23,7 @@ Logo
CXXGraph -  0.1.2 +  0.1.3
CXXGraph is a small library, header only, that manages the Graph and it's algorithm in C++
@@ -88,1592 +88,1807 @@
14 #include <string>
15 #include <functional>
16 #include <fstream>
-
17 
-
18 namespace CXXGRAPH
-
19 {
-
20  //STRING ERROR CONST EXPRESSION
-
21  constexpr char ERR_NO_DIR_OR_UNDIR_EDGE[] = "Edge are neither Directed neither Undirected";
-
22  constexpr char ERR_NO_WEIGHTED_EDGE[] = "Edge are not Weighted";
-
23  constexpr char ERR_DIJ_TARGET_NODE_NOT_REACHABLE[] = "Target Node not Reachable";
-
24  constexpr char ERR_DIJ_TARGET_NODE_NOT_IN_GRAPH[] = "Target Node not inside Graph";
-
25  constexpr char ERR_DIJ_SOURCE_NODE_NOT_IN_GRAPH[] = "Source Node not inside Graph";
-
27  constexpr double INF_DOUBLE = std::numeric_limits<double>::max();
-
28  template <typename T>
-
29  class Node;
-
30  template <typename T>
-
31  class Edge;
-
32  template <typename T>
-
33  class DirectedEdge;
-
34  template <typename T>
-
35  class UndirectedEdge;
-
36  template <typename T>
-
37  class DirectedWeightedEdge;
-
38  template <typename T>
-
39  class UndirectedWeightedEdge;
-
40  template <typename T>
-
41  class Graph;
-
42 
-
43  class Weighted;
-
44 
-
45  template <typename T>
-
46  using AdjacencyMatrix = std::map<const Node<T> *, std::vector<std::pair<const Node<T> *, const Edge<T> *>>>;
+
17 #include <limits.h>
+
18 
+
19 namespace CXXGRAPH
+
20 {
+
21  //STRING ERROR CONST EXPRESSION
+
22  constexpr char ERR_NO_DIR_OR_UNDIR_EDGE[] = "Edge are neither Directed neither Undirected";
+
23  constexpr char ERR_NO_WEIGHTED_EDGE[] = "Edge are not Weighted";
+
24  constexpr char ERR_DIJ_TARGET_NODE_NOT_REACHABLE[] = "Target Node not Reachable";
+
25  constexpr char ERR_DIJ_TARGET_NODE_NOT_IN_GRAPH[] = "Target Node not inside Graph";
+
26  constexpr char ERR_DIJ_SOURCE_NODE_NOT_IN_GRAPH[] = "Source Node not inside Graph";
+
28  constexpr double INF_DOUBLE = std::numeric_limits<double>::max();
+
29  template <typename T>
+
30  class Node;
+
31  template <typename T>
+
32  class Edge;
+
33  template <typename T>
+
34  class DirectedEdge;
+
35  template <typename T>
+
36  class UndirectedEdge;
+
37  template <typename T>
+
38  class DirectedWeightedEdge;
+
39  template <typename T>
+
40  class UndirectedWeightedEdge;
+
41  template <typename T>
+
42  class Graph;
+
43  template <typename T>
+
44  class Partition;
+
45 
+
46  class Weighted;
47 
-
48  template <typename T>
-
49  std::ostream &operator<<(std::ostream &o, const Node<T> &node);
-
50  template <typename T>
-
51  std::ostream &operator<<(std::ostream &o, const Edge<T> &edge);
-
52  template <typename T>
-
53  std::ostream &operator<<(std::ostream &o, const DirectedEdge<T> &edge);
-
54  template <typename T>
-
55  std::ostream &operator<<(std::ostream &o, const UndirectedEdge<T> &edge);
-
56  template <typename T>
-
57  std::ostream &operator<<(std::ostream &o, const DirectedWeightedEdge<T> &edge);
-
58  template <typename T>
-
59  std::ostream &operator<<(std::ostream &o, const UndirectedWeightedEdge<T> &edge);
-
60  template <typename T>
-
61  std::ostream &operator<<(std::ostream &o, const Graph<T> &graph);
-
62  template <typename T>
-
63  std::ostream &operator<<(std::ostream &o, const AdjacencyMatrix<T> &adj);
-
64 
-
65  typedef struct DijkstraResult_struct
-
66  {
-
67  bool success; // TRUE if the function does not return error, FALSE otherwise
-
68  std::string errorMessage; //message of error
-
69  double result; //result (valid only if success is TRUE)
- -
71 
-
72  template <typename T>
-
73  class Node
-
74  {
-
75  private:
-
76  unsigned long id;
-
77  T data;
-
78 
-
79  public:
-
80  Node(const unsigned long id, const T &data);
-
81  ~Node() = default;
-
82  const unsigned long &getId() const;
-
83  const T &getData() const;
-
84  //operator
-
85  bool operator==(const Node<T> &b) const;
-
86  bool operator<(const Node<T> &b) const;
-
87  friend std::ostream &operator<<<>(std::ostream &os, const Node<T> &node);
-
88  };
-
89 
-
90  template <typename T>
-
91  Node<T>::Node(const unsigned long id, const T &data)
-
92  {
-
93  this->id = id;
-
94  this->data = data;
-
95  }
-
96 
-
97  template <typename T>
-
98  const unsigned long &Node<T>::getId() const
-
99  {
-
100  return id;
-
101  }
-
102 
-
103  template <typename T>
-
104  const T &Node<T>::getData() const
-
105  {
-
106  return data;
-
107  }
-
108 
-
109  template <typename T>
-
110  bool Node<T>::operator==(const Node<T> &b) const
-
111  {
-
112  return (this->id == b.id && this->data == b.data);
-
113  }
-
114 
-
115  template <typename T>
-
116  bool Node<T>::operator<(const Node<T> &b) const
-
117  {
-
118  return (this->id < b.id);
-
119  }
-
120 
-
121  class Weighted
-
122  {
-
123  private:
-
124  double weight;
-
125 
-
126  public:
-
127  Weighted();
-
128  Weighted(const double weight);
-
129  virtual ~Weighted() = default;
-
130  double getWeight() const;
-
131  void setWeight(const double weight);
-
132  };
-
133 
-
134  //inline because the implementation of non-template function in header file
-
135  inline Weighted::Weighted()
-
136  {
-
137  weight = 0.0;
-
138  }
-
139 
-
140  //inline because the implementation of non-template function in header file
-
141  inline Weighted::Weighted(const double weight)
-
142  {
-
143  this->weight = weight;
-
144  }
-
145 
-
146  //inline because the implementation of non-template function in header file
-
147  inline double Weighted::getWeight() const
-
148  {
-
149  return weight;
-
150  }
-
151 
-
152  //inline because the implementation of non-template function in header file
-
153  inline void Weighted::setWeight(const double weight)
-
154  {
-
155  this->weight = weight;
-
156  }
-
157 
-
158  template <typename T>
-
159  class Edge
-
160  {
-
161  private:
-
162  unsigned long id;
-
163  std::pair<const Node<T> *, const Node<T> *> nodePair;
-
164 
-
165  public:
-
166  Edge(const unsigned long id, const Node<T> &node1, const Node<T> &node2);
-
167  Edge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair);
-
168  virtual ~Edge() = default;
-
169  const unsigned long &getId() const;
-
170  const std::pair<const Node<T> *, const Node<T> *> &getNodePair() const;
-
171  virtual const std::optional<bool> isDirected() const;
-
172  virtual const std::optional<bool> isWeighted() const;
-
173  //operator
-
174  virtual bool operator==(const Edge<T> &b) const;
-
175  bool operator<(const Edge<T> &b) const;
-
176  //operator DirectedEdge<T>() const { return DirectedEdge<T>(id, nodePair); }
-
177  //operator UndirectedEdge<T>() const { return UndirectedEdge<T>(id, nodePair); }
+ +
50  {
+
51  bool success; // TRUE if the function does not return error, FALSE otherwise
+
52  std::string errorMessage; //message of error
+
53  double result; //result (valid only if success is TRUE)
+
54  };
+ +
56 
+ +
59  {
+
60  unsigned int numberOfPartitions; // The number of Partitions
+
61  unsigned int numberOfNodes; // The number of Nodes
+
62  unsigned int replicatedNodesCount; // The number of Nodes that are replicated
+
63  unsigned int numberOfEdges; // The number of edges
+
64  unsigned int replicatedEdgesCount; // The number of edges that are replicated
+
65  unsigned int maxEdgesLoad; // Maximum edges load of the partitions
+
66  unsigned int minEdgesLoad; // Minimun edges load of the partitions
+
67  unsigned int maxNodesLoad; // Maximum nodes load of the partitions
+
68  unsigned int minNodesLoad; // Minimun nodes load of the partitions
+
69  double balanceEdgesFactor; // The balance edges factor of the partitions (maxEdgesLoad - minEdgesLoad) / (maxEdgesLoad), 0 is the optimal partitioning
+
70  double balanceNodesFactor; // The balance edges factor of the partitions (maxNodesLoad - minNodesLoad) / (maxNodesLoad), 0 is the optimal partitioning
+
71  double nodesReplicationFactor; // The replication factor of the Nodes (replicatedNodesCount / numberOfNodes), 1 is the optimal partitioning
+
72  double edgesReplicationFactor; // The replication factor of the edges (replicatedEdgesCount / numberOfEdges), 1 is the optimal partitioning
+
73 
+
74  friend std::ostream &operator<<(std::ostream &os, const PartitioningStats_struct &partitionStats)
+
75  {
+
76  os << "Partitioning Stats:\n";
+
77  os << "\tNumber of Partitions: " << partitionStats.numberOfPartitions << "\n";
+
78  os << "\tNumber of Nodes: " << partitionStats.numberOfNodes << "\n";
+
79  os << "\tNumber of Edges: " << partitionStats.numberOfEdges << "\n";
+
80  os << "\tNumber of Nodes Replica: " << partitionStats.replicatedNodesCount << "\n";
+
81  os << "\tNumber of Edges Replica: " << partitionStats.replicatedEdgesCount << "\n";
+
82  os << "\tNodes Replication Factor: " << partitionStats.nodesReplicationFactor << "\n";
+
83  os << "\tEdges Replication Factor: " << partitionStats.edgesReplicationFactor << "\n";
+
84  os << "\tMax Edges Load: " << partitionStats.maxEdgesLoad << "\n";
+
85  os << "\tMin Edges Load: " << partitionStats.minEdgesLoad << "\n";
+
86  os << "\tBalance Edges Factor: " << partitionStats.balanceEdgesFactor << "\n";
+
87  os << "\tMax Nodes Load: " << partitionStats.maxNodesLoad << "\n";
+
88  os << "\tMin Nodes Load: " << partitionStats.minNodesLoad << "\n";
+
89  os << "\tBalance Nodes Factor: " << partitionStats.balanceNodesFactor << "\n";
+
90  return os;
+
91  }
+
92  };
+ +
94 
+
95  template <typename T>
+
96  using AdjacencyMatrix = std::map<const Node<T> *, std::vector<std::pair<const Node<T> *, const Edge<T> *>>>;
+
97 
+
98  template <typename T>
+
99  std::ostream &operator<<(std::ostream &o, const Node<T> &node);
+
100  template <typename T>
+
101  std::ostream &operator<<(std::ostream &o, const Edge<T> &edge);
+
102  template <typename T>
+
103  std::ostream &operator<<(std::ostream &o, const DirectedEdge<T> &edge);
+
104  template <typename T>
+
105  std::ostream &operator<<(std::ostream &o, const UndirectedEdge<T> &edge);
+
106  template <typename T>
+
107  std::ostream &operator<<(std::ostream &o, const DirectedWeightedEdge<T> &edge);
+
108  template <typename T>
+
109  std::ostream &operator<<(std::ostream &o, const UndirectedWeightedEdge<T> &edge);
+
110  template <typename T>
+
111  std::ostream &operator<<(std::ostream &o, const Graph<T> &graph);
+
112  template <typename T>
+
113  std::ostream &operator<<(std::ostream &o, const AdjacencyMatrix<T> &adj);
+
114  template <typename T>
+
115  using PartitionMap = std::map<unsigned int, Partition<T> *>;
+
116 
+
117  template <typename T>
+
118  class Node
+
119  {
+
120  private:
+
121  unsigned long id;
+
122  T data;
+
123 
+
124  public:
+
125  Node(const unsigned long id, const T &data);
+
126  ~Node() = default;
+
127  const unsigned long &getId() const;
+
128  const T &getData() const;
+
129  //operator
+
130  bool operator==(const Node<T> &b) const;
+
131  bool operator<(const Node<T> &b) const;
+
132  friend std::ostream &operator<<<>(std::ostream &os, const Node<T> &node);
+
133  };
+
134 
+
135  template <typename T>
+
136  Node<T>::Node(const unsigned long id, const T &data)
+
137  {
+
138  this->id = id;
+
139  this->data = data;
+
140  }
+
141 
+
142  template <typename T>
+
143  const unsigned long &Node<T>::getId() const
+
144  {
+
145  return id;
+
146  }
+
147 
+
148  template <typename T>
+
149  const T &Node<T>::getData() const
+
150  {
+
151  return data;
+
152  }
+
153 
+
154  template <typename T>
+
155  bool Node<T>::operator==(const Node<T> &b) const
+
156  {
+
157  return (this->id == b.id && this->data == b.data);
+
158  }
+
159 
+
160  template <typename T>
+
161  bool Node<T>::operator<(const Node<T> &b) const
+
162  {
+
163  return (this->id < b.id);
+
164  }
+
165 
+
166  class Weighted
+
167  {
+
168  private:
+
169  double weight;
+
170 
+
171  public:
+
172  Weighted();
+
173  Weighted(const double weight);
+
174  virtual ~Weighted() = default;
+
175  double getWeight() const;
+
176  void setWeight(const double weight);
+
177  };
178 
-
179  friend std::ostream &operator<<<>(std::ostream &os, const Edge<T> &edge);
-
180  };
-
181 
-
182  template <typename T>
-
183  Edge<T>::Edge(const unsigned long id, const Node<T> &node1, const Node<T> &node2) : nodePair(&node1, &node2)
-
184  {
-
185  this->id = id;
-
186  }
-
187 
-
188  template <typename T>
-
189  Edge<T>::Edge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair) : nodePair(nodepair)
-
190  {
-
191  this->id = id;
-
192  }
-
193 
-
194  template <typename T>
-
195  const unsigned long &Edge<T>::getId() const
-
196  {
-
197  return id;
-
198  }
-
199 
-
200  template <typename T>
-
201  const std::pair<const Node<T> *, const Node<T> *> &Edge<T>::getNodePair() const
-
202  {
-
203  return nodePair;
-
204  }
-
205 
-
206  template <typename T>
-
207  const std::optional<bool> Edge<T>::isDirected() const
-
208  {
-
209  return std::nullopt;
-
210  }
-
211 
-
212  template <typename T>
-
213  const std::optional<bool> Edge<T>::isWeighted() const
-
214  {
-
215  return std::nullopt;
-
216  }
-
217 
-
218  template <typename T>
-
219  bool Edge<T>::operator==(const Edge<T> &b) const
-
220  {
-
221  return (this->id == b.id && this->nodePair == b.nodePair);
-
222  }
+
179  //inline because the implementation of non-template function in header file
+
180  inline Weighted::Weighted()
+
181  {
+
182  weight = 0.0;
+
183  }
+
184 
+
185  //inline because the implementation of non-template function in header file
+
186  inline Weighted::Weighted(const double weight)
+
187  {
+
188  this->weight = weight;
+
189  }
+
190 
+
191  //inline because the implementation of non-template function in header file
+
192  inline double Weighted::getWeight() const
+
193  {
+
194  return weight;
+
195  }
+
196 
+
197  //inline because the implementation of non-template function in header file
+
198  inline void Weighted::setWeight(const double weight)
+
199  {
+
200  this->weight = weight;
+
201  }
+
202 
+
203  template <typename T>
+
204  class Edge
+
205  {
+
206  private:
+
207  unsigned long id;
+
208  std::pair<const Node<T> *, const Node<T> *> nodePair;
+
209 
+
210  public:
+
211  Edge(const unsigned long id, const Node<T> &node1, const Node<T> &node2);
+
212  Edge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair);
+
213  virtual ~Edge() = default;
+
214  const unsigned long &getId() const;
+
215  const std::pair<const Node<T> *, const Node<T> *> &getNodePair() const;
+
216  virtual const std::optional<bool> isDirected() const;
+
217  virtual const std::optional<bool> isWeighted() const;
+
218  //operator
+
219  virtual bool operator==(const Edge<T> &b) const;
+
220  bool operator<(const Edge<T> &b) const;
+
221  //operator DirectedEdge<T>() const { return DirectedEdge<T>(id, nodePair); }
+
222  //operator UndirectedEdge<T>() const { return UndirectedEdge<T>(id, nodePair); }
223 
-
224  template <typename T>
-
225  bool Edge<T>::operator<(const Edge<T> &b) const
-
226  {
-
227  return (this->id < b.id);
-
228  }
-
229 
-
230  template <typename T>
-
231  class DirectedEdge : public Edge<T>
-
232  {
-
233  public:
-
234  DirectedEdge(const unsigned long id, const Node<T> &node1, const Node<T> &node2);
-
235  DirectedEdge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair);
-
236  DirectedEdge(const Edge<T> &edge);
-
237  virtual ~DirectedEdge() = default;
-
238  const Node<T> &getFrom() const;
-
239  const Node<T> &getTo() const;
-
240  const std::optional<bool> isDirected() const override;
-
241  virtual const std::optional<bool> isWeighted() const override;
-
242  //operator
-
243  explicit operator UndirectedEdge<T>() const { return UndirectedEdge<T>(Edge<T>::getId(), Edge<T>::getNodePair()); }
+
224  friend std::ostream &operator<<<>(std::ostream &os, const Edge<T> &edge);
+
225  };
+
226 
+
227  template <typename T>
+
228  Edge<T>::Edge(const unsigned long id, const Node<T> &node1, const Node<T> &node2) : nodePair(&node1, &node2)
+
229  {
+
230  this->id = id;
+
231  }
+
232 
+
233  template <typename T>
+
234  Edge<T>::Edge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair) : nodePair(nodepair)
+
235  {
+
236  this->id = id;
+
237  }
+
238 
+
239  template <typename T>
+
240  const unsigned long &Edge<T>::getId() const
+
241  {
+
242  return id;
+
243  }
244 
-
245  friend std::ostream &operator<<<>(std::ostream &os, const DirectedEdge<T> &edge);
-
246  };
-
247 
-
248  template <typename T>
-
249  DirectedEdge<T>::DirectedEdge(const unsigned long id, const Node<T> &node1, const Node<T> &node2) : Edge<T>(id, node1, node2)
-
250  {
-
251  }
-
252 
-
253  template <typename T>
-
254  DirectedEdge<T>::DirectedEdge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair) : Edge<T>(id, nodepair)
-
255  {
-
256  }
-
257 
-
258  template <typename T>
-
259  DirectedEdge<T>::DirectedEdge(const Edge<T> &edge) : DirectedEdge(edge.getId(), *(edge.getNodePair().first), *(edge.getNodePair().second))
-
260  {
+
245  template <typename T>
+
246  const std::pair<const Node<T> *, const Node<T> *> &Edge<T>::getNodePair() const
+
247  {
+
248  return nodePair;
+
249  }
+
250 
+
251  template <typename T>
+
252  const std::optional<bool> Edge<T>::isDirected() const
+
253  {
+
254  return std::nullopt;
+
255  }
+
256 
+
257  template <typename T>
+
258  const std::optional<bool> Edge<T>::isWeighted() const
+
259  {
+
260  return std::nullopt;
261  }
262 
263  template <typename T>
-
264  const Node<T> &DirectedEdge<T>::getFrom() const
+
264  bool Edge<T>::operator==(const Edge<T> &b) const
265  {
-
266  return *(Edge<T>::getNodePair().first);
+
266  return (this->id == b.id && this->nodePair == b.nodePair);
267  }
268 
269  template <typename T>
-
270  const Node<T> &DirectedEdge<T>::getTo() const
+
270  bool Edge<T>::operator<(const Edge<T> &b) const
271  {
-
272  return *(Edge<T>::getNodePair().second);
+
272  return (this->id < b.id);
273  }
274 
275  template <typename T>
-
276  const std::optional<bool> DirectedEdge<T>::isDirected() const
-
277  {
-
278  return true;
-
279  }
-
280 
-
281  template <typename T>
-
282  const std::optional<bool> DirectedEdge<T>::isWeighted() const
-
283  {
-
284  return false;
-
285  }
-
286 
-
287  template <typename T>
-
288  class UndirectedEdge : public Edge<T>
-
289  {
-
290  public:
-
291  UndirectedEdge(const unsigned long id, const Node<T> &node1, const Node<T> &node2);
-
292  UndirectedEdge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair);
-
293  UndirectedEdge(const Edge<T> &edge);
-
294  virtual ~UndirectedEdge() = default;
-
295  const Node<T> &getNode1() const;
-
296  const Node<T> &getNode2() const;
-
297  const std::optional<bool> isDirected() const override;
-
298  const std::optional<bool> isWeighted() const override;
-
299  //operator
-
300  explicit operator DirectedEdge<T>() const { return DirectedEdge<T>(Edge<T>::getId(), Edge<T>::getNodePair()); }
-
301 
-
302  friend std::ostream &operator<<<>(std::ostream &os, const UndirectedEdge<T> &edge);
-
303  };
-
304 
-
305  template <typename T>
-
306  UndirectedEdge<T>::UndirectedEdge(const unsigned long id, const Node<T> &node1, const Node<T> &node2) : Edge<T>(id, node1, node2)
-
307  {
-
308  }
-
309 
-
310  template <typename T>
-
311  UndirectedEdge<T>::UndirectedEdge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair) : Edge<T>(id, nodepair)
-
312  {
-
313  }
-
314 
-
315  template <typename T>
-
316  UndirectedEdge<T>::UndirectedEdge(const Edge<T> &edge) : UndirectedEdge(edge.getId(), *(edge.getNodePair().first), *(edge.getNodePair().second))
-
317  {
+
276  class DirectedEdge : public Edge<T>
+
277  {
+
278  public:
+
279  DirectedEdge(const unsigned long id, const Node<T> &node1, const Node<T> &node2);
+
280  DirectedEdge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair);
+
281  DirectedEdge(const Edge<T> &edge);
+
282  virtual ~DirectedEdge() = default;
+
283  const Node<T> &getFrom() const;
+
284  const Node<T> &getTo() const;
+
285  const std::optional<bool> isDirected() const override;
+
286  virtual const std::optional<bool> isWeighted() const override;
+
287  //operator
+
288  explicit operator UndirectedEdge<T>() const { return UndirectedEdge<T>(Edge<T>::getId(), Edge<T>::getNodePair()); }
+
289 
+
290  friend std::ostream &operator<<<>(std::ostream &os, const DirectedEdge<T> &edge);
+
291  };
+
292 
+
293  template <typename T>
+
294  DirectedEdge<T>::DirectedEdge(const unsigned long id, const Node<T> &node1, const Node<T> &node2) : Edge<T>(id, node1, node2)
+
295  {
+
296  }
+
297 
+
298  template <typename T>
+
299  DirectedEdge<T>::DirectedEdge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair) : Edge<T>(id, nodepair)
+
300  {
+
301  }
+
302 
+
303  template <typename T>
+
304  DirectedEdge<T>::DirectedEdge(const Edge<T> &edge) : DirectedEdge(edge.getId(), *(edge.getNodePair().first), *(edge.getNodePair().second))
+
305  {
+
306  }
+
307 
+
308  template <typename T>
+
309  const Node<T> &DirectedEdge<T>::getFrom() const
+
310  {
+
311  return *(Edge<T>::getNodePair().first);
+
312  }
+
313 
+
314  template <typename T>
+
315  const Node<T> &DirectedEdge<T>::getTo() const
+
316  {
+
317  return *(Edge<T>::getNodePair().second);
318  }
319 
320  template <typename T>
-
321  const Node<T> &UndirectedEdge<T>::getNode1() const
+
321  const std::optional<bool> DirectedEdge<T>::isDirected() const
322  {
-
323  return *(Edge<T>::getNodePair().first);
+
323  return true;
324  }
325 
326  template <typename T>
-
327  const Node<T> &UndirectedEdge<T>::getNode2() const
+
327  const std::optional<bool> DirectedEdge<T>::isWeighted() const
328  {
-
329  return *(Edge<T>::getNodePair().second);
+
329  return false;
330  }
331 
332  template <typename T>
-
333  const std::optional<bool> UndirectedEdge<T>::isDirected() const
-
334  {
-
335  return false;
-
336  }
-
337 
-
338  template <typename T>
-
339  const std::optional<bool> UndirectedEdge<T>::isWeighted() const
-
340  {
-
341  return false;
-
342  }
-
343 
-
344  template <typename T>
-
345  class DirectedWeightedEdge : public DirectedEdge<T>, public Weighted
-
346  {
-
347  public:
-
348  DirectedWeightedEdge(const unsigned long id, const Node<T> &node1, const Node<T> &node2, const double weight);
-
349  DirectedWeightedEdge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair, const double weight);
-
350  DirectedWeightedEdge(const DirectedEdge<T> &edge, const double weight);
-
351  DirectedWeightedEdge(const Edge<T> &edge, const double weight);
- -
353  DirectedWeightedEdge(const Edge<T> &edge);
- -
355  virtual ~DirectedWeightedEdge() = default;
-
356  const std::optional<bool> isWeighted() const override;
-
357  //operator
-
358  explicit operator UndirectedWeightedEdge<T>() const { return UndirectedWeightedEdge<T>(Edge<T>::getId(), Edge<T>::getNodePair(), Weighted::getWeight()); }
+
333  class UndirectedEdge : public Edge<T>
+
334  {
+
335  public:
+
336  UndirectedEdge(const unsigned long id, const Node<T> &node1, const Node<T> &node2);
+
337  UndirectedEdge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair);
+
338  UndirectedEdge(const Edge<T> &edge);
+
339  virtual ~UndirectedEdge() = default;
+
340  const Node<T> &getNode1() const;
+
341  const Node<T> &getNode2() const;
+
342  const std::optional<bool> isDirected() const override;
+
343  const std::optional<bool> isWeighted() const override;
+
344  //operator
+
345  explicit operator DirectedEdge<T>() const { return DirectedEdge<T>(Edge<T>::getId(), Edge<T>::getNodePair()); }
+
346 
+
347  friend std::ostream &operator<<<>(std::ostream &os, const UndirectedEdge<T> &edge);
+
348  };
+
349 
+
350  template <typename T>
+
351  UndirectedEdge<T>::UndirectedEdge(const unsigned long id, const Node<T> &node1, const Node<T> &node2) : Edge<T>(id, node1, node2)
+
352  {
+
353  }
+
354 
+
355  template <typename T>
+
356  UndirectedEdge<T>::UndirectedEdge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair) : Edge<T>(id, nodepair)
+
357  {
+
358  }
359 
-
360  friend std::ostream &operator<<<>(std::ostream &os, const DirectedWeightedEdge<T> &edge);
-
361  };
-
362 
-
363  template <typename T>
-
364  DirectedWeightedEdge<T>::DirectedWeightedEdge(const unsigned long id, const Node<T> &node1, const Node<T> &node2, const double weight) : DirectedEdge<T>(id, node1, node2), Weighted(weight)
-
365  {
-
366  }
-
367 
-
368  template <typename T>
-
369  DirectedWeightedEdge<T>::DirectedWeightedEdge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair, const double weight) : DirectedEdge<T>(id, nodepair), Weighted(weight)
-
370  {
-
371  }
-
372 
-
373  template <typename T>
-
374  DirectedWeightedEdge<T>::DirectedWeightedEdge(const DirectedEdge<T> &edge, const double weight) : DirectedEdge<T>(edge), Weighted(weight)
-
375  {
-
376  }
-
377 
-
378  template <typename T>
-
379  DirectedWeightedEdge<T>::DirectedWeightedEdge(const Edge<T> &edge, const double weight) : DirectedEdge<T>(edge), Weighted(weight)
-
380  {
+
360  template <typename T>
+
361  UndirectedEdge<T>::UndirectedEdge(const Edge<T> &edge) : UndirectedEdge(edge.getId(), *(edge.getNodePair().first), *(edge.getNodePair().second))
+
362  {
+
363  }
+
364 
+
365  template <typename T>
+
366  const Node<T> &UndirectedEdge<T>::getNode1() const
+
367  {
+
368  return *(Edge<T>::getNodePair().first);
+
369  }
+
370 
+
371  template <typename T>
+
372  const Node<T> &UndirectedEdge<T>::getNode2() const
+
373  {
+
374  return *(Edge<T>::getNodePair().second);
+
375  }
+
376 
+
377  template <typename T>
+
378  const std::optional<bool> UndirectedEdge<T>::isDirected() const
+
379  {
+
380  return false;
381  }
382 
383  template <typename T>
-
384  DirectedWeightedEdge<T>::DirectedWeightedEdge(const DirectedEdge<T> &edge) : DirectedEdge<T>(edge), Weighted()
-
385  {
-
386  }
-
387 
-
388  template <typename T>
-
389  DirectedWeightedEdge<T>::DirectedWeightedEdge(const Edge<T> &edge) : DirectedEdge<T>(edge), Weighted()
-
390  {
-
391  }
-
392 
-
393  template <typename T>
-
394  DirectedWeightedEdge<T>::DirectedWeightedEdge(const UndirectedWeightedEdge<T> &edge) : DirectedEdge<T>(edge), Weighted(edge.getWeight())
-
395  {
-
396  }
-
397 
-
398  template <typename T>
-
399  const std::optional<bool> DirectedWeightedEdge<T>::isWeighted() const
-
400  {
-
401  return true;
-
402  }
-
403 
-
404  template <typename T>
- -
406  {
-
407  public:
-
408  UndirectedWeightedEdge(const unsigned long id, const Node<T> &node1, const Node<T> &node2, const double weight);
-
409  UndirectedWeightedEdge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair, const double weight);
-
410  UndirectedWeightedEdge(const UndirectedEdge<T> &edge, const double weight);
-
411  UndirectedWeightedEdge(const Edge<T> &edge, const double weight);
- -
413  UndirectedWeightedEdge(const Edge<T> &edge);
- -
415  virtual ~UndirectedWeightedEdge() = default;
-
416  const std::optional<bool> isWeighted() const override;
-
417  //operator
-
418  explicit operator DirectedWeightedEdge<T>() const { return DirectedWeightedEdge<T>(Edge<T>::getId(), Edge<T>::getNodePair(), Weighted::getWeight()); }
-
419 
-
420  friend std::ostream &operator<<<>(std::ostream &os, const UndirectedWeightedEdge<T> &edge);
-
421  };
+
384  const std::optional<bool> UndirectedEdge<T>::isWeighted() const
+
385  {
+
386  return false;
+
387  }
+
388 
+
389  template <typename T>
+
390  class DirectedWeightedEdge : public DirectedEdge<T>, public Weighted
+
391  {
+
392  public:
+
393  DirectedWeightedEdge(const unsigned long id, const Node<T> &node1, const Node<T> &node2, const double weight);
+
394  DirectedWeightedEdge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair, const double weight);
+
395  DirectedWeightedEdge(const DirectedEdge<T> &edge, const double weight);
+
396  DirectedWeightedEdge(const Edge<T> &edge, const double weight);
+ +
398  DirectedWeightedEdge(const Edge<T> &edge);
+ +
400  virtual ~DirectedWeightedEdge() = default;
+
401  const std::optional<bool> isWeighted() const override;
+
402  //operator
+
403  explicit operator UndirectedWeightedEdge<T>() const { return UndirectedWeightedEdge<T>(Edge<T>::getId(), Edge<T>::getNodePair(), Weighted::getWeight()); }
+
404 
+
405  friend std::ostream &operator<<<>(std::ostream &os, const DirectedWeightedEdge<T> &edge);
+
406  };
+
407 
+
408  template <typename T>
+
409  DirectedWeightedEdge<T>::DirectedWeightedEdge(const unsigned long id, const Node<T> &node1, const Node<T> &node2, const double weight) : DirectedEdge<T>(id, node1, node2), Weighted(weight)
+
410  {
+
411  }
+
412 
+
413  template <typename T>
+
414  DirectedWeightedEdge<T>::DirectedWeightedEdge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair, const double weight) : DirectedEdge<T>(id, nodepair), Weighted(weight)
+
415  {
+
416  }
+
417 
+
418  template <typename T>
+
419  DirectedWeightedEdge<T>::DirectedWeightedEdge(const DirectedEdge<T> &edge, const double weight) : DirectedEdge<T>(edge), Weighted(weight)
+
420  {
+
421  }
422 
423  template <typename T>
-
424  UndirectedWeightedEdge<T>::UndirectedWeightedEdge(const unsigned long id, const Node<T> &node1, const Node<T> &node2, const double weight) : UndirectedEdge<T>(id, node1, node2), Weighted(weight)
+
424  DirectedWeightedEdge<T>::DirectedWeightedEdge(const Edge<T> &edge, const double weight) : DirectedEdge<T>(edge), Weighted(weight)
425  {
426  }
427 
428  template <typename T>
-
429  UndirectedWeightedEdge<T>::UndirectedWeightedEdge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair, const double weight) : UndirectedEdge<T>(id, nodepair), Weighted(weight)
+
429  DirectedWeightedEdge<T>::DirectedWeightedEdge(const DirectedEdge<T> &edge) : DirectedEdge<T>(edge), Weighted()
430  {
431  }
432 
433  template <typename T>
-
434  UndirectedWeightedEdge<T>::UndirectedWeightedEdge(const UndirectedEdge<T> &edge, const double weight) : UndirectedEdge<T>(edge), Weighted(weight)
+
434  DirectedWeightedEdge<T>::DirectedWeightedEdge(const Edge<T> &edge) : DirectedEdge<T>(edge), Weighted()
435  {
436  }
437 
438  template <typename T>
-
439  UndirectedWeightedEdge<T>::UndirectedWeightedEdge(const Edge<T> &edge, const double weight) : UndirectedEdge<T>(edge), Weighted(weight)
+
439  DirectedWeightedEdge<T>::DirectedWeightedEdge(const UndirectedWeightedEdge<T> &edge) : DirectedEdge<T>(edge), Weighted(edge.getWeight())
440  {
441  }
442 
443  template <typename T>
-
444  UndirectedWeightedEdge<T>::UndirectedWeightedEdge(const UndirectedEdge<T> &edge) : UndirectedEdge<T>(edge), Weighted()
-
445  {
-
446  }
-
447 
-
448  template <typename T>
-
449  UndirectedWeightedEdge<T>::UndirectedWeightedEdge(const Edge<T> &edge) : UndirectedEdge<T>(edge), Weighted()
-
450  {
-
451  }
-
452 
-
453  template <typename T>
-
454  UndirectedWeightedEdge<T>::UndirectedWeightedEdge(const DirectedWeightedEdge<T> &edge) : UndirectedEdge<T>(edge), Weighted(edge.getWeight())
-
455  {
-
456  }
-
457 
-
458  template <typename T>
-
459  const std::optional<bool> UndirectedWeightedEdge<T>::isWeighted() const
-
460  {
-
461  return true;
-
462  }
-
463 
-
464  template <typename T>
-
465  class Partition;
-
466  template <typename T>
-
467  class Graph
-
468  {
-
469  private:
-
470  std::list<const Edge<T> *> edgeSet;
-
471  void addElementToAdjMatrix(AdjacencyMatrix<T> &adjMatrix, const Node<T> *nodeFrom, const Node<T> *nodeTo, const Edge<T> *edge) const;
-
472  int writeToStandardFile_csv(const std::string &workingDir, const std::string &OFileName, bool compress, bool writeNodeFeat, bool writeEdgeWeight) const;
-
473  int readFromStandardFile_csv(const std::string &workingDir, const std::string &OFileName, bool compress, bool readNodeFeat, bool readEdgeWeight);
-
474  int writeToStandardFile_tsv(const std::string &workingDir, const std::string &OFileName, bool compress, bool writeNodeFeat, bool writeEdgeWeight) const;
-
475  int readFromStandardFile_tsv(const std::string &workingDir, const std::string &OFileName, bool compress, bool readNodeFeat, bool readEdgeWeight);
-
476  void recreateGraphFromReadFiles(std::map<unsigned long, std::pair<unsigned long, unsigned long>> &edgeMap, std::map<unsigned long, bool> &edgeDirectedMap, std::map<unsigned long, T> &nodeFeatMap, std::map<unsigned long, double> &edgeWeightMap);
-
477  void greedyPartition(std::map<unsigned int, Partition<T> *> &partitionMap) const;
-
478 
-
479  public:
-
481  typedef enum E_InputOutputFormat
-
482  {
- - -
485  OUT_1,
-
486  OUT_2
- -
488 
-
489  typedef enum E_PartitionAlgorithm
-
490  {
- -
492  ALG_1,
-
493  ALG_2
-
494  } PartitionAlgorithm;
-
495 
-
496  Graph() = default;
-
497  Graph(const std::list<const Edge<T> *> &edgeSet);
-
498  ~Graph() = default;
-
499  const std::list<const Edge<T> *> &getEdgeSet() const;
-
500  void setEdgeSet(std::list<const Edge<T> *> &edgeSet);
-
501  void addEdge(const Edge<T> *edge);
-
502  void removeEdge(unsigned long edgeId);
-
503  const std::list<const Node<T> *> getNodeSet() const;
-
504  const std::optional<const Edge<T> *> getEdge(unsigned long edgeId) const;
-
505  /*This function generate a list of adjacency matrix with every element of the matrix
-
506  * contain the node where is directed the link and the Edge corrispondent to the link
-
507  */
-
508  const AdjacencyMatrix<T> getAdjMatrix() const;
-
520  const DijkstraResult dijkstra(const Node<T> &source, const Node<T> &target) const;
-
530  const std::vector<Node<T>> breadth_first_search(const Node<T> &start) const;
-
540  const std::vector<Node<T>> depth_first_search(const Node<T> &start) const;
+
444  const std::optional<bool> DirectedWeightedEdge<T>::isWeighted() const
+
445  {
+
446  return true;
+
447  }
+
448 
+
449  template <typename T>
+ +
451  {
+
452  public:
+
453  UndirectedWeightedEdge(const unsigned long id, const Node<T> &node1, const Node<T> &node2, const double weight);
+
454  UndirectedWeightedEdge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair, const double weight);
+
455  UndirectedWeightedEdge(const UndirectedEdge<T> &edge, const double weight);
+
456  UndirectedWeightedEdge(const Edge<T> &edge, const double weight);
+ +
458  UndirectedWeightedEdge(const Edge<T> &edge);
+ +
460  virtual ~UndirectedWeightedEdge() = default;
+
461  const std::optional<bool> isWeighted() const override;
+
462  //operator
+
463  explicit operator DirectedWeightedEdge<T>() const { return DirectedWeightedEdge<T>(Edge<T>::getId(), Edge<T>::getNodePair(), Weighted::getWeight()); }
+
464 
+
465  friend std::ostream &operator<<<>(std::ostream &os, const UndirectedWeightedEdge<T> &edge);
+
466  };
+
467 
+
468  template <typename T>
+
469  UndirectedWeightedEdge<T>::UndirectedWeightedEdge(const unsigned long id, const Node<T> &node1, const Node<T> &node2, const double weight) : UndirectedEdge<T>(id, node1, node2), Weighted(weight)
+
470  {
+
471  }
+
472 
+
473  template <typename T>
+
474  UndirectedWeightedEdge<T>::UndirectedWeightedEdge(const unsigned long id, const std::pair<const Node<T> *, const Node<T> *> &nodepair, const double weight) : UndirectedEdge<T>(id, nodepair), Weighted(weight)
+
475  {
+
476  }
+
477 
+
478  template <typename T>
+
479  UndirectedWeightedEdge<T>::UndirectedWeightedEdge(const UndirectedEdge<T> &edge, const double weight) : UndirectedEdge<T>(edge), Weighted(weight)
+
480  {
+
481  }
+
482 
+
483  template <typename T>
+
484  UndirectedWeightedEdge<T>::UndirectedWeightedEdge(const Edge<T> &edge, const double weight) : UndirectedEdge<T>(edge), Weighted(weight)
+
485  {
+
486  }
+
487 
+
488  template <typename T>
+
489  UndirectedWeightedEdge<T>::UndirectedWeightedEdge(const UndirectedEdge<T> &edge) : UndirectedEdge<T>(edge), Weighted()
+
490  {
+
491  }
+
492 
+
493  template <typename T>
+
494  UndirectedWeightedEdge<T>::UndirectedWeightedEdge(const Edge<T> &edge) : UndirectedEdge<T>(edge), Weighted()
+
495  {
+
496  }
+
497 
+
498  template <typename T>
+
499  UndirectedWeightedEdge<T>::UndirectedWeightedEdge(const DirectedWeightedEdge<T> &edge) : UndirectedEdge<T>(edge), Weighted(edge.getWeight())
+
500  {
+
501  }
+
502 
+
503  template <typename T>
+
504  const std::optional<bool> UndirectedWeightedEdge<T>::isWeighted() const
+
505  {
+
506  return true;
+
507  }
+
508 
+
509  template <typename T>
+
510  class Partition;
+
511  template <typename T>
+
512  class Graph
+
513  {
+
514  private:
+
515  std::list<const Edge<T> *> edgeSet;
+
516  void addElementToAdjMatrix(AdjacencyMatrix<T> &adjMatrix, const Node<T> *nodeFrom, const Node<T> *nodeTo, const Edge<T> *edge) const;
+
517  int writeToStandardFile_csv(const std::string &workingDir, const std::string &OFileName, bool compress, bool writeNodeFeat, bool writeEdgeWeight) const;
+
518  int readFromStandardFile_csv(const std::string &workingDir, const std::string &OFileName, bool compress, bool readNodeFeat, bool readEdgeWeight);
+
519  int writeToStandardFile_tsv(const std::string &workingDir, const std::string &OFileName, bool compress, bool writeNodeFeat, bool writeEdgeWeight) const;
+
520  int readFromStandardFile_tsv(const std::string &workingDir, const std::string &OFileName, bool compress, bool readNodeFeat, bool readEdgeWeight);
+
521  void recreateGraphFromReadFiles(std::map<unsigned long, std::pair<unsigned long, unsigned long>> &edgeMap, std::map<unsigned long, bool> &edgeDirectedMap, std::map<unsigned long, T> &nodeFeatMap, std::map<unsigned long, double> &edgeWeightMap);
+
522  void greedyPartition(PartitionMap<T> &partitionMap) const;
+
523 
+
524  public:
+
526  typedef enum E_InputOutputFormat
+
527  {
+ + +
530  OUT_1,
+
531  OUT_2
+ +
533 
+
535  typedef enum E_PartitionAlgorithm
+
536  {
+ +
538  ALG_1,
+
539  ALG_2
+
541 
-
549  bool isCyclicDirectedGraphDFS() const;
-
550 
-
558  bool isCyclicDirectedGraphBFS() const;
-
559 
-
566  bool isDirectedGraph() const;
-
567 
-
580  int writeToFile(InputOutputFormat format = InputOutputFormat::STANDARD_CSV, const std::string &workingDir = ".", const std::string &OFileName = "graph", bool compress = false, bool writeNodeFeat = false, bool writeEdgeWeight = false) const;
-
581 
-
594  int readFromFile(InputOutputFormat format = InputOutputFormat::STANDARD_CSV, const std::string &workingDir = ".", const std::string &OFileName = "graph", bool compress = false, bool readNodeFeat = false, bool readEdgeWeight = false);
-
595 
-
604  std::map<unsigned int, Partition<T> *> partitionGraph(PartitionAlgorithm algorithm, unsigned int numberOfPartitions) const;
-
605 
-
606  friend std::ostream &operator<<<>(std::ostream &os, const Graph<T> &graph);
-
607  friend std::ostream &operator<<<>(std::ostream &os, const AdjacencyMatrix<T> &adj);
-
608  };
-
609 
-
610  template <typename T>
-
611  Graph<T>::Graph(const std::list<const Edge<T> *> &edgeSet)
-
612  {
-
613  for (auto edgeSetIt = edgeSet.begin(); edgeSetIt != edgeSet.end(); ++edgeSetIt)
-
614  {
-
615  if (std::find_if(this->edgeSet.begin(), this->edgeSet.end(), [edgeSetIt](const Edge<T> *edge)
-
616  { return (*edge == **edgeSetIt); }) == this->edgeSet.end())
-
617  {
-
618  this->edgeSet.push_back(*edgeSetIt);
-
619  }
-
620  }
-
621  }
-
622 
-
623  template <typename T>
-
624  const std::list<const Edge<T> *> &Graph<T>::getEdgeSet() const
-
625  {
-
626  return edgeSet;
-
627  }
+
542  Graph() = default;
+
543  Graph(const std::list<const Edge<T> *> &edgeSet);
+
544  ~Graph() = default;
+
545  const std::list<const Edge<T> *> &getEdgeSet() const;
+
546  void setEdgeSet(std::list<const Edge<T> *> &edgeSet);
+
547  void addEdge(const Edge<T> *edge);
+
548  void removeEdge(unsigned long edgeId);
+
549  const std::list<const Node<T> *> getNodeSet() const;
+
550  const std::optional<const Edge<T> *> getEdge(unsigned long edgeId) const;
+
555  const AdjacencyMatrix<T> getAdjMatrix() const;
+
567  const DijkstraResult dijkstra(const Node<T> &source, const Node<T> &target) const;
+
577  const std::vector<Node<T>> breadth_first_search(const Node<T> &start) const;
+
587  const std::vector<Node<T>> depth_first_search(const Node<T> &start) const;
+
588 
+
596  bool isCyclicDirectedGraphDFS() const;
+
597 
+
605  bool isCyclicDirectedGraphBFS() const;
+
606 
+
613  bool isDirectedGraph() const;
+
614 
+
627  int writeToFile(InputOutputFormat format = InputOutputFormat::STANDARD_CSV, const std::string &workingDir = ".", const std::string &OFileName = "graph", bool compress = false, bool writeNodeFeat = false, bool writeEdgeWeight = false) const;
628 
-
629  template <typename T>
-
630  void Graph<T>::setEdgeSet(std::list<const Edge<T> *> &edgeSet)
-
631  {
-
632  this->edgeSet.clear();
-
633  for (auto edgeSetIt = edgeSet.begin(); edgeSetIt != edgeSet.end(); ++edgeSetIt)
-
634  {
-
635  if (std::find_if(this->edgeSet.begin(), this->edgeSet.end(), [edgeSetIt](const Edge<T> *edge)
-
636  { return (*edge == **edgeSetIt); }) == this->edgeSet.end())
-
637  {
-
638  this->edgeSet.push_back(*edgeSetIt);
-
639  }
-
640  }
-
641  }
+
641  int readFromFile(InputOutputFormat format = InputOutputFormat::STANDARD_CSV, const std::string &workingDir = ".", const std::string &OFileName = "graph", bool compress = false, bool readNodeFeat = false, bool readEdgeWeight = false);
642 
-
643  template <typename T>
-
644  void Graph<T>::addEdge(const Edge<T> *edge)
-
645  {
-
646  if (std::find_if(edgeSet.begin(), edgeSet.end(), [edge](const Edge<T> *edge_a)
-
647  { return (*edge == *edge_a); }) == edgeSet.end())
-
648  {
-
649  edgeSet.push_back(edge);
-
650  }
-
651  }
+
651  PartitionMap<T> partitionGraph(PartitionAlgorithm algorithm, unsigned int numberOfPartitions) const;
652 
-
653  template <typename T>
-
654  void Graph<T>::removeEdge(unsigned long edgeId)
-
655  {
-
656  auto edgeOpt = getEdge(edgeId);
-
657  if (edgeOpt.has_value())
-
658  {
-
659  edgeSet.erase(edgeSet.find(edgeOpt.value()));
-
660  }
-
661  }
-
662 
-
663  template <typename T>
-
664  const std::list<const Node<T> *> Graph<T>::getNodeSet() const
-
665  {
-
666  std::list<const Node<T> *> nodeSet;
-
667  for (auto edge : edgeSet)
-
668  {
-
669  if (std::find_if(nodeSet.begin(), nodeSet.end(), [edge](const Node<T> *node)
-
670  { return (*edge->getNodePair().first == *node); }) == nodeSet.end())
-
671  {
-
672  nodeSet.push_back(edge->getNodePair().first);
-
673  }
-
674  if (std::find_if(nodeSet.begin(), nodeSet.end(), [edge](const Node<T> *node)
-
675  { return (*edge->getNodePair().second == *node); }) == nodeSet.end())
-
676  {
-
677  nodeSet.push_back(edge->getNodePair().second);
-
678  }
-
679  }
-
680  return nodeSet;
-
681  }
-
682 
-
683  template <typename T>
-
684  const std::optional<const Edge<T> *> Graph<T>::getEdge(unsigned long edgeId) const
-
685  {
-
686 
-
687  auto it = edgeSet.begin();
-
688  for (it; it != edgeSet.end(); ++it)
-
689  {
-
690  if ((*it)->getId() == edgeId)
-
691  {
-
692  return *it;
-
693  }
-
694  }
-
695 
-
696  return std::nullopt;
-
697  }
-
698 
-
699  template <typename T>
-
700  void Graph<T>::addElementToAdjMatrix(AdjacencyMatrix<T> &adjMatrix, const Node<T> *nodeFrom, const Node<T> *nodeTo, const Edge<T> *edge) const
-
701  {
-
702  std::pair<const Node<T> *, const Edge<T> *> elem = {nodeTo, edge};
-
703  adjMatrix[nodeFrom].push_back(elem);
-
704 
-
705  //adjMatrix[nodeFrom.getId()].push_back(std::make_pair<const Node<T>,const Edge<T>>(nodeTo, edge));
-
706  }
-
707 
-
708  template <typename T>
-
709  int Graph<T>::writeToStandardFile_csv(const std::string &workingDir, const std::string &OFileName, bool compress, bool writeNodeFeat, bool writeEdgeWeight) const
-
710  {
-
711  std::ofstream ofileGraph;
-
712  std::string completePathToFileGraph = workingDir + "/" + OFileName + ".csv";
-
713  ofileGraph.open(completePathToFileGraph);
-
714  if (!ofileGraph.is_open())
+
653  friend std::ostream &operator<<<>(std::ostream &os, const Graph<T> &graph);
+
654  friend std::ostream &operator<<<>(std::ostream &os, const AdjacencyMatrix<T> &adj);
+
655  };
+
656 
+
657  template <typename T>
+
658  Graph<T>::Graph(const std::list<const Edge<T> *> &edgeSet)
+
659  {
+
660  for (auto edgeSetIt = edgeSet.begin(); edgeSetIt != edgeSet.end(); ++edgeSetIt)
+
661  {
+
662  if (std::find_if(this->edgeSet.begin(), this->edgeSet.end(), [edgeSetIt](const Edge<T> *edge)
+
663  { return (*edge == **edgeSetIt); }) == this->edgeSet.end())
+
664  {
+
665  this->edgeSet.push_back(*edgeSetIt);
+
666  }
+
667  }
+
668  }
+
669 
+
670  template <typename T>
+
671  const std::list<const Edge<T> *> &Graph<T>::getEdgeSet() const
+
672  {
+
673  return edgeSet;
+
674  }
+
675 
+
676  template <typename T>
+
677  void Graph<T>::setEdgeSet(std::list<const Edge<T> *> &edgeSet)
+
678  {
+
679  this->edgeSet.clear();
+
680  for (auto edgeSetIt = edgeSet.begin(); edgeSetIt != edgeSet.end(); ++edgeSetIt)
+
681  {
+
682  if (std::find_if(this->edgeSet.begin(), this->edgeSet.end(), [edgeSetIt](const Edge<T> *edge)
+
683  { return (*edge == **edgeSetIt); }) == this->edgeSet.end())
+
684  {
+
685  this->edgeSet.push_back(*edgeSetIt);
+
686  }
+
687  }
+
688  }
+
689 
+
690  template <typename T>
+
691  void Graph<T>::addEdge(const Edge<T> *edge)
+
692  {
+
693  if (std::find_if(edgeSet.begin(), edgeSet.end(), [edge](const Edge<T> *edge_a)
+
694  { return (*edge == *edge_a); }) == edgeSet.end())
+
695  {
+
696  edgeSet.push_back(edge);
+
697  }
+
698  }
+
699 
+
700  template <typename T>
+
701  void Graph<T>::removeEdge(unsigned long edgeId)
+
702  {
+
703  auto edgeOpt = getEdge(edgeId);
+
704  if (edgeOpt.has_value())
+
705  {
+
706  edgeSet.erase(edgeSet.find(edgeOpt.value()));
+
707  }
+
708  }
+
709 
+
710  template <typename T>
+
711  const std::list<const Node<T> *> Graph<T>::getNodeSet() const
+
712  {
+
713  std::list<const Node<T> *> nodeSet;
+
714  for (auto edge : edgeSet)
715  {
-
716  // ERROR File Not Open
-
717  return -1;
-
718  }
-
719  auto printOutGraph = [&ofileGraph](const Edge<T> *e)
-
720  { ofileGraph << e->getId() << "," << e->getNodePair().first->getId() << "," << e->getNodePair().second->getId() << "," << ((e->isDirected().has_value() && e->isDirected().value()) ? 1 : 0) << std::endl; };
-
721  std::for_each(edgeSet.cbegin(), edgeSet.cend(), printOutGraph);
-
722  ofileGraph.close();
-
723 
-
724  if (writeNodeFeat)
-
725  {
-
726  std::ofstream ofileNodeFeat;
-
727  std::string completePathToFileNodeFeat = workingDir + "/" + OFileName + "_NodeFeat"
-
728  ".csv";
-
729  ofileNodeFeat.open(completePathToFileNodeFeat);
-
730  if (!ofileNodeFeat.is_open())
-
731  {
-
732  // ERROR File Not Open
-
733  return -1;
-
734  }
-
735  auto printOutNodeFeat = [&ofileNodeFeat](const Node<T> *node)
-
736  { ofileNodeFeat << node->getId() << "," << node->getData() << std::endl; };
-
737  auto nodeSet = getNodeSet();
-
738  std::for_each(nodeSet.cbegin(), nodeSet.cend(), printOutNodeFeat);
-
739  ofileNodeFeat.close();
-
740  }
-
741 
-
742  if (writeEdgeWeight)
-
743  {
-
744  std::ofstream ofileEdgeWeight;
-
745  std::string completePathToFileEdgeWeight = workingDir + "/" + OFileName + "_EdgeWeight"
-
746  ".csv";
-
747  ofileEdgeWeight.open(completePathToFileEdgeWeight);
-
748  if (!ofileEdgeWeight.is_open())
-
749  {
-
750  // ERROR File Not Open
-
751  return -1;
-
752  }
-
753  auto printOutEdgeWeight = [&ofileEdgeWeight](const Edge<T> *e)
-
754  { ofileEdgeWeight << e->getId() << "," << (e->isWeighted().has_value() && e->isWeighted().value() ? (dynamic_cast<const Weighted *>(e))->getWeight() : 0.0) << "," << (e->isWeighted().has_value() && e->isWeighted().value() ? 1 : 0) << std::endl; };
-
755 
-
756  std::for_each(edgeSet.cbegin(), edgeSet.cend(), printOutEdgeWeight);
-
757  ofileEdgeWeight.close();
-
758  }
-
759  return 0;
-
760  }
-
761 
-
762  template <typename T>
-
763  int Graph<T>::readFromStandardFile_csv(const std::string &workingDir, const std::string &OFileName, bool compress, bool readNodeFeat, bool readEdgeWeight)
-
764  {
-
765  std::ifstream ifileGraph;
-
766  std::ifstream ifileNodeFeat;
-
767  std::ifstream ifileEdgeWeight;
-
768  std::map<unsigned long, std::pair<unsigned long, unsigned long>> edgeMap;
-
769  std::map<unsigned long, bool> edgeDirectedMap;
-
770  std::map<unsigned long, T> nodeFeatMap;
-
771  std::map<unsigned long, double> edgeWeightMap;
-
772  std::string completePathToFileGraph = workingDir + "/" + OFileName + ".csv";
-
773  ifileGraph.open(completePathToFileGraph);
-
774  if (!ifileGraph.is_open())
-
775  {
-
776  // ERROR File Not Open
-
777  return -1;
-
778  }
-
779  char comma;
-
780  for (;;)
-
781  { /* loop continually */
-
782  unsigned long edgeId;
-
783  unsigned long nodeId1;
-
784  unsigned long nodeId2;
-
785  bool directed;
-
786  ifileGraph >> edgeId >> comma >> nodeId1 >> comma >> nodeId2 >> comma >> directed;
-
787  edgeMap[edgeId] = std::pair<unsigned long, unsigned long>(nodeId1, nodeId2);
-
788  edgeDirectedMap[edgeId] = directed;
-
789  if (ifileGraph.fail() || ifileGraph.eof())
-
790  break;
-
791  ifileGraph.ignore(128, '\n');
-
792  }
-
793  ifileGraph.close();
-
794 
-
795  if (readNodeFeat)
-
796  {
-
797  std::string completePathToFileNodeFeat = workingDir + "/" + OFileName + "_NodeFeat"
-
798  ".csv";
-
799  ifileNodeFeat.open(completePathToFileNodeFeat);
-
800  if (!ifileNodeFeat.is_open())
-
801  {
-
802  // ERROR File Not Open
-
803  return -1;
-
804  }
-
805  for (;;)
-
806  { /* loop continually */
-
807  unsigned long nodeId;
-
808  T nodeFeat;
-
809  ifileNodeFeat >> nodeId >> comma >> nodeFeat;
-
810  nodeFeatMap[nodeId] = nodeFeat;
-
811  if (ifileNodeFeat.fail() || ifileNodeFeat.eof())
-
812  break;
-
813  ifileNodeFeat.ignore(128, '\n');
-
814  }
-
815  ifileNodeFeat.close();
-
816  }
-
817 
-
818  if (readEdgeWeight)
-
819  {
-
820 
-
821  std::string completePathToFileEdgeWeight = workingDir + "/" + OFileName + "_EdgeWeight"
-
822  ".csv";
-
823  ifileEdgeWeight.open(completePathToFileEdgeWeight);
-
824  if (!ifileEdgeWeight.is_open())
-
825  {
-
826  // ERROR File Not Open
-
827  return -1;
-
828  }
-
829  for (;;)
-
830  { /* loop continually */
-
831  unsigned long edgeId;
-
832  double weight;
-
833  bool weighted;
-
834  ifileEdgeWeight >> edgeId >> comma >> weight >> comma >> weighted;
-
835  if (weighted)
-
836  {
-
837  edgeWeightMap[edgeId] = weight;
-
838  }
-
839  if (ifileEdgeWeight.fail() || ifileEdgeWeight.eof())
-
840  break;
-
841  ifileEdgeWeight.ignore(128, '\n');
-
842  }
-
843  ifileEdgeWeight.close();
-
844  }
-
845  recreateGraphFromReadFiles(edgeMap, edgeDirectedMap, nodeFeatMap, edgeWeightMap);
-
846  return 0;
-
847  }
-
848 
-
849  template <typename T>
-
850  int Graph<T>::writeToStandardFile_tsv(const std::string &workingDir, const std::string &OFileName, bool compress, bool writeNodeFeat, bool writeEdgeWeight) const
-
851  {
-
852  std::ofstream ofileGraph;
-
853  std::string completePathToFileGraph = workingDir + "/" + OFileName + ".tsv";
-
854  ofileGraph.open(completePathToFileGraph);
-
855  if (!ofileGraph.is_open())
-
856  {
-
857  // ERROR File Not Open
-
858  return -1;
-
859  }
-
860  auto printOutGraph = [&ofileGraph](const Edge<T> *e)
-
861  { ofileGraph << e->getId() << "\t" << e->getNodePair().first->getId() << "\t" << e->getNodePair().second->getId() << "\t" << ((e->isDirected().has_value() && e->isDirected().value()) ? 1 : 0) << std::endl; };
-
862  std::for_each(edgeSet.cbegin(), edgeSet.cend(), printOutGraph);
-
863  ofileGraph.close();
+
716  if (std::find_if(nodeSet.begin(), nodeSet.end(), [edge](const Node<T> *node)
+
717  { return (*edge->getNodePair().first == *node); }) == nodeSet.end())
+
718  {
+
719  nodeSet.push_back(edge->getNodePair().first);
+
720  }
+
721  if (std::find_if(nodeSet.begin(), nodeSet.end(), [edge](const Node<T> *node)
+
722  { return (*edge->getNodePair().second == *node); }) == nodeSet.end())
+
723  {
+
724  nodeSet.push_back(edge->getNodePair().second);
+
725  }
+
726  }
+
727  return nodeSet;
+
728  }
+
729 
+
730  template <typename T>
+
731  const std::optional<const Edge<T> *> Graph<T>::getEdge(unsigned long edgeId) const
+
732  {
+
733 
+
734  auto it = edgeSet.begin();
+
735  for (it; it != edgeSet.end(); ++it)
+
736  {
+
737  if ((*it)->getId() == edgeId)
+
738  {
+
739  return *it;
+
740  }
+
741  }
+
742 
+
743  return std::nullopt;
+
744  }
+
745 
+
746  template <typename T>
+
747  void Graph<T>::addElementToAdjMatrix(AdjacencyMatrix<T> &adjMatrix, const Node<T> *nodeFrom, const Node<T> *nodeTo, const Edge<T> *edge) const
+
748  {
+
749  std::pair<const Node<T> *, const Edge<T> *> elem = {nodeTo, edge};
+
750  adjMatrix[nodeFrom].push_back(elem);
+
751 
+
752  //adjMatrix[nodeFrom.getId()].push_back(std::make_pair<const Node<T>,const Edge<T>>(nodeTo, edge));
+
753  }
+
754 
+
755  template <typename T>
+
756  int Graph<T>::writeToStandardFile_csv(const std::string &workingDir, const std::string &OFileName, bool compress, bool writeNodeFeat, bool writeEdgeWeight) const
+
757  {
+
758  std::ofstream ofileGraph;
+
759  std::string completePathToFileGraph = workingDir + "/" + OFileName + ".csv";
+
760  ofileGraph.open(completePathToFileGraph);
+
761  if (!ofileGraph.is_open())
+
762  {
+
763  // ERROR File Not Open
+
764  return -1;
+
765  }
+
766  auto printOutGraph = [&ofileGraph](const Edge<T> *e)
+
767  { ofileGraph << e->getId() << "," << e->getNodePair().first->getId() << "," << e->getNodePair().second->getId() << "," << ((e->isDirected().has_value() && e->isDirected().value()) ? 1 : 0) << std::endl; };
+
768  std::for_each(edgeSet.cbegin(), edgeSet.cend(), printOutGraph);
+
769  ofileGraph.close();
+
770 
+
771  if (writeNodeFeat)
+
772  {
+
773  std::ofstream ofileNodeFeat;
+
774  std::string completePathToFileNodeFeat = workingDir + "/" + OFileName + "_NodeFeat"
+
775  ".csv";
+
776  ofileNodeFeat.open(completePathToFileNodeFeat);
+
777  if (!ofileNodeFeat.is_open())
+
778  {
+
779  // ERROR File Not Open
+
780  return -1;
+
781  }
+
782  auto printOutNodeFeat = [&ofileNodeFeat](const Node<T> *node)
+
783  { ofileNodeFeat << node->getId() << "," << node->getData() << std::endl; };
+
784  auto nodeSet = getNodeSet();
+
785  std::for_each(nodeSet.cbegin(), nodeSet.cend(), printOutNodeFeat);
+
786  ofileNodeFeat.close();
+
787  }
+
788 
+
789  if (writeEdgeWeight)
+
790  {
+
791  std::ofstream ofileEdgeWeight;
+
792  std::string completePathToFileEdgeWeight = workingDir + "/" + OFileName + "_EdgeWeight"
+
793  ".csv";
+
794  ofileEdgeWeight.open(completePathToFileEdgeWeight);
+
795  if (!ofileEdgeWeight.is_open())
+
796  {
+
797  // ERROR File Not Open
+
798  return -1;
+
799  }
+
800  auto printOutEdgeWeight = [&ofileEdgeWeight](const Edge<T> *e)
+
801  { ofileEdgeWeight << e->getId() << "," << (e->isWeighted().has_value() && e->isWeighted().value() ? (dynamic_cast<const Weighted *>(e))->getWeight() : 0.0) << "," << (e->isWeighted().has_value() && e->isWeighted().value() ? 1 : 0) << std::endl; };
+
802 
+
803  std::for_each(edgeSet.cbegin(), edgeSet.cend(), printOutEdgeWeight);
+
804  ofileEdgeWeight.close();
+
805  }
+
806  return 0;
+
807  }
+
808 
+
809  template <typename T>
+
810  int Graph<T>::readFromStandardFile_csv(const std::string &workingDir, const std::string &OFileName, bool compress, bool readNodeFeat, bool readEdgeWeight)
+
811  {
+
812  std::ifstream ifileGraph;
+
813  std::ifstream ifileNodeFeat;
+
814  std::ifstream ifileEdgeWeight;
+
815  std::map<unsigned long, std::pair<unsigned long, unsigned long>> edgeMap;
+
816  std::map<unsigned long, bool> edgeDirectedMap;
+
817  std::map<unsigned long, T> nodeFeatMap;
+
818  std::map<unsigned long, double> edgeWeightMap;
+
819  std::string completePathToFileGraph = workingDir + "/" + OFileName + ".csv";
+
820  ifileGraph.open(completePathToFileGraph);
+
821  if (!ifileGraph.is_open())
+
822  {
+
823  // ERROR File Not Open
+
824  return -1;
+
825  }
+
826  char comma;
+
827  for (;;)
+
828  { /* loop continually */
+
829  unsigned long edgeId;
+
830  unsigned long nodeId1;
+
831  unsigned long nodeId2;
+
832  bool directed;
+
833  ifileGraph >> edgeId >> comma >> nodeId1 >> comma >> nodeId2 >> comma >> directed;
+
834  edgeMap[edgeId] = std::pair<unsigned long, unsigned long>(nodeId1, nodeId2);
+
835  edgeDirectedMap[edgeId] = directed;
+
836  if (ifileGraph.fail() || ifileGraph.eof())
+
837  break;
+
838  ifileGraph.ignore(128, '\n');
+
839  }
+
840  ifileGraph.close();
+
841 
+
842  if (readNodeFeat)
+
843  {
+
844  std::string completePathToFileNodeFeat = workingDir + "/" + OFileName + "_NodeFeat"
+
845  ".csv";
+
846  ifileNodeFeat.open(completePathToFileNodeFeat);
+
847  if (!ifileNodeFeat.is_open())
+
848  {
+
849  // ERROR File Not Open
+
850  return -1;
+
851  }
+
852  for (;;)
+
853  { /* loop continually */
+
854  unsigned long nodeId;
+
855  T nodeFeat;
+
856  ifileNodeFeat >> nodeId >> comma >> nodeFeat;
+
857  nodeFeatMap[nodeId] = nodeFeat;
+
858  if (ifileNodeFeat.fail() || ifileNodeFeat.eof())
+
859  break;
+
860  ifileNodeFeat.ignore(128, '\n');
+
861  }
+
862  ifileNodeFeat.close();
+
863  }
864 
-
865  if (writeNodeFeat)
+
865  if (readEdgeWeight)
866  {
-
867  std::ofstream ofileNodeFeat;
-
868  std::string completePathToFileNodeFeat = workingDir + "/" + OFileName + "_NodeFeat"
-
869  ".tsv";
-
870  ofileNodeFeat.open(completePathToFileNodeFeat);
-
871  if (!ofileNodeFeat.is_open())
+
867 
+
868  std::string completePathToFileEdgeWeight = workingDir + "/" + OFileName + "_EdgeWeight"
+
869  ".csv";
+
870  ifileEdgeWeight.open(completePathToFileEdgeWeight);
+
871  if (!ifileEdgeWeight.is_open())
872  {
873  // ERROR File Not Open
874  return -1;
875  }
-
876  auto printOutNodeFeat = [&ofileNodeFeat](const Node<T> *node)
-
877  { ofileNodeFeat << node->getId() << "\t" << node->getData() << std::endl; };
-
878  auto nodeSet = getNodeSet();
-
879  std::for_each(nodeSet.cbegin(), nodeSet.cend(), printOutNodeFeat);
-
880  ofileNodeFeat.close();
-
881  }
-
882 
-
883  if (writeEdgeWeight)
-
884  {
-
885  std::ofstream ofileEdgeWeight;
-
886  std::string completePathToFileEdgeWeight = workingDir + "/" + OFileName + "_EdgeWeight"
-
887  ".tsv";
-
888  ofileEdgeWeight.open(completePathToFileEdgeWeight);
-
889  if (!ofileEdgeWeight.is_open())
-
890  {
-
891  // ERROR File Not Open
-
892  return -1;
-
893  }
-
894  auto printOutEdgeWeight = [&ofileEdgeWeight](const Edge<T> *e)
-
895  { ofileEdgeWeight << e->getId() << "\t" << (e->isWeighted().has_value() && e->isWeighted().value() ? (dynamic_cast<const Weighted *>(e))->getWeight() : 0.0) << "\t" << (e->isWeighted().has_value() && e->isWeighted().value() ? 1 : 0) << std::endl; };
-
896 
-
897  std::for_each(edgeSet.cbegin(), edgeSet.cend(), printOutEdgeWeight);
-
898  ofileEdgeWeight.close();
-
899  }
-
900  return 0;
-
901  }
-
902 
-
903  template <typename T>
-
904  int Graph<T>::readFromStandardFile_tsv(const std::string &workingDir, const std::string &OFileName, bool compress, bool readNodeFeat, bool readEdgeWeight)
-
905  {
-
906  std::ifstream ifileGraph;
-
907  std::ifstream ifileNodeFeat;
-
908  std::ifstream ifileEdgeWeight;
-
909  std::map<unsigned long, std::pair<unsigned long, unsigned long>> edgeMap;
-
910  std::map<unsigned long, bool> edgeDirectedMap;
-
911  std::map<unsigned long, T> nodeFeatMap;
-
912  std::map<unsigned long, double> edgeWeightMap;
-
913  std::string completePathToFileGraph = workingDir + "/" + OFileName + ".tsv";
-
914  ifileGraph.open(completePathToFileGraph);
-
915  if (!ifileGraph.is_open())
-
916  {
-
917  // ERROR File Not Open
-
918  return -1;
-
919  }
-
920  for (;;)
-
921  { /* loop continually */
-
922  unsigned long edgeId;
-
923  unsigned long nodeId1;
-
924  unsigned long nodeId2;
-
925  bool directed;
-
926  ifileGraph >> edgeId >> std::ws >> nodeId1 >> std::ws >> nodeId2 >> std::ws >> directed;
-
927  edgeMap[edgeId] = std::pair<unsigned long, unsigned long>(nodeId1, nodeId2);
-
928  edgeDirectedMap[edgeId] = directed;
-
929  if (ifileGraph.fail() || ifileGraph.eof())
-
930  break;
-
931  ifileGraph.ignore(128, '\n');
-
932  }
-
933  ifileGraph.close();
-
934 
-
935  if (readNodeFeat)
-
936  {
-
937  std::string completePathToFileNodeFeat = workingDir + "/" + OFileName + "_NodeFeat"
-
938  ".tsv";
-
939  ifileNodeFeat.open(completePathToFileNodeFeat);
-
940  if (!ifileNodeFeat.is_open())
-
941  {
-
942  // ERROR File Not Open
-
943  return -1;
-
944  }
-
945  for (;;)
-
946  { /* loop continually */
-
947  unsigned long nodeId;
-
948  T nodeFeat;
-
949  ifileNodeFeat >> nodeId >> std::ws >> nodeFeat;
-
950  nodeFeatMap[nodeId] = nodeFeat;
-
951  if (ifileNodeFeat.fail() || ifileNodeFeat.eof())
-
952  break;
-
953  ifileNodeFeat.ignore(128, '\n');
-
954  }
-
955  ifileNodeFeat.close();
-
956  }
-
957 
-
958  if (readEdgeWeight)
-
959  {
-
960 
-
961  std::string completePathToFileEdgeWeight = workingDir + "/" + OFileName + "_EdgeWeight"
-
962  ".tsv";
-
963  ifileEdgeWeight.open(completePathToFileEdgeWeight);
-
964  if (!ifileEdgeWeight.is_open())
-
965  {
-
966  // ERROR File Not Open
-
967  return -1;
-
968  }
-
969  for (;;)
-
970  { /* loop continually */
-
971  unsigned long edgeId;
-
972  double weight;
-
973  bool weighted;
-
974  ifileEdgeWeight >> edgeId >> std::ws >> weight >> std::ws >> weighted;
-
975  if (weighted)
-
976  {
-
977  edgeWeightMap[edgeId] = weight;
-
978  }
-
979  if (ifileEdgeWeight.fail() || ifileEdgeWeight.eof())
-
980  break;
-
981  ifileEdgeWeight.ignore(128, '\n');
-
982  }
-
983  ifileEdgeWeight.close();
-
984  }
-
985  recreateGraphFromReadFiles(edgeMap, edgeDirectedMap, nodeFeatMap, edgeWeightMap);
-
986  return 0;
-
987  }
-
988 
-
989  template <typename T>
-
990  void Graph<T>::recreateGraphFromReadFiles(std::map<unsigned long, std::pair<unsigned long, unsigned long>> &edgeMap, std::map<unsigned long, bool> &edgeDirectedMap, std::map<unsigned long, T> &nodeFeatMap, std::map<unsigned long, double> &edgeWeightMap)
-
991  {
-
992  std::map<unsigned long, Node<T> *> nodeMap;
-
993  for (auto edgeIt = edgeMap.begin(); edgeIt != edgeMap.end(); ++edgeIt)
-
994  {
-
995  Node<T> *node1 = nullptr;
-
996  Node<T> *node2 = nullptr;
-
997  if (nodeMap.find(edgeIt->second.first) == nodeMap.end())
-
998  {
-
999  //Create new Node
-
1000  T feat;
-
1001  if (nodeFeatMap.find(edgeIt->second.first) != nodeFeatMap.end())
-
1002  {
-
1003  feat = nodeFeatMap.at(edgeIt->second.first);
-
1004  }
-
1005  node1 = new Node<T>(edgeIt->second.first, feat);
-
1006  nodeMap[edgeIt->second.first] = node1;
-
1007  }
-
1008  else
-
1009  {
-
1010  node1 = nodeMap.at(edgeIt->second.first);
-
1011  }
-
1012  if (nodeMap.find(edgeIt->second.second) == nodeMap.end())
-
1013  {
-
1014  //Create new Node
-
1015  T feat;
-
1016  if (nodeFeatMap.find(edgeIt->second.second) != nodeFeatMap.end())
-
1017  {
-
1018  feat = nodeFeatMap.at(edgeIt->second.second);
-
1019  }
-
1020  node2 = new Node<T>(edgeIt->second.second, feat);
-
1021  nodeMap[edgeIt->second.second] = node2;
-
1022  }
-
1023  else
-
1024  {
-
1025  node2 = nodeMap.at(edgeIt->second.second);
-
1026  }
-
1027 
-
1028  if (edgeWeightMap.find(edgeIt->first) != edgeWeightMap.end())
-
1029  {
-
1030  if (edgeDirectedMap.find(edgeIt->first) != edgeDirectedMap.end() && edgeDirectedMap.at(edgeIt->first))
-
1031  {
-
1032  auto edge = new DirectedWeightedEdge<T>(edgeIt->first, *node1, *node2, edgeWeightMap.at(edgeIt->first));
-
1033  addEdge(edge);
-
1034  }
-
1035  else
-
1036  {
-
1037  auto edge = new UndirectedWeightedEdge<T>(edgeIt->first, *node1, *node2, edgeWeightMap.at(edgeIt->first));
-
1038  addEdge(edge);
-
1039  }
-
1040  }
-
1041  else
-
1042  {
-
1043  if (edgeDirectedMap.find(edgeIt->first) != edgeDirectedMap.end() && edgeDirectedMap.at(edgeIt->first))
-
1044  {
-
1045  auto edge = new DirectedEdge<T>(edgeIt->first, *node1, *node2);
-
1046  addEdge(edge);
-
1047  }
-
1048  else
+
876  for (;;)
+
877  { /* loop continually */
+
878  unsigned long edgeId;
+
879  double weight;
+
880  bool weighted;
+
881  ifileEdgeWeight >> edgeId >> comma >> weight >> comma >> weighted;
+
882  if (weighted)
+
883  {
+
884  edgeWeightMap[edgeId] = weight;
+
885  }
+
886  if (ifileEdgeWeight.fail() || ifileEdgeWeight.eof())
+
887  break;
+
888  ifileEdgeWeight.ignore(128, '\n');
+
889  }
+
890  ifileEdgeWeight.close();
+
891  }
+
892  recreateGraphFromReadFiles(edgeMap, edgeDirectedMap, nodeFeatMap, edgeWeightMap);
+
893  return 0;
+
894  }
+
895 
+
896  template <typename T>
+
897  int Graph<T>::writeToStandardFile_tsv(const std::string &workingDir, const std::string &OFileName, bool compress, bool writeNodeFeat, bool writeEdgeWeight) const
+
898  {
+
899  std::ofstream ofileGraph;
+
900  std::string completePathToFileGraph = workingDir + "/" + OFileName + ".tsv";
+
901  ofileGraph.open(completePathToFileGraph);
+
902  if (!ofileGraph.is_open())
+
903  {
+
904  // ERROR File Not Open
+
905  return -1;
+
906  }
+
907  auto printOutGraph = [&ofileGraph](const Edge<T> *e)
+
908  { ofileGraph << e->getId() << "\t" << e->getNodePair().first->getId() << "\t" << e->getNodePair().second->getId() << "\t" << ((e->isDirected().has_value() && e->isDirected().value()) ? 1 : 0) << std::endl; };
+
909  std::for_each(edgeSet.cbegin(), edgeSet.cend(), printOutGraph);
+
910  ofileGraph.close();
+
911 
+
912  if (writeNodeFeat)
+
913  {
+
914  std::ofstream ofileNodeFeat;
+
915  std::string completePathToFileNodeFeat = workingDir + "/" + OFileName + "_NodeFeat"
+
916  ".tsv";
+
917  ofileNodeFeat.open(completePathToFileNodeFeat);
+
918  if (!ofileNodeFeat.is_open())
+
919  {
+
920  // ERROR File Not Open
+
921  return -1;
+
922  }
+
923  auto printOutNodeFeat = [&ofileNodeFeat](const Node<T> *node)
+
924  { ofileNodeFeat << node->getId() << "\t" << node->getData() << std::endl; };
+
925  auto nodeSet = getNodeSet();
+
926  std::for_each(nodeSet.cbegin(), nodeSet.cend(), printOutNodeFeat);
+
927  ofileNodeFeat.close();
+
928  }
+
929 
+
930  if (writeEdgeWeight)
+
931  {
+
932  std::ofstream ofileEdgeWeight;
+
933  std::string completePathToFileEdgeWeight = workingDir + "/" + OFileName + "_EdgeWeight"
+
934  ".tsv";
+
935  ofileEdgeWeight.open(completePathToFileEdgeWeight);
+
936  if (!ofileEdgeWeight.is_open())
+
937  {
+
938  // ERROR File Not Open
+
939  return -1;
+
940  }
+
941  auto printOutEdgeWeight = [&ofileEdgeWeight](const Edge<T> *e)
+
942  { ofileEdgeWeight << e->getId() << "\t" << (e->isWeighted().has_value() && e->isWeighted().value() ? (dynamic_cast<const Weighted *>(e))->getWeight() : 0.0) << "\t" << (e->isWeighted().has_value() && e->isWeighted().value() ? 1 : 0) << std::endl; };
+
943 
+
944  std::for_each(edgeSet.cbegin(), edgeSet.cend(), printOutEdgeWeight);
+
945  ofileEdgeWeight.close();
+
946  }
+
947  return 0;
+
948  }
+
949 
+
950  template <typename T>
+
951  int Graph<T>::readFromStandardFile_tsv(const std::string &workingDir, const std::string &OFileName, bool compress, bool readNodeFeat, bool readEdgeWeight)
+
952  {
+
953  std::ifstream ifileGraph;
+
954  std::ifstream ifileNodeFeat;
+
955  std::ifstream ifileEdgeWeight;
+
956  std::map<unsigned long, std::pair<unsigned long, unsigned long>> edgeMap;
+
957  std::map<unsigned long, bool> edgeDirectedMap;
+
958  std::map<unsigned long, T> nodeFeatMap;
+
959  std::map<unsigned long, double> edgeWeightMap;
+
960  std::string completePathToFileGraph = workingDir + "/" + OFileName + ".tsv";
+
961  ifileGraph.open(completePathToFileGraph);
+
962  if (!ifileGraph.is_open())
+
963  {
+
964  // ERROR File Not Open
+
965  return -1;
+
966  }
+
967  for (;;)
+
968  { /* loop continually */
+
969  unsigned long edgeId;
+
970  unsigned long nodeId1;
+
971  unsigned long nodeId2;
+
972  bool directed;
+
973  ifileGraph >> edgeId >> std::ws >> nodeId1 >> std::ws >> nodeId2 >> std::ws >> directed;
+
974  edgeMap[edgeId] = std::pair<unsigned long, unsigned long>(nodeId1, nodeId2);
+
975  edgeDirectedMap[edgeId] = directed;
+
976  if (ifileGraph.fail() || ifileGraph.eof())
+
977  break;
+
978  ifileGraph.ignore(128, '\n');
+
979  }
+
980  ifileGraph.close();
+
981 
+
982  if (readNodeFeat)
+
983  {
+
984  std::string completePathToFileNodeFeat = workingDir + "/" + OFileName + "_NodeFeat"
+
985  ".tsv";
+
986  ifileNodeFeat.open(completePathToFileNodeFeat);
+
987  if (!ifileNodeFeat.is_open())
+
988  {
+
989  // ERROR File Not Open
+
990  return -1;
+
991  }
+
992  for (;;)
+
993  { /* loop continually */
+
994  unsigned long nodeId;
+
995  T nodeFeat;
+
996  ifileNodeFeat >> nodeId >> std::ws >> nodeFeat;
+
997  nodeFeatMap[nodeId] = nodeFeat;
+
998  if (ifileNodeFeat.fail() || ifileNodeFeat.eof())
+
999  break;
+
1000  ifileNodeFeat.ignore(128, '\n');
+
1001  }
+
1002  ifileNodeFeat.close();
+
1003  }
+
1004 
+
1005  if (readEdgeWeight)
+
1006  {
+
1007 
+
1008  std::string completePathToFileEdgeWeight = workingDir + "/" + OFileName + "_EdgeWeight"
+
1009  ".tsv";
+
1010  ifileEdgeWeight.open(completePathToFileEdgeWeight);
+
1011  if (!ifileEdgeWeight.is_open())
+
1012  {
+
1013  // ERROR File Not Open
+
1014  return -1;
+
1015  }
+
1016  for (;;)
+
1017  { /* loop continually */
+
1018  unsigned long edgeId;
+
1019  double weight;
+
1020  bool weighted;
+
1021  ifileEdgeWeight >> edgeId >> std::ws >> weight >> std::ws >> weighted;
+
1022  if (weighted)
+
1023  {
+
1024  edgeWeightMap[edgeId] = weight;
+
1025  }
+
1026  if (ifileEdgeWeight.fail() || ifileEdgeWeight.eof())
+
1027  break;
+
1028  ifileEdgeWeight.ignore(128, '\n');
+
1029  }
+
1030  ifileEdgeWeight.close();
+
1031  }
+
1032  recreateGraphFromReadFiles(edgeMap, edgeDirectedMap, nodeFeatMap, edgeWeightMap);
+
1033  return 0;
+
1034  }
+
1035 
+
1036  template <typename T>
+
1037  void Graph<T>::recreateGraphFromReadFiles(std::map<unsigned long, std::pair<unsigned long, unsigned long>> &edgeMap, std::map<unsigned long, bool> &edgeDirectedMap, std::map<unsigned long, T> &nodeFeatMap, std::map<unsigned long, double> &edgeWeightMap)
+
1038  {
+
1039  std::map<unsigned long, Node<T> *> nodeMap;
+
1040  for (auto edgeIt = edgeMap.begin(); edgeIt != edgeMap.end(); ++edgeIt)
+
1041  {
+
1042  Node<T> *node1 = nullptr;
+
1043  Node<T> *node2 = nullptr;
+
1044  if (nodeMap.find(edgeIt->second.first) == nodeMap.end())
+
1045  {
+
1046  //Create new Node
+
1047  T feat;
+
1048  if (nodeFeatMap.find(edgeIt->second.first) != nodeFeatMap.end())
1049  {
-
1050  auto edge = new UndirectedEdge<T>(edgeIt->first, *node1, *node2);
-
1051  addEdge(edge);
-
1052  }
-
1053  }
-
1054  }
-
1055  }
-
1056 
-
1057  template <typename T>
-
1058  void Graph<T>::greedyPartition(std::map<unsigned int, Partition<T> *> &partitionMap) const
-
1059  {
-
1060  unsigned int index = 0;
-
1061  unsigned int numberOfPartitions = partitionMap.size();
-
1062  if (index == numberOfPartitions)
-
1063  {
-
1064  //ERROR partion map of zero element
-
1065  return;
-
1066  }
-
1067  auto edgeSet = getEdgeSet();
-
1068  for (auto edge : edgeSet)
-
1069  {
-
1070  partitionMap.at(index)->addEdge(edge);
-
1071  index++;
-
1072  index = index % numberOfPartitions;
-
1073  }
-
1074  }
-
1075 
-
1076  template <typename T>
-
1077  const AdjacencyMatrix<T> Graph<T>::getAdjMatrix() const
-
1078  {
-
1079  AdjacencyMatrix<T> adj;
-
1080  auto edgeSetIt = edgeSet.begin();
-
1081  for (edgeSetIt; edgeSetIt != edgeSet.end(); ++edgeSetIt)
-
1082  {
-
1083  if ((*edgeSetIt)->isDirected().has_value() && (*edgeSetIt)->isDirected().value())
-
1084  {
-
1085  const DirectedEdge<T> *d_edge = dynamic_cast<const DirectedEdge<T> *>(*edgeSetIt);
-
1086  addElementToAdjMatrix(adj, &(d_edge->getFrom()), &(d_edge->getTo()), d_edge);
+
1050  feat = nodeFeatMap.at(edgeIt->second.first);
+
1051  }
+
1052  node1 = new Node<T>(edgeIt->second.first, feat);
+
1053  nodeMap[edgeIt->second.first] = node1;
+
1054  }
+
1055  else
+
1056  {
+
1057  node1 = nodeMap.at(edgeIt->second.first);
+
1058  }
+
1059  if (nodeMap.find(edgeIt->second.second) == nodeMap.end())
+
1060  {
+
1061  //Create new Node
+
1062  T feat;
+
1063  if (nodeFeatMap.find(edgeIt->second.second) != nodeFeatMap.end())
+
1064  {
+
1065  feat = nodeFeatMap.at(edgeIt->second.second);
+
1066  }
+
1067  node2 = new Node<T>(edgeIt->second.second, feat);
+
1068  nodeMap[edgeIt->second.second] = node2;
+
1069  }
+
1070  else
+
1071  {
+
1072  node2 = nodeMap.at(edgeIt->second.second);
+
1073  }
+
1074 
+
1075  if (edgeWeightMap.find(edgeIt->first) != edgeWeightMap.end())
+
1076  {
+
1077  if (edgeDirectedMap.find(edgeIt->first) != edgeDirectedMap.end() && edgeDirectedMap.at(edgeIt->first))
+
1078  {
+
1079  auto edge = new DirectedWeightedEdge<T>(edgeIt->first, *node1, *node2, edgeWeightMap.at(edgeIt->first));
+
1080  addEdge(edge);
+
1081  }
+
1082  else
+
1083  {
+
1084  auto edge = new UndirectedWeightedEdge<T>(edgeIt->first, *node1, *node2, edgeWeightMap.at(edgeIt->first));
+
1085  addEdge(edge);
+
1086  }
1087  }
-
1088  else if ((*edgeSetIt)->isDirected().has_value() && !(*edgeSetIt)->isDirected().value())
+
1088  else
1089  {
-
1090  const UndirectedEdge<T> *ud_edge = dynamic_cast<const UndirectedEdge<T> *>(*edgeSetIt);
-
1091  ;
-
1092  addElementToAdjMatrix(adj, &(ud_edge->getNode1()), &(ud_edge->getNode2()), ud_edge);
-
1093  addElementToAdjMatrix(adj, &(ud_edge->getNode2()), &(ud_edge->getNode1()), ud_edge);
-
1094  }
-
1095  else
-
1096  { //is a simple edge we cannot create adj matrix
-
1097  return adj;
-
1098  }
-
1099  }
-
1100  return adj;
-
1101  }
-
1102 
-
1103  template <typename T>
-
1104  const DijkstraResult Graph<T>::dijkstra(const Node<T> &source, const Node<T> &target) const
-
1105  {
-
1106  DijkstraResult result;
-
1107  result.success = false;
-
1108  result.errorMessage = "";
-
1109  result.result = INF_DOUBLE;
-
1110  auto nodeSet = getNodeSet();
-
1111  if (std::find(nodeSet.begin(), nodeSet.end(), &source) == nodeSet.end())
-
1112  {
-
1113  // check if source node exist in the graph
-
1114  result.errorMessage = ERR_DIJ_SOURCE_NODE_NOT_IN_GRAPH;
-
1115  return result;
-
1116  }
-
1117  if (std::find(nodeSet.begin(), nodeSet.end(), &target) == nodeSet.end())
-
1118  {
-
1119  // check if target node exist in the graph
-
1120  result.errorMessage = ERR_DIJ_TARGET_NODE_NOT_IN_GRAPH;
-
1121  return result;
-
1122  }
-
1123  const AdjacencyMatrix<T> adj = getAdjMatrix();
-
1124  // n denotes the number of vertices in graph
-
1125  int n = adj.size();
-
1126 
-
1127  // setting all the distances initially to INF_DOUBLE
-
1128  std::map<const Node<T> *, double> dist;
-
1129 
-
1130  for (auto elem : adj)
-
1131  {
-
1132  dist[elem.first] = INF_DOUBLE;
-
1133  }
-
1134 
-
1135  // creating a min heap using priority queue
-
1136  // first element of pair contains the distance
-
1137  // second element of pair contains the vertex
-
1138  std::priority_queue<std::pair<double, const Node<T> *>, std::vector<std::pair<double, const Node<T> *>>,
-
1139  std::greater<std::pair<double, const Node<T> *>>>
-
1140  pq;
-
1141 
-
1142  // pushing the source vertex 's' with 0 distance in min heap
-
1143  pq.push(std::make_pair(0.0, &source));
-
1144 
-
1145  // marking the distance of source as 0
-
1146  dist[&source] = 0;
-
1147 
-
1148  while (!pq.empty())
-
1149  {
-
1150  // second element of pair denotes the node / vertex
-
1151  const Node<T> *currentNode = pq.top().second;
-
1152 
-
1153  // first element of pair denotes the distance
-
1154  double currentDist = pq.top().first;
-
1155 
-
1156  pq.pop();
-
1157 
-
1158  // for all the reachable vertex from the currently exploring vertex
-
1159  // we will try to minimize the distance
-
1160  if (adj.find(currentNode) != adj.end())
-
1161  {
-
1162  for (std::pair<const Node<T> *, const Edge<T> *> elem : adj.at(currentNode))
-
1163  {
-
1164  // minimizing distances
-
1165  if (elem.second->isWeighted().has_value() && elem.second->isWeighted().value())
-
1166  {
-
1167  if (elem.second->isDirected().has_value() && elem.second->isDirected().value())
-
1168  {
-
1169  const DirectedWeightedEdge<T> *dw_edge = dynamic_cast<const DirectedWeightedEdge<T> *>(elem.second);
-
1170  if (currentDist + dw_edge->getWeight() < dist[elem.first])
-
1171  {
-
1172  dist[elem.first] = currentDist + dw_edge->getWeight();
-
1173  pq.push(std::make_pair(dist[elem.first], elem.first));
-
1174  }
-
1175  }
-
1176  else if (elem.second->isDirected().has_value() && !elem.second->isDirected().value())
-
1177  {
-
1178  const UndirectedWeightedEdge<T> *udw_edge = dynamic_cast<const UndirectedWeightedEdge<T> *>(elem.second);
-
1179  if (currentDist + udw_edge->getWeight() < dist[elem.first])
-
1180  {
-
1181  dist[elem.first] = currentDist + udw_edge->getWeight();
-
1182  pq.push(std::make_pair(dist[elem.first], elem.first));
-
1183  }
-
1184  }
-
1185  else
-
1186  {
-
1187  //ERROR it shouldn't never returned ( does not exist a Node Weighted and not Directed/Undirected)
-
1188  result.errorMessage = ERR_NO_DIR_OR_UNDIR_EDGE;
-
1189  return result;
-
1190  }
-
1191  }
-
1192  else
-
1193  {
-
1194  // No Weighted Edge
-
1195  result.errorMessage = ERR_NO_WEIGHTED_EDGE;
-
1196  return result;
-
1197  }
-
1198  }
-
1199  }
-
1200  }
-
1201  if (dist[&target] != INF_DOUBLE)
-
1202  {
-
1203  result.success = true;
-
1204  result.errorMessage = "";
-
1205  result.result = dist[&target];
-
1206  return result;
-
1207  }
-
1208  result.errorMessage = ERR_DIJ_TARGET_NODE_NOT_REACHABLE;
-
1209  result.result = -1;
-
1210  return result;
-
1211  }
-
1212 
-
1213  template <typename T>
-
1214  const std::vector<Node<T>> Graph<T>::breadth_first_search(const Node<T> &start) const
-
1215  {
-
1216  // vector to keep track of visited nodes
-
1217  std::vector<Node<T>> visited;
-
1218  auto nodeSet = getNodeSet();
-
1219  //check is exist node in the graph
-
1220  if (std::find(nodeSet.begin(), nodeSet.end(), &start) == nodeSet.end())
-
1221  {
-
1222  return visited;
-
1223  }
-
1224  const AdjacencyMatrix<T> adj = getAdjMatrix();
-
1225  // queue that stores vertices that need to be further explored
-
1226  std::queue<const Node<T> *> tracker;
-
1227 
-
1228  // mark the starting node as visited
-
1229  visited.push_back(start);
-
1230  tracker.push(&start);
-
1231  while (!tracker.empty())
-
1232  {
-
1233  const Node<T> *node = tracker.front();
-
1234  tracker.pop();
-
1235  if (adj.find(node) != adj.end())
-
1236  {
-
1237  for (auto elem : adj.at(node))
-
1238  {
-
1239  // if the node is not visited then mark it as visited
-
1240  // and push it to the queue
-
1241  if (std::find(visited.begin(), visited.end(), *(elem.first)) == visited.end())
-
1242  {
-
1243  visited.push_back(*(elem.first));
-
1244  tracker.push(elem.first);
-
1245  }
-
1246  }
-
1247  }
-
1248  }
-
1249 
-
1250  return visited;
-
1251  }
-
1252 
-
1253  template <typename T>
-
1254  const std::vector<Node<T>> Graph<T>::depth_first_search(const Node<T> &start) const
-
1255  {
-
1256  // vector to keep track of visited nodes
-
1257  std::vector<Node<T>> visited;
-
1258  auto nodeSet = getNodeSet();
-
1259  //check is exist node in the graph
-
1260  if (std::find(nodeSet.begin(), nodeSet.end(), &start) == nodeSet.end())
-
1261  {
-
1262  return visited;
-
1263  }
-
1264  const AdjacencyMatrix<T> adj = getAdjMatrix();
-
1265  std::function<void(const AdjacencyMatrix<T> &, const Node<T> &, std::vector<Node<T>> &)> explore;
-
1266  explore = [&explore](const AdjacencyMatrix<T> &adj, const Node<T> &node, std::vector<Node<T>> &visited) -> void
-
1267  {
-
1268  visited.push_back(node);
-
1269  if (adj.find(&node) != adj.end())
-
1270  {
-
1271  for (auto x : adj.at(&node))
-
1272  {
-
1273  if (std::find(visited.begin(), visited.end(), *(x.first)) == visited.end())
-
1274  {
-
1275  explore(adj, *(x.first), visited);
-
1276  }
-
1277  }
-
1278  }
-
1279  };
-
1280  explore(adj, start, visited);
-
1281 
-
1282  return visited;
-
1283  }
-
1284 
-
1285  template <typename T>
- -
1287  {
-
1288  if (!isDirectedGraph())
-
1289  {
-
1290  return false;
-
1291  }
-
1292  enum nodeStates : uint8_t
-
1293  {
-
1294  not_visited,
-
1295  in_stack,
-
1296  visited
-
1297  };
-
1298  auto nodeSet = this->getNodeSet();
-
1299  auto adjMatrix = this->getAdjMatrix();
-
1300 
-
1301  /* State of the node.
-
1302  *
-
1303  * It is a vector of "nodeStates" which represents the state node is in.
-
1304  * It can take only 3 values: "not_visited", "in_stack", and "visited".
-
1305  *
-
1306  * Initially, all nodes are in "not_visited" state.
-
1307  */
-
1308  std::map<unsigned long, nodeStates> state;
-
1309  for (auto node : nodeSet)
-
1310  {
-
1311  state[node->getId()] = not_visited;
-
1312  }
-
1313  int stateCounter = 0;
-
1314 
-
1315  // Start visiting each node.
-
1316  for (auto node : nodeSet)
-
1317  {
-
1318  // If a node is not visited, only then check for presence of cycle.
-
1319  // There is no need to check for presence of cycle for a visited
-
1320  // node as it has already been checked for presence of cycle.
-
1321  if (state[node->getId()] == not_visited)
-
1322  {
-
1323  // Check for cycle.
-
1324  std::function<bool(AdjacencyMatrix<T> &, std::map<unsigned long, nodeStates> &, const Node<T> *)> isCyclicDFSHelper;
-
1325  isCyclicDFSHelper = [this, &isCyclicDFSHelper](AdjacencyMatrix<T> &adjMatrix, std::map<unsigned long, nodeStates> &states, const Node<T> *node)
-
1326  {
-
1327  // Add node "in_stack" state.
-
1328  states[node->getId()] = in_stack;
-
1329 
-
1330  // If the node has children, then recursively visit all children of the
-
1331  // node.
-
1332  auto const it = adjMatrix.find(node);
-
1333  if (it != adjMatrix.end())
-
1334  {
-
1335  for (auto child : it->second)
-
1336  {
-
1337  // If state of child node is "not_visited", evaluate that child
-
1338  // for presence of cycle.
-
1339  auto state_of_child = states.at((std::get<0>(child))->getId());
-
1340  if (state_of_child == not_visited)
-
1341  {
-
1342  if (isCyclicDFSHelper(adjMatrix, states, std::get<0>(child)))
-
1343  {
-
1344  return true;
-
1345  }
-
1346  }
-
1347  else if (state_of_child == in_stack)
-
1348  {
-
1349  // If child node was "in_stack", then that means that there
-
1350  // is a cycle in the graph. Return true for presence of the
-
1351  // cycle.
-
1352  return true;
-
1353  }
-
1354  }
-
1355  }
-
1356 
-
1357  // Current node has been evaluated for the presence of cycle and had no
-
1358  // cycle. Mark current node as "visited".
-
1359  states[node->getId()] = visited;
-
1360  // Return that current node didn't result in any cycles.
-
1361  return false;
-
1362  };
-
1363  if (isCyclicDFSHelper(adjMatrix, state, node))
-
1364  {
-
1365  return true;
-
1366  }
-
1367  }
-
1368  }
-
1369 
-
1370  // All nodes have been safely traversed, that means there is no cycle in
-
1371  // the graph. Return false.
-
1372  return false;
-
1373  }
-
1374 
-
1375  template <typename T>
- -
1377  {
-
1378  if (!isDirectedGraph())
-
1379  {
-
1380  return false;
-
1381  }
-
1382  auto adjMatrix = this->getAdjMatrix();
-
1383  auto nodeSet = this->getNodeSet();
-
1384 
-
1385  std::map<unsigned long, unsigned int> indegree;
-
1386  for (auto node : nodeSet)
-
1387  {
-
1388  indegree[node->getId()] = 0;
-
1389  }
-
1390  // Calculate the indegree i.e. the number of incident edges to the node.
-
1391  for (auto const &list : adjMatrix)
-
1392  {
-
1393  auto children = list.second;
-
1394  for (auto const &child : children)
-
1395  {
-
1396  indegree[std::get<0>(child)->getId()]++;
-
1397  }
-
1398  }
-
1399 
-
1400  std::queue<const Node<T> *> can_be_solved;
-
1401  for (auto node : nodeSet)
-
1402  {
-
1403  // If a node doesn't have any input edges, then that node will
-
1404  // definately not result in a cycle and can be visited safely.
-
1405  if (!indegree[node->getId()])
-
1406  {
-
1407  can_be_solved.emplace(&(*node));
-
1408  }
-
1409  }
-
1410 
-
1411  // Vertices that need to be traversed.
-
1412  auto remain = this->getNodeSet().size();
-
1413  // While there are safe nodes that we can visit.
-
1414  while (!can_be_solved.empty())
-
1415  {
-
1416  auto solved = can_be_solved.front();
-
1417  // Visit the node.
-
1418  can_be_solved.pop();
-
1419  // Decrease number of nodes that need to be traversed.
-
1420  remain--;
+
1090  if (edgeDirectedMap.find(edgeIt->first) != edgeDirectedMap.end() && edgeDirectedMap.at(edgeIt->first))
+
1091  {
+
1092  auto edge = new DirectedEdge<T>(edgeIt->first, *node1, *node2);
+
1093  addEdge(edge);
+
1094  }
+
1095  else
+
1096  {
+
1097  auto edge = new UndirectedEdge<T>(edgeIt->first, *node1, *node2);
+
1098  addEdge(edge);
+
1099  }
+
1100  }
+
1101  }
+
1102  }
+
1103 
+
1104  template <typename T>
+
1105  void Graph<T>::greedyPartition(PartitionMap<T> &partitionMap) const
+
1106  {
+
1107  unsigned int index = 0;
+
1108  unsigned int numberOfPartitions = partitionMap.size();
+
1109  if (index == numberOfPartitions)
+
1110  {
+
1111  //ERROR partition map of zero element
+
1112  return;
+
1113  }
+
1114  auto edgeSet = getEdgeSet();
+
1115  for (auto edge : edgeSet)
+
1116  {
+
1117  partitionMap.at(index)->addEdge(edge);
+
1118  index++;
+
1119  index = index % numberOfPartitions;
+
1120  }
+
1121  }
+
1122 
+
1123  template <typename T>
+
1124  const AdjacencyMatrix<T> Graph<T>::getAdjMatrix() const
+
1125  {
+
1126  AdjacencyMatrix<T> adj;
+
1127  auto edgeSetIt = edgeSet.begin();
+
1128  for (edgeSetIt; edgeSetIt != edgeSet.end(); ++edgeSetIt)
+
1129  {
+
1130  if ((*edgeSetIt)->isDirected().has_value() && (*edgeSetIt)->isDirected().value())
+
1131  {
+
1132  const DirectedEdge<T> *d_edge = dynamic_cast<const DirectedEdge<T> *>(*edgeSetIt);
+
1133  addElementToAdjMatrix(adj, &(d_edge->getFrom()), &(d_edge->getTo()), d_edge);
+
1134  }
+
1135  else if ((*edgeSetIt)->isDirected().has_value() && !(*edgeSetIt)->isDirected().value())
+
1136  {
+
1137  const UndirectedEdge<T> *ud_edge = dynamic_cast<const UndirectedEdge<T> *>(*edgeSetIt);
+
1138  ;
+
1139  addElementToAdjMatrix(adj, &(ud_edge->getNode1()), &(ud_edge->getNode2()), ud_edge);
+
1140  addElementToAdjMatrix(adj, &(ud_edge->getNode2()), &(ud_edge->getNode1()), ud_edge);
+
1141  }
+
1142  else
+
1143  { //is a simple edge we cannot create adj matrix
+
1144  return adj;
+
1145  }
+
1146  }
+
1147  return adj;
+
1148  }
+
1149 
+
1150  template <typename T>
+
1151  const DijkstraResult Graph<T>::dijkstra(const Node<T> &source, const Node<T> &target) const
+
1152  {
+
1153  DijkstraResult result;
+
1154  result.success = false;
+
1155  result.errorMessage = "";
+
1156  result.result = INF_DOUBLE;
+
1157  auto nodeSet = getNodeSet();
+
1158  if (std::find(nodeSet.begin(), nodeSet.end(), &source) == nodeSet.end())
+
1159  {
+
1160  // check if source node exist in the graph
+
1161  result.errorMessage = ERR_DIJ_SOURCE_NODE_NOT_IN_GRAPH;
+
1162  return result;
+
1163  }
+
1164  if (std::find(nodeSet.begin(), nodeSet.end(), &target) == nodeSet.end())
+
1165  {
+
1166  // check if target node exist in the graph
+
1167  result.errorMessage = ERR_DIJ_TARGET_NODE_NOT_IN_GRAPH;
+
1168  return result;
+
1169  }
+
1170  const AdjacencyMatrix<T> adj = getAdjMatrix();
+
1171  // n denotes the number of vertices in graph
+
1172  int n = adj.size();
+
1173 
+
1174  // setting all the distances initially to INF_DOUBLE
+
1175  std::map<const Node<T> *, double> dist;
+
1176 
+
1177  for (auto elem : adj)
+
1178  {
+
1179  dist[elem.first] = INF_DOUBLE;
+
1180  }
+
1181 
+
1182  // creating a min heap using priority queue
+
1183  // first element of pair contains the distance
+
1184  // second element of pair contains the vertex
+
1185  std::priority_queue<std::pair<double, const Node<T> *>, std::vector<std::pair<double, const Node<T> *>>,
+
1186  std::greater<std::pair<double, const Node<T> *>>>
+
1187  pq;
+
1188 
+
1189  // pushing the source vertex 's' with 0 distance in min heap
+
1190  pq.push(std::make_pair(0.0, &source));
+
1191 
+
1192  // marking the distance of source as 0
+
1193  dist[&source] = 0;
+
1194 
+
1195  while (!pq.empty())
+
1196  {
+
1197  // second element of pair denotes the node / vertex
+
1198  const Node<T> *currentNode = pq.top().second;
+
1199 
+
1200  // first element of pair denotes the distance
+
1201  double currentDist = pq.top().first;
+
1202 
+
1203  pq.pop();
+
1204 
+
1205  // for all the reachable vertex from the currently exploring vertex
+
1206  // we will try to minimize the distance
+
1207  if (adj.find(currentNode) != adj.end())
+
1208  {
+
1209  for (std::pair<const Node<T> *, const Edge<T> *> elem : adj.at(currentNode))
+
1210  {
+
1211  // minimizing distances
+
1212  if (elem.second->isWeighted().has_value() && elem.second->isWeighted().value())
+
1213  {
+
1214  if (elem.second->isDirected().has_value() && elem.second->isDirected().value())
+
1215  {
+
1216  const DirectedWeightedEdge<T> *dw_edge = dynamic_cast<const DirectedWeightedEdge<T> *>(elem.second);
+
1217  if (currentDist + dw_edge->getWeight() < dist[elem.first])
+
1218  {
+
1219  dist[elem.first] = currentDist + dw_edge->getWeight();
+
1220  pq.push(std::make_pair(dist[elem.first], elem.first));
+
1221  }
+
1222  }
+
1223  else if (elem.second->isDirected().has_value() && !elem.second->isDirected().value())
+
1224  {
+
1225  const UndirectedWeightedEdge<T> *udw_edge = dynamic_cast<const UndirectedWeightedEdge<T> *>(elem.second);
+
1226  if (currentDist + udw_edge->getWeight() < dist[elem.first])
+
1227  {
+
1228  dist[elem.first] = currentDist + udw_edge->getWeight();
+
1229  pq.push(std::make_pair(dist[elem.first], elem.first));
+
1230  }
+
1231  }
+
1232  else
+
1233  {
+
1234  //ERROR it shouldn't never returned ( does not exist a Node Weighted and not Directed/Undirected)
+
1235  result.errorMessage = ERR_NO_DIR_OR_UNDIR_EDGE;
+
1236  return result;
+
1237  }
+
1238  }
+
1239  else
+
1240  {
+
1241  // No Weighted Edge
+
1242  result.errorMessage = ERR_NO_WEIGHTED_EDGE;
+
1243  return result;
+
1244  }
+
1245  }
+
1246  }
+
1247  }
+
1248  if (dist[&target] != INF_DOUBLE)
+
1249  {
+
1250  result.success = true;
+
1251  result.errorMessage = "";
+
1252  result.result = dist[&target];
+
1253  return result;
+
1254  }
+
1255  result.errorMessage = ERR_DIJ_TARGET_NODE_NOT_REACHABLE;
+
1256  result.result = -1;
+
1257  return result;
+
1258  }
+
1259 
+
1260  template <typename T>
+
1261  const std::vector<Node<T>> Graph<T>::breadth_first_search(const Node<T> &start) const
+
1262  {
+
1263  // vector to keep track of visited nodes
+
1264  std::vector<Node<T>> visited;
+
1265  auto nodeSet = getNodeSet();
+
1266  //check is exist node in the graph
+
1267  if (std::find(nodeSet.begin(), nodeSet.end(), &start) == nodeSet.end())
+
1268  {
+
1269  return visited;
+
1270  }
+
1271  const AdjacencyMatrix<T> adj = getAdjMatrix();
+
1272  // queue that stores vertices that need to be further explored
+
1273  std::queue<const Node<T> *> tracker;
+
1274 
+
1275  // mark the starting node as visited
+
1276  visited.push_back(start);
+
1277  tracker.push(&start);
+
1278  while (!tracker.empty())
+
1279  {
+
1280  const Node<T> *node = tracker.front();
+
1281  tracker.pop();
+
1282  if (adj.find(node) != adj.end())
+
1283  {
+
1284  for (auto elem : adj.at(node))
+
1285  {
+
1286  // if the node is not visited then mark it as visited
+
1287  // and push it to the queue
+
1288  if (std::find(visited.begin(), visited.end(), *(elem.first)) == visited.end())
+
1289  {
+
1290  visited.push_back(*(elem.first));
+
1291  tracker.push(elem.first);
+
1292  }
+
1293  }
+
1294  }
+
1295  }
+
1296 
+
1297  return visited;
+
1298  }
+
1299 
+
1300  template <typename T>
+
1301  const std::vector<Node<T>> Graph<T>::depth_first_search(const Node<T> &start) const
+
1302  {
+
1303  // vector to keep track of visited nodes
+
1304  std::vector<Node<T>> visited;
+
1305  auto nodeSet = getNodeSet();
+
1306  //check is exist node in the graph
+
1307  if (std::find(nodeSet.begin(), nodeSet.end(), &start) == nodeSet.end())
+
1308  {
+
1309  return visited;
+
1310  }
+
1311  const AdjacencyMatrix<T> adj = getAdjMatrix();
+
1312  std::function<void(const AdjacencyMatrix<T> &, const Node<T> &, std::vector<Node<T>> &)> explore;
+
1313  explore = [&explore](const AdjacencyMatrix<T> &adj, const Node<T> &node, std::vector<Node<T>> &visited) -> void
+
1314  {
+
1315  visited.push_back(node);
+
1316  if (adj.find(&node) != adj.end())
+
1317  {
+
1318  for (auto x : adj.at(&node))
+
1319  {
+
1320  if (std::find(visited.begin(), visited.end(), *(x.first)) == visited.end())
+
1321  {
+
1322  explore(adj, *(x.first), visited);
+
1323  }
+
1324  }
+
1325  }
+
1326  };
+
1327  explore(adj, start, visited);
+
1328 
+
1329  return visited;
+
1330  }
+
1331 
+
1332  template <typename T>
+ +
1334  {
+
1335  if (!isDirectedGraph())
+
1336  {
+
1337  return false;
+
1338  }
+
1339  enum nodeStates : uint8_t
+
1340  {
+
1341  not_visited,
+
1342  in_stack,
+
1343  visited
+
1344  };
+
1345  auto nodeSet = this->getNodeSet();
+
1346  auto adjMatrix = this->getAdjMatrix();
+
1347 
+
1348  /* State of the node.
+
1349  *
+
1350  * It is a vector of "nodeStates" which represents the state node is in.
+
1351  * It can take only 3 values: "not_visited", "in_stack", and "visited".
+
1352  *
+
1353  * Initially, all nodes are in "not_visited" state.
+
1354  */
+
1355  std::map<unsigned long, nodeStates> state;
+
1356  for (auto node : nodeSet)
+
1357  {
+
1358  state[node->getId()] = not_visited;
+
1359  }
+
1360  int stateCounter = 0;
+
1361 
+
1362  // Start visiting each node.
+
1363  for (auto node : nodeSet)
+
1364  {
+
1365  // If a node is not visited, only then check for presence of cycle.
+
1366  // There is no need to check for presence of cycle for a visited
+
1367  // node as it has already been checked for presence of cycle.
+
1368  if (state[node->getId()] == not_visited)
+
1369  {
+
1370  // Check for cycle.
+
1371  std::function<bool(AdjacencyMatrix<T> &, std::map<unsigned long, nodeStates> &, const Node<T> *)> isCyclicDFSHelper;
+
1372  isCyclicDFSHelper = [this, &isCyclicDFSHelper](AdjacencyMatrix<T> &adjMatrix, std::map<unsigned long, nodeStates> &states, const Node<T> *node)
+
1373  {
+
1374  // Add node "in_stack" state.
+
1375  states[node->getId()] = in_stack;
+
1376 
+
1377  // If the node has children, then recursively visit all children of the
+
1378  // node.
+
1379  auto const it = adjMatrix.find(node);
+
1380  if (it != adjMatrix.end())
+
1381  {
+
1382  for (auto child : it->second)
+
1383  {
+
1384  // If state of child node is "not_visited", evaluate that child
+
1385  // for presence of cycle.
+
1386  auto state_of_child = states.at((std::get<0>(child))->getId());
+
1387  if (state_of_child == not_visited)
+
1388  {
+
1389  if (isCyclicDFSHelper(adjMatrix, states, std::get<0>(child)))
+
1390  {
+
1391  return true;
+
1392  }
+
1393  }
+
1394  else if (state_of_child == in_stack)
+
1395  {
+
1396  // If child node was "in_stack", then that means that there
+
1397  // is a cycle in the graph. Return true for presence of the
+
1398  // cycle.
+
1399  return true;
+
1400  }
+
1401  }
+
1402  }
+
1403 
+
1404  // Current node has been evaluated for the presence of cycle and had no
+
1405  // cycle. Mark current node as "visited".
+
1406  states[node->getId()] = visited;
+
1407  // Return that current node didn't result in any cycles.
+
1408  return false;
+
1409  };
+
1410  if (isCyclicDFSHelper(adjMatrix, state, node))
+
1411  {
+
1412  return true;
+
1413  }
+
1414  }
+
1415  }
+
1416 
+
1417  // All nodes have been safely traversed, that means there is no cycle in
+
1418  // the graph. Return false.
+
1419  return false;
+
1420  }
1421 
-
1422  // Visit all the children of the visited node.
-
1423  auto it = adjMatrix.find(solved);
-
1424  if (it != adjMatrix.end())
-
1425  {
-
1426  for (auto child : it->second)
-
1427  {
-
1428  // Check if we can visited the node safely.
-
1429  if (--indegree[std::get<0>(child)->getId()] == 0)
-
1430  {
-
1431  // if node can be visited safely, then add that node to
-
1432  // the visit queue.
-
1433  can_be_solved.emplace(std::get<0>(child));
-
1434  }
-
1435  }
-
1436  }
-
1437  }
-
1438 
-
1439  // If there are still nodes that we can't visit, then it means that
-
1440  // there is a cycle and return true, else return false.
-
1441  return !(remain == 0);
-
1442  }
-
1443 
-
1444  template <typename T>
- -
1446  {
-
1447  auto edgeSet = this->getEdgeSet();
-
1448  for (auto edge : edgeSet)
+
1422  template <typename T>
+ +
1424  {
+
1425  if (!isDirectedGraph())
+
1426  {
+
1427  return false;
+
1428  }
+
1429  auto adjMatrix = this->getAdjMatrix();
+
1430  auto nodeSet = this->getNodeSet();
+
1431 
+
1432  std::map<unsigned long, unsigned int> indegree;
+
1433  for (auto node : nodeSet)
+
1434  {
+
1435  indegree[node->getId()] = 0;
+
1436  }
+
1437  // Calculate the indegree i.e. the number of incident edges to the node.
+
1438  for (auto const &list : adjMatrix)
+
1439  {
+
1440  auto children = list.second;
+
1441  for (auto const &child : children)
+
1442  {
+
1443  indegree[std::get<0>(child)->getId()]++;
+
1444  }
+
1445  }
+
1446 
+
1447  std::queue<const Node<T> *> can_be_solved;
+
1448  for (auto node : nodeSet)
1449  {
-
1450  if (!(edge->isDirected().has_value() && edge->isDirected().value()))
-
1451  {
-
1452  //Found Undirected Edge
-
1453  return false;
-
1454  }
-
1455  }
-
1456  //No Undirected Edge
-
1457  return true;
-
1458  }
-
1459 
-
1460  template <typename T>
-
1461  int Graph<T>::writeToFile(InputOutputFormat format, const std::string &workingDir, const std::string &OFileName, bool compress, bool writeNodeFeat, bool writeEdgeWeight) const
-
1462  {
-
1463  if (format == InputOutputFormat::STANDARD_CSV)
-
1464  {
-
1465  return writeToStandardFile_csv(workingDir, OFileName, compress, writeNodeFeat, writeEdgeWeight);
-
1466  }
-
1467  else if (format == InputOutputFormat::STANDARD_TSV)
-
1468  {
-
1469  return writeToStandardFile_tsv(workingDir, OFileName, compress, writeNodeFeat, writeEdgeWeight);
-
1470  }
-
1471  else
-
1472  {
-
1473  //OUTPUT FORMAT NOT RECOGNIZED
-
1474  return -1;
-
1475  }
-
1476  }
-
1477 
-
1478  template <typename T>
-
1479  int Graph<T>::readFromFile(InputOutputFormat format, const std::string &workingDir, const std::string &OFileName, bool compress, bool readNodeFeat, bool readEdgeWeight)
-
1480  {
-
1481  if (format == InputOutputFormat::STANDARD_CSV)
-
1482  {
-
1483  return readFromStandardFile_csv(workingDir, OFileName, compress, readNodeFeat, readEdgeWeight);
+
1450  // If a node doesn't have any input edges, then that node will
+
1451  // definately not result in a cycle and can be visited safely.
+
1452  if (!indegree[node->getId()])
+
1453  {
+
1454  can_be_solved.emplace(&(*node));
+
1455  }
+
1456  }
+
1457 
+
1458  // Vertices that need to be traversed.
+
1459  auto remain = this->getNodeSet().size();
+
1460  // While there are safe nodes that we can visit.
+
1461  while (!can_be_solved.empty())
+
1462  {
+
1463  auto solved = can_be_solved.front();
+
1464  // Visit the node.
+
1465  can_be_solved.pop();
+
1466  // Decrease number of nodes that need to be traversed.
+
1467  remain--;
+
1468 
+
1469  // Visit all the children of the visited node.
+
1470  auto it = adjMatrix.find(solved);
+
1471  if (it != adjMatrix.end())
+
1472  {
+
1473  for (auto child : it->second)
+
1474  {
+
1475  // Check if we can visited the node safely.
+
1476  if (--indegree[std::get<0>(child)->getId()] == 0)
+
1477  {
+
1478  // if node can be visited safely, then add that node to
+
1479  // the visit queue.
+
1480  can_be_solved.emplace(std::get<0>(child));
+
1481  }
+
1482  }
+
1483  }
1484  }
-
1485  else if (format == InputOutputFormat::STANDARD_TSV)
-
1486  {
-
1487  return readFromStandardFile_tsv(workingDir, OFileName, compress, readNodeFeat, readEdgeWeight);
-
1488  }
-
1489  else
-
1490  {
-
1491  //OUTPUT FORMAT NOT RECOGNIZED
-
1492  return -1;
-
1493  }
-
1494  }
-
1495 
-
1496  template <typename T>
-
1497  std::map<unsigned int, Partition<T> *> Graph<T>::partitionGraph(PartitionAlgorithm algorithm, unsigned int numberOfPartitions) const
-
1498  {
-
1499  std::map<unsigned int, Partition<T> *> partitionMap;
-
1500  for (unsigned int i = 0; i < numberOfPartitions; ++i)
-
1501  {
-
1502  partitionMap[i] = new Partition<T>(i);
-
1503  }
-
1504  if (algorithm == PartitionAlgorithm::GREEDY_VC)
-
1505  {
-
1506  greedyPartition(partitionMap);
-
1507  }
-
1508  else
-
1509  {
-
1510  //Error not recognized algorithm
-
1511  partitionMap.clear();
-
1512  }
-
1513  return partitionMap;
-
1514  }
-
1515 
-
1516  template <typename T>
-
1517  class Partition : public Graph<T>
-
1518  {
-
1519  public:
-
1520  Partition();
-
1521  Partition(unsigned int partitionId);
-
1522  Partition(const std::list<const Edge<T> *> &edgeSet);
-
1523  Partition(unsigned int partitionId, const std::list<const Edge<T> *> &edgeSet);
-
1524  ~Partition() = default;
-
1525 
-
1526  unsigned int getPartitionId() const;
-
1527  void setPartitionId(unsigned int partitionId);
-
1528 
-
1529  private:
-
1530  unsigned int partitionId;
-
1531  };
-
1532 
-
1533  template <typename T>
- -
1535  {
-
1536  partitionId = 0;
-
1537  }
-
1538 
-
1539  template <typename T>
-
1540  Partition<T>::Partition(unsigned int partitionId) : Graph<T>()
-
1541  {
-
1542  this->partitionId = partitionId;
-
1543  }
-
1544 
-
1545  template <typename T>
-
1546  Partition<T>::Partition(const std::list<const Edge<T> *> &edgeSet) : Graph<T>(edgeSet)
-
1547  {
-
1548  partitionId = 0;
-
1549  }
-
1550 
-
1551  template <typename T>
-
1552  Partition<T>::Partition(unsigned int partitionId, const std::list<const Edge<T> *> &edgeSet) : Graph<T>(edgeSet)
-
1553  {
-
1554  this->partitionId = partitionId;
-
1555  }
-
1556 
-
1557  template <typename T>
-
1558  unsigned int Partition<T>::getPartitionId() const
-
1559  {
-
1560  return partitionId;
+
1485 
+
1486  // If there are still nodes that we can't visit, then it means that
+
1487  // there is a cycle and return true, else return false.
+
1488  return !(remain == 0);
+
1489  }
+
1490 
+
1491  template <typename T>
+ +
1493  {
+
1494  auto edgeSet = this->getEdgeSet();
+
1495  for (auto edge : edgeSet)
+
1496  {
+
1497  if (!(edge->isDirected().has_value() && edge->isDirected().value()))
+
1498  {
+
1499  //Found Undirected Edge
+
1500  return false;
+
1501  }
+
1502  }
+
1503  //No Undirected Edge
+
1504  return true;
+
1505  }
+
1506 
+
1507  template <typename T>
+
1508  int Graph<T>::writeToFile(InputOutputFormat format, const std::string &workingDir, const std::string &OFileName, bool compress, bool writeNodeFeat, bool writeEdgeWeight) const
+
1509  {
+
1510  if (format == InputOutputFormat::STANDARD_CSV)
+
1511  {
+
1512  return writeToStandardFile_csv(workingDir, OFileName, compress, writeNodeFeat, writeEdgeWeight);
+
1513  }
+
1514  else if (format == InputOutputFormat::STANDARD_TSV)
+
1515  {
+
1516  return writeToStandardFile_tsv(workingDir, OFileName, compress, writeNodeFeat, writeEdgeWeight);
+
1517  }
+
1518  else
+
1519  {
+
1520  //OUTPUT FORMAT NOT RECOGNIZED
+
1521  return -1;
+
1522  }
+
1523  }
+
1524 
+
1525  template <typename T>
+
1526  int Graph<T>::readFromFile(InputOutputFormat format, const std::string &workingDir, const std::string &OFileName, bool compress, bool readNodeFeat, bool readEdgeWeight)
+
1527  {
+
1528  if (format == InputOutputFormat::STANDARD_CSV)
+
1529  {
+
1530  return readFromStandardFile_csv(workingDir, OFileName, compress, readNodeFeat, readEdgeWeight);
+
1531  }
+
1532  else if (format == InputOutputFormat::STANDARD_TSV)
+
1533  {
+
1534  return readFromStandardFile_tsv(workingDir, OFileName, compress, readNodeFeat, readEdgeWeight);
+
1535  }
+
1536  else
+
1537  {
+
1538  //OUTPUT FORMAT NOT RECOGNIZED
+
1539  return -1;
+
1540  }
+
1541  }
+
1542 
+
1543  template <typename T>
+
1544  PartitionMap<T> Graph<T>::partitionGraph(PartitionAlgorithm algorithm, unsigned int numberOfPartitions) const
+
1545  {
+
1546  PartitionMap<T> partitionMap;
+
1547  for (unsigned int i = 0; i < numberOfPartitions; ++i)
+
1548  {
+
1549  partitionMap[i] = new Partition<T>(i);
+
1550  }
+
1551  if (algorithm == PartitionAlgorithm::GREEDY_VC)
+
1552  {
+
1553  greedyPartition(partitionMap);
+
1554  }
+
1555  else
+
1556  {
+
1557  //Error not recognized algorithm
+
1558  partitionMap.clear();
+
1559  }
+
1560  return partitionMap;
1561  }
1562 
1563  template <typename T>
-
1564  void Partition<T>::setPartitionId(unsigned int partitionId)
+
1564  class Partition : public Graph<T>
1565  {
-
1566  this->partitionId = partitionId;
-
1567  }
-
1568 
-
1569  //ostream overload
-
1570  template <typename T>
-
1571  std::ostream &operator<<(std::ostream &os, const Node<T> &node)
-
1572  {
-
1573  os << "Node: {\n"
-
1574  << " Id:\t" << node.id << "\n Data:\t" << node.data << "\n}";
-
1575  return os;
-
1576  }
-
1577 
-
1578  template <typename T>
-
1579  std::ostream &operator<<(std::ostream &os, const Edge<T> &edge)
-
1580  {
-
1581  os << "((Node: " << edge.nodePair.first->getId() << ")) ?----- |Edge: " << edge.id << "|-----? ((Node: " << edge.nodePair.second->getId() << "))";
-
1582  return os;
-
1583  }
+
1566  public:
+
1567  Partition();
+
1568  Partition(unsigned int partitionId);
+
1569  Partition(const std::list<const Edge<T> *> &edgeSet);
+
1570  Partition(unsigned int partitionId, const std::list<const Edge<T> *> &edgeSet);
+
1571  ~Partition() = default;
+
1577  unsigned int getPartitionId() const;
+
1583  void setPartitionId(unsigned int partitionId);
1584 
-
1585  template <typename T>
-
1586  std::ostream &operator<<(std::ostream &os, const DirectedEdge<T> &edge)
-
1587  {
-
1588  os << "((Node: " << edge.getFrom().getId() << ")) +----- |Edge: #" << edge.getId() << "|-----> ((Node: " << edge.getTo().getId() << "))";
-
1589  return os;
-
1590  }
-
1591 
-
1592  template <typename T>
-
1593  std::ostream &operator<<(std::ostream &os, const UndirectedEdge<T> &edge)
-
1594  {
-
1595  os << "((Node: " << edge.getNode1().getId() << ")) <----- |Edge: #" << edge.getId() << "|-----> ((Node: " << edge.getNode2().getId() << "))";
-
1596  return os;
-
1597  }
+
1585  private:
+
1586  unsigned int partitionId;
+
1587  };
+
1588 
+
1596  template <typename T>
+
1597  static PartitioningStats getPartitionStats(const PartitionMap<T> &partitionMap);
1598 
-
1599  template <typename T>
-
1600  std::ostream &operator<<(std::ostream &os, const DirectedWeightedEdge<T> &edge)
-
1601  {
-
1602  os << "((Node: " << edge.getFrom().getId() << ")) +----- |Edge: #" << edge.getId() << " W:" << edge.getWeight() << "|-----> ((Node: " << edge.getTo().getId() << "))";
-
1603  return os;
-
1604  }
-
1605 
1606  template <typename T>
-
1607  std::ostream &operator<<(std::ostream &os, const UndirectedWeightedEdge<T> &edge)
-
1608  {
-
1609  os << "((Node: " << edge.getNode1().getId() << ")) <----- |Edge: #" << edge.getId() << " W:" << edge.getWeight() << "|-----> ((Node: " << edge.getNode2().getId() << "))";
-
1610  return os;
-
1611  }
-
1612 
-
1613  template <typename T>
-
1614  std::ostream &operator<<(std::ostream &os, const AdjacencyMatrix<T> &adj)
-
1615  {
-
1616  os << "Adjacency Matrix:\n";
-
1617  auto it = adj.begin();
-
1618  unsigned long max_column = 0;
-
1619  for (it; it != adj.end(); ++it)
-
1620  {
-
1621  if (it->second.size() > max_column)
-
1622  {
-
1623  max_column = it->second.size();
-
1624  }
-
1625  }
-
1626  if (max_column == 0)
-
1627  {
-
1628  os << "ERROR in Print\n";
-
1629  return os;
-
1630  }
-
1631  else
-
1632  {
-
1633  it = adj.begin();
-
1634  os << "|--|";
-
1635  for (int i = 0; i < max_column; i++)
-
1636  {
-
1637  os << "-----|";
-
1638  }
-
1639  os << "\n";
-
1640  for (it; it != adj.end(); ++it)
-
1641  {
-
1642  os << "|N" << it->first->getId() << "|";
-
1643  auto it2 = it->second.begin();
-
1644  for (it2; it2 != it->second.end(); ++it2)
-
1645  {
-
1646  os << "N" << it2->first->getId() << ",E" << it2->second->getId() << "|";
-
1647  }
-
1648  os << "\n|--|";
-
1649  for (int i = 0; i < max_column; i++)
-
1650  {
-
1651  os << "-----|";
-
1652  }
-
1653  os << "\n";
-
1654  }
-
1655  }
-
1656  return os;
-
1657  }
+
1607  static unsigned int getMaxEdgesLoad(const PartitionMap<T> &partitionMap);
+
1608 
+
1616  template <typename T>
+
1617  static unsigned int getMinEdgesLoad(const PartitionMap<T> &partitionMap);
+
1618 
+
1626  template <typename T>
+
1627  static unsigned int getMaxNodesLoad(const PartitionMap<T> &partitionMap);
+
1628 
+
1636  template <typename T>
+
1637  static unsigned int getMinNodesLoad(const PartitionMap<T> &partitionMap);
+
1638 
+
1646  template <typename T>
+
1647  static unsigned int getNumberOfEdges(const PartitionMap<T> &partitionMap);
+
1648 
+
1656  template <typename T>
+
1657  static unsigned int getNumberOfNodes(const PartitionMap<T> &partitionMap);
1658 
-
1659 } // namespace CXXGRAPH
-
1660 #endif // __CXXGRAPH_H__
-
Definition: Graph.hpp:232
-
Definition: Graph.hpp:346
-
Definition: Graph.hpp:160
-
Definition: Graph.hpp:468
-
const std::vector< Node< T > > depth_first_search(const Node< T > &start) const
Function performs the depth first search algorithm over the graph.
Definition: Graph.hpp:1254
-
E_PartitionAlgorithm
Definition: Graph.hpp:490
-
@ GREEDY_VC
A Greedy Vertex-Cut Algorithm.
Definition: Graph.hpp:491
+
1666  template <typename T>
+
1667  static unsigned int getNumberOfReplicatedEdges(const PartitionMap<T> &partitionMap);
+
1668 
+
1676  template <typename T>
+
1677  static unsigned int getNumberOfReplicatedNodes(const PartitionMap<T> &partitionMap);
+
1678 
+
1679  template <typename T>
+ +
1681  {
+
1682  partitionId = 0;
+
1683  }
+
1684 
+
1685  template <typename T>
+
1686  Partition<T>::Partition(unsigned int partitionId) : Graph<T>()
+
1687  {
+
1688  this->partitionId = partitionId;
+
1689  }
+
1690 
+
1691  template <typename T>
+
1692  Partition<T>::Partition(const std::list<const Edge<T> *> &edgeSet) : Graph<T>(edgeSet)
+
1693  {
+
1694  partitionId = 0;
+
1695  }
+
1696 
+
1697  template <typename T>
+
1698  Partition<T>::Partition(unsigned int partitionId, const std::list<const Edge<T> *> &edgeSet) : Graph<T>(edgeSet)
+
1699  {
+
1700  this->partitionId = partitionId;
+
1701  }
+
1702 
+
1703  template <typename T>
+
1704  unsigned int Partition<T>::getPartitionId() const
+
1705  {
+
1706  return partitionId;
+
1707  }
+
1708 
+
1709  template <typename T>
+
1710  void Partition<T>::setPartitionId(unsigned int partitionId)
+
1711  {
+
1712  this->partitionId = partitionId;
+
1713  }
+
1714 
+
1715  template <typename T>
+
1716  PartitioningStats getPartitionStats(const PartitionMap<T> &partitionMap)
+
1717  {
+
1718  PartitioningStats result;
+
1719  result.numberOfPartitions = partitionMap.size();
+
1720  result.numberOfNodes = getNumberOfNodes(partitionMap);
+
1721  result.numberOfEdges = getNumberOfEdges(partitionMap);
+
1722  result.replicatedNodesCount = getNumberOfReplicatedNodes(partitionMap);
+
1723  result.replicatedEdgesCount = getNumberOfReplicatedEdges(partitionMap);
+
1724  result.maxEdgesLoad = getMaxEdgesLoad(partitionMap);
+
1725  result.minEdgesLoad = getMinEdgesLoad(partitionMap);
+
1726  result.maxNodesLoad = getMaxNodesLoad(partitionMap);
+
1727  result.minNodesLoad = getMinNodesLoad(partitionMap);
+
1728  result.edgesReplicationFactor = (double)result.replicatedEdgesCount / result.numberOfEdges;
+
1729  result.nodesReplicationFactor = (double)result.replicatedNodesCount / result.numberOfNodes;
+
1730  result.balanceEdgesFactor = (double)(result.maxEdgesLoad - result.minEdgesLoad) / (result.maxEdgesLoad);
+
1731  result.balanceNodesFactor = (double)(result.maxNodesLoad - result.minNodesLoad) / (result.maxNodesLoad);
+
1732  return result;
+
1733  }
+
1734 
+
1735  template <typename T>
+
1736  unsigned int getMaxEdgesLoad(const PartitionMap<T> &partitionMap)
+
1737  {
+
1738  unsigned int maxLoad = 0;
+
1739  for (auto it = partitionMap.begin(); it != partitionMap.end(); ++it)
+
1740  {
+
1741  if (it->second->getEdgeSet().size() > maxLoad)
+
1742  {
+
1743  maxLoad = it->second->getEdgeSet().size();
+
1744  }
+
1745  }
+
1746  return maxLoad;
+
1747  }
+
1748 
+
1749  template <typename T>
+
1750  unsigned int getMinEdgesLoad(const PartitionMap<T> &partitionMap)
+
1751  {
+
1752  unsigned int minLoad = std::numeric_limits<unsigned int>::max();
+
1753  for (auto it = partitionMap.begin(); it != partitionMap.end(); ++it)
+
1754  {
+
1755  if (it->second->getEdgeSet().size() < minLoad)
+
1756  {
+
1757  minLoad = it->second->getEdgeSet().size();
+
1758  }
+
1759  }
+
1760  return minLoad;
+
1761  }
+
1762 
+
1763  template <typename T>
+
1764  unsigned int getMaxNodesLoad(const PartitionMap<T> &partitionMap)
+
1765  {
+
1766  unsigned int maxLoad = 0;
+
1767  for (auto it = partitionMap.begin(); it != partitionMap.end(); ++it)
+
1768  {
+
1769  if (it->second->getNodeSet().size() > maxLoad)
+
1770  {
+
1771  maxLoad = it->second->getNodeSet().size();
+
1772  }
+
1773  }
+
1774  return maxLoad;
+
1775  }
+
1776 
+
1777  template <typename T>
+
1778  unsigned int getMinNodesLoad(const PartitionMap<T> &partitionMap)
+
1779  {
+
1780  unsigned int minLoad = std::numeric_limits<unsigned int>::max();
+
1781  for (auto it = partitionMap.begin(); it != partitionMap.end(); ++it)
+
1782  {
+
1783  if (it->second->getNodeSet().size() < minLoad)
+
1784  {
+
1785  minLoad = it->second->getNodeSet().size();
+
1786  }
+
1787  }
+
1788  return minLoad;
+
1789  }
+
1790 
+
1791  template <typename T>
+
1792  unsigned int getNumberOfEdges(const PartitionMap<T> &partitionMap)
+
1793  {
+
1794  unsigned int numberOfEdges = 0;
+
1795  std::list<const Edge<T> *> edgeSet;
+
1796 
+
1797  for (auto it = partitionMap.begin(); it != partitionMap.end(); ++it)
+
1798  {
+
1799  const std::list<const Edge<T> *> partitionEdgeSet = it->second->getEdgeSet();
+
1800  for (auto it2 = partitionEdgeSet.begin(); it2 != partitionEdgeSet.end(); ++it2)
+
1801  {
+
1802  if (std::find_if(edgeSet.begin(), edgeSet.end(), [it2](const Edge<T> *edge)
+
1803  { return (*(*it2) == *edge); }) == edgeSet.end())
+
1804  {
+
1805  edgeSet.push_back(*it2);
+
1806  }
+
1807  }
+
1808  }
+
1809 
+
1810  return edgeSet.size();
+
1811  }
+
1812 
+
1813  template <typename T>
+
1814  unsigned int getNumberOfNodes(const PartitionMap<T> &partitionMap)
+
1815  {
+
1816 
+
1817  unsigned int numberOfNodes = 0;
+
1818  std::list<const Node<T> *> nodeSet;
+
1819 
+
1820  for (auto it = partitionMap.begin(); it != partitionMap.end(); ++it)
+
1821  {
+
1822  const std::list<const Node<T> *> partitionNodeSet = it->second->getNodeSet();
+
1823  for (auto it2 = partitionNodeSet.begin(); it2 != partitionNodeSet.end(); ++it2)
+
1824  {
+
1825  if (std::find_if(nodeSet.begin(), nodeSet.end(), [it2](const Node<T> *node)
+
1826  { return (*(*it2) == *node); }) == nodeSet.end())
+
1827  {
+
1828  nodeSet.push_back(*it2);
+
1829  }
+
1830  }
+
1831  }
+
1832 
+
1833  return nodeSet.size();
+
1834  }
+
1835 
+
1836  template <typename T>
+
1837  unsigned int getNumberOfReplicatedEdges(const PartitionMap<T> &partitionMap)
+
1838  {
+
1839 
+
1840  unsigned int numberOfEdges = 0;
+
1841  for (auto it = partitionMap.begin(); it != partitionMap.end(); ++it)
+
1842  {
+
1843  numberOfEdges += it->second->getEdgeSet().size();
+
1844  }
+
1845  return numberOfEdges;
+
1846  }
+
1847 
+
1848  template <typename T>
+
1849  unsigned int getNumberOfReplicatedNodes(const PartitionMap<T> &partitionMap)
+
1850  {
+
1851  unsigned int numberOfNodes = 0;
+
1852  for (auto it = partitionMap.begin(); it != partitionMap.end(); ++it)
+
1853  {
+
1854  numberOfNodes += it->second->getNodeSet().size();
+
1855  }
+
1856  return numberOfNodes;
+
1857  }
+
1858 
+
1859  //ostream overload
+
1860  template <typename T>
+
1861  std::ostream &operator<<(std::ostream &os, const Node<T> &node)
+
1862  {
+
1863  os << "Node: {\n"
+
1864  << " Id:\t" << node.id << "\n Data:\t" << node.data << "\n}";
+
1865  return os;
+
1866  }
+
1867 
+
1868  template <typename T>
+
1869  std::ostream &operator<<(std::ostream &os, const Edge<T> &edge)
+
1870  {
+
1871  os << "((Node: " << edge.nodePair.first->getId() << ")) ?----- |Edge: " << edge.id << "|-----? ((Node: " << edge.nodePair.second->getId() << "))";
+
1872  return os;
+
1873  }
+
1874 
+
1875  template <typename T>
+
1876  std::ostream &operator<<(std::ostream &os, const DirectedEdge<T> &edge)
+
1877  {
+
1878  os << "((Node: " << edge.getFrom().getId() << ")) +----- |Edge: #" << edge.getId() << "|-----> ((Node: " << edge.getTo().getId() << "))";
+
1879  return os;
+
1880  }
+
1881 
+
1882  template <typename T>
+
1883  std::ostream &operator<<(std::ostream &os, const UndirectedEdge<T> &edge)
+
1884  {
+
1885  os << "((Node: " << edge.getNode1().getId() << ")) <----- |Edge: #" << edge.getId() << "|-----> ((Node: " << edge.getNode2().getId() << "))";
+
1886  return os;
+
1887  }
+
1888 
+
1889  template <typename T>
+
1890  std::ostream &operator<<(std::ostream &os, const DirectedWeightedEdge<T> &edge)
+
1891  {
+
1892  os << "((Node: " << edge.getFrom().getId() << ")) +----- |Edge: #" << edge.getId() << " W:" << edge.getWeight() << "|-----> ((Node: " << edge.getTo().getId() << "))";
+
1893  return os;
+
1894  }
+
1895 
+
1896  template <typename T>
+
1897  std::ostream &operator<<(std::ostream &os, const UndirectedWeightedEdge<T> &edge)
+
1898  {
+
1899  os << "((Node: " << edge.getNode1().getId() << ")) <----- |Edge: #" << edge.getId() << " W:" << edge.getWeight() << "|-----> ((Node: " << edge.getNode2().getId() << "))";
+
1900  return os;
+
1901  }
+
1902 
+
1903  template <typename T>
+
1904  std::ostream &operator<<(std::ostream &os, const AdjacencyMatrix<T> &adj)
+
1905  {
+
1906  os << "Adjacency Matrix:\n";
+
1907  auto it = adj.begin();
+
1908  unsigned long max_column = 0;
+
1909  for (it; it != adj.end(); ++it)
+
1910  {
+
1911  if (it->second.size() > max_column)
+
1912  {
+
1913  max_column = it->second.size();
+
1914  }
+
1915  }
+
1916  if (max_column == 0)
+
1917  {
+
1918  os << "ERROR in Print\n";
+
1919  return os;
+
1920  }
+
1921  else
+
1922  {
+
1923  it = adj.begin();
+
1924  os << "|--|";
+
1925  for (int i = 0; i < max_column; i++)
+
1926  {
+
1927  os << "-----|";
+
1928  }
+
1929  os << "\n";
+
1930  for (it; it != adj.end(); ++it)
+
1931  {
+
1932  os << "|N" << it->first->getId() << "|";
+
1933  auto it2 = it->second.begin();
+
1934  for (it2; it2 != it->second.end(); ++it2)
+
1935  {
+
1936  os << "N" << it2->first->getId() << ",E" << it2->second->getId() << "|";
+
1937  }
+
1938  os << "\n|--|";
+
1939  for (int i = 0; i < max_column; i++)
+
1940  {
+
1941  os << "-----|";
+
1942  }
+
1943  os << "\n";
+
1944  }
+
1945  }
+
1946  return os;
+
1947  }
+
1948 
+
1949 } // namespace CXXGRAPH
+
1950 #endif // __CXXGRAPH_H__
+
Definition: Graph.hpp:277
+
Definition: Graph.hpp:391
+
Definition: Graph.hpp:205
+
Definition: Graph.hpp:513
+
const std::vector< Node< T > > depth_first_search(const Node< T > &start) const
Function performs the depth first search algorithm over the graph.
Definition: Graph.hpp:1301
+
E_PartitionAlgorithm
Specify the Partition Algorithm.
Definition: Graph.hpp:536
+
@ GREEDY_VC
A Greedy Vertex-Cut Algorithm.
Definition: Graph.hpp:537
+
enum CXXGRAPH::Graph::E_PartitionAlgorithm PartitionAlgorithm
Specify the Partition Algorithm.
enum CXXGRAPH::Graph::E_InputOutputFormat InputOutputFormat
Specify the Input/Output format of the Graph for Import/Export functions.
-
bool isCyclicDirectedGraphBFS() const
This function uses BFS to check for cycle in the graph. Pay Attention, this function work only with d...
Definition: Graph.hpp:1376
-
int writeToFile(InputOutputFormat format=InputOutputFormat::STANDARD_CSV, const std::string &workingDir=".", const std::string &OFileName="graph", bool compress=false, bool writeNodeFeat=false, bool writeEdgeWeight=false) const
This function write the graph in an output file.
Definition: Graph.hpp:1461
-
bool isDirectedGraph() const
This function checks if a graph is directed.
Definition: Graph.hpp:1445
-
const DijkstraResult dijkstra(const Node< T > &source, const Node< T > &target) const
Function runs the dijkstra algorithm for some source node and target node in the graph and returns th...
Definition: Graph.hpp:1104
-
bool isCyclicDirectedGraphDFS() const
This function uses DFS to check for cycle in the graph. Pay Attention, this function work only with d...
Definition: Graph.hpp:1286
-
int readFromFile(InputOutputFormat format=InputOutputFormat::STANDARD_CSV, const std::string &workingDir=".", const std::string &OFileName="graph", bool compress=false, bool readNodeFeat=false, bool readEdgeWeight=false)
This function write the graph in an output file.
Definition: Graph.hpp:1479
-
std::map< unsigned int, Partition< T > * > partitionGraph(PartitionAlgorithm algorithm, unsigned int numberOfPartitions) const
This function partition a graph in a set of partitions.
Definition: Graph.hpp:1497
-
const std::vector< Node< T > > breadth_first_search(const Node< T > &start) const
Function performs the breadth first search algorithm over the graph.
Definition: Graph.hpp:1214
-
E_InputOutputFormat
Specify the Input/Output format of the Graph for Import/Export functions.
Definition: Graph.hpp:482
-
@ STANDARD_CSV
A standard csv format.
Definition: Graph.hpp:483
-
@ STANDARD_TSV
A standard tsv format.
Definition: Graph.hpp:484
-
Definition: Graph.hpp:74
-
Definition: Graph.hpp:1518
-
Definition: Graph.hpp:289
-
Definition: Graph.hpp:406
-
Definition: Graph.hpp:122
-
Definition: Graph.hpp:66
+
bool isCyclicDirectedGraphBFS() const
This function uses BFS to check for cycle in the graph. Pay Attention, this function work only with d...
Definition: Graph.hpp:1423
+
int writeToFile(InputOutputFormat format=InputOutputFormat::STANDARD_CSV, const std::string &workingDir=".", const std::string &OFileName="graph", bool compress=false, bool writeNodeFeat=false, bool writeEdgeWeight=false) const
This function write the graph in an output file.
Definition: Graph.hpp:1508
+
bool isDirectedGraph() const
This function checks if a graph is directed.
Definition: Graph.hpp:1492
+
const DijkstraResult dijkstra(const Node< T > &source, const Node< T > &target) const
Function runs the dijkstra algorithm for some source node and target node in the graph and returns th...
Definition: Graph.hpp:1151
+
bool isCyclicDirectedGraphDFS() const
This function uses DFS to check for cycle in the graph. Pay Attention, this function work only with d...
Definition: Graph.hpp:1333
+
PartitionMap< T > partitionGraph(PartitionAlgorithm algorithm, unsigned int numberOfPartitions) const
This function partition a graph in a set of partitions.
Definition: Graph.hpp:1544
+
int readFromFile(InputOutputFormat format=InputOutputFormat::STANDARD_CSV, const std::string &workingDir=".", const std::string &OFileName="graph", bool compress=false, bool readNodeFeat=false, bool readEdgeWeight=false)
This function write the graph in an output file.
Definition: Graph.hpp:1526
+
const AdjacencyMatrix< T > getAdjMatrix() const
This function generate a list of adjacency matrix with every element of the matrix contain the node w...
Definition: Graph.hpp:1124
+
const std::vector< Node< T > > breadth_first_search(const Node< T > &start) const
Function performs the breadth first search algorithm over the graph.
Definition: Graph.hpp:1261
+
E_InputOutputFormat
Specify the Input/Output format of the Graph for Import/Export functions.
Definition: Graph.hpp:527
+
@ STANDARD_CSV
A standard csv format.
Definition: Graph.hpp:528
+
@ STANDARD_TSV
A standard tsv format.
Definition: Graph.hpp:529
+
Definition: Graph.hpp:119
+
Definition: Graph.hpp:1565
+
void setPartitionId(unsigned int partitionId)
Set the Partition ID.
Definition: Graph.hpp:1710
+
unsigned int getPartitionId() const
Get the Partition ID.
Definition: Graph.hpp:1704
+
Definition: Graph.hpp:334
+
Definition: Graph.hpp:451
+
Definition: Graph.hpp:167
+
Struct that contains the information about Dijsktra's Algorithm results.
Definition: Graph.hpp:50
+
Struct that contains the information about the partitioning statistics.
Definition: Graph.hpp:59