Skip to content

Commit 4b1adcb

Browse files
authored
Introduced functions to het Partitions Stats
Fix #29 Implement statistic results of the partition
1 parent 4cfe2b6 commit 4b1adcb

File tree

2 files changed

+261
-26
lines changed

2 files changed

+261
-26
lines changed

include/Graph.hpp

+207-26
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include <string>
1515
#include <functional>
1616
#include <fstream>
17+
#include <limits.h>
1718

1819
namespace CXXGRAPH
1920
{
@@ -53,23 +54,43 @@ namespace CXXGRAPH
5354
};
5455
typedef DijkstraResult_struct DijkstraResult;
5556

56-
/// Struct that contains the information about the partioning statistics
57-
struct PartioningStats_struct
58-
{
59-
unsigned int numberOfPartions; // The number of Partitions
60-
unsigned int numberOfVertices; // The number of Vertices
61-
unsigned int replicatedVerticesCount; // The number of Vertices that are replicated
62-
unsigned int numberOfEdges; // The number of edges
63-
unsigned int replicatedEdgesCount; // The number of edges that are replicated
64-
unsigned int maxLoad; // Maximum load of the partitions
65-
unsigned int minLoad; // Minimun load of the partitions
66-
double balanceFactor; // The balance factor of the partitions (maxLoad - minLoad) / (maxLoad + minLoad), 0 is the optimal partitioning
67-
double verticesReplicationFactor; // The replication factor of the vertices (replicatedVerticesCount / numberOfVertices), 1 is the optimal partitioning
68-
double edgesReplicationFactor; // The replication factor of the edges (replicatedEdgesCount / numberOfEdges), 1 is the optimal partitioning
69-
70-
friend std::ostream &operator<<(std::ostream &os, const PartioningStats_struct &partitionStats);
57+
/// Struct that contains the information about the partitioning statistics
58+
struct PartitioningStats_struct
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+
}
7192
};
72-
typedef PartioningStats_struct PartioningStats;
93+
typedef PartitioningStats_struct PartitioningStats;
7394

7495
template <typename T>
7596
using AdjacencyMatrix = std::map<const Node<T> *, std::vector<std::pair<const Node<T> *, const Edge<T> *>>>;
@@ -91,8 +112,6 @@ namespace CXXGRAPH
91112
template <typename T>
92113
std::ostream &operator<<(std::ostream &o, const AdjacencyMatrix<T> &adj);
93114
template <typename T>
94-
std::ostream &operator<<(std::ostream &o, const PartioningStats &partitionStats);
95-
template <typename T>
96115
using PartitionMap = std::map<unsigned int, Partition<T> *>;
97116

98117
template <typename T>
@@ -1089,7 +1108,7 @@ namespace CXXGRAPH
10891108
unsigned int numberOfPartitions = partitionMap.size();
10901109
if (index == numberOfPartitions)
10911110
{
1092-
//ERROR partion map of zero element
1111+
//ERROR partition map of zero element
10931112
return;
10941113
}
10951114
auto edgeSet = getEdgeSet();
@@ -1557,6 +1576,24 @@ namespace CXXGRAPH
15571576
private:
15581577
unsigned int partitionId;
15591578
};
1579+
template <typename T>
1580+
static PartitioningStats getPartitionStats(const PartitionMap<T> &partitionMap);
1581+
template <typename T>
1582+
static unsigned int getMaxEdgesLoad(const PartitionMap<T> &partitionMap);
1583+
template <typename T>
1584+
static unsigned int getMinEdgesLoad(const PartitionMap<T> &partitionMap);
1585+
template <typename T>
1586+
static unsigned int getMaxNodesLoad(const PartitionMap<T> &partitionMap);
1587+
template <typename T>
1588+
static unsigned int getMinNodesLoad(const PartitionMap<T> &partitionMap);
1589+
template <typename T>
1590+
static unsigned int getNumberOfEdges(const PartitionMap<T> &partitionMap);
1591+
template <typename T>
1592+
static unsigned int getNumberOfNodes(const PartitionMap<T> &partitionMap);
1593+
template <typename T>
1594+
static unsigned int getNumberOfReplicatedEdges(const PartitionMap<T> &partitionMap);
1595+
template <typename T>
1596+
static unsigned int getNumberOfReplicatedNodes(const PartitionMap<T> &partitionMap);
15601597

15611598
template <typename T>
15621599
Partition<T>::Partition() : Graph<T>()
@@ -1594,6 +1631,150 @@ namespace CXXGRAPH
15941631
this->partitionId = partitionId;
15951632
}
15961633

1634+
template <typename T>
1635+
PartitioningStats getPartitionStats(const PartitionMap<T> &partitionMap)
1636+
{
1637+
PartitioningStats result;
1638+
result.numberOfPartitions = partitionMap.size();
1639+
result.numberOfNodes = getNumberOfNodes(partitionMap);
1640+
result.numberOfEdges = getNumberOfEdges(partitionMap);
1641+
result.replicatedNodesCount = getNumberOfReplicatedNodes(partitionMap);
1642+
result.replicatedEdgesCount = getNumberOfReplicatedEdges(partitionMap);
1643+
result.maxEdgesLoad = getMaxEdgesLoad(partitionMap);
1644+
result.minEdgesLoad = getMinEdgesLoad(partitionMap);
1645+
result.maxNodesLoad = getMaxNodesLoad(partitionMap);
1646+
result.minNodesLoad = getMinNodesLoad(partitionMap);
1647+
result.edgesReplicationFactor = (double)result.replicatedEdgesCount / result.numberOfEdges;
1648+
result.nodesReplicationFactor = (double)result.replicatedNodesCount / result.numberOfNodes;
1649+
result.balanceEdgesFactor = (double)(result.maxEdgesLoad - result.minEdgesLoad) / (result.maxEdgesLoad);
1650+
result.balanceNodesFactor = (double)(result.maxNodesLoad - result.minNodesLoad) / (result.maxNodesLoad);
1651+
return result;
1652+
}
1653+
1654+
template <typename T>
1655+
unsigned int getMaxEdgesLoad(const PartitionMap<T> &partitionMap)
1656+
{
1657+
unsigned int maxLoad = 0;
1658+
for (auto it = partitionMap.begin(); it != partitionMap.end(); ++it)
1659+
{
1660+
if (it->second->getEdgeSet().size() > maxLoad)
1661+
{
1662+
maxLoad = it->second->getEdgeSet().size();
1663+
}
1664+
}
1665+
return maxLoad;
1666+
}
1667+
1668+
template <typename T>
1669+
unsigned int getMinEdgesLoad(const PartitionMap<T> &partitionMap)
1670+
{
1671+
unsigned int minLoad = std::numeric_limits<unsigned int>::max();
1672+
for (auto it = partitionMap.begin(); it != partitionMap.end(); ++it)
1673+
{
1674+
if (it->second->getEdgeSet().size() < minLoad)
1675+
{
1676+
minLoad = it->second->getEdgeSet().size();
1677+
}
1678+
}
1679+
return minLoad;
1680+
}
1681+
1682+
template <typename T>
1683+
unsigned int getMaxNodesLoad(const PartitionMap<T> &partitionMap)
1684+
{
1685+
unsigned int maxLoad = 0;
1686+
for (auto it = partitionMap.begin(); it != partitionMap.end(); ++it)
1687+
{
1688+
if (it->second->getNodeSet().size() > maxLoad)
1689+
{
1690+
maxLoad = it->second->getNodeSet().size();
1691+
}
1692+
}
1693+
return maxLoad;
1694+
}
1695+
1696+
template <typename T>
1697+
unsigned int getMinNodesLoad(const PartitionMap<T> &partitionMap)
1698+
{
1699+
unsigned int minLoad = std::numeric_limits<unsigned int>::max();
1700+
for (auto it = partitionMap.begin(); it != partitionMap.end(); ++it)
1701+
{
1702+
if (it->second->getNodeSet().size() < minLoad)
1703+
{
1704+
minLoad = it->second->getNodeSet().size();
1705+
}
1706+
}
1707+
return minLoad;
1708+
}
1709+
1710+
template <typename T>
1711+
unsigned int getNumberOfEdges(const PartitionMap<T> &partitionMap)
1712+
{
1713+
unsigned int numberOfEdges = 0;
1714+
std::list<const Edge<T> *> edgeSet;
1715+
1716+
for (auto it = partitionMap.begin(); it != partitionMap.end(); ++it)
1717+
{
1718+
const std::list<const Edge<T> *> partitionEdgeSet = it->second->getEdgeSet();
1719+
for (auto it2 = partitionEdgeSet.begin(); it2 != partitionEdgeSet.end(); ++it2)
1720+
{
1721+
if (std::find_if(edgeSet.begin(), edgeSet.end(), [it2](const Edge<T> *edge)
1722+
{ return (*(*it2) == *edge); }) == edgeSet.end())
1723+
{
1724+
edgeSet.push_back(*it2);
1725+
}
1726+
}
1727+
}
1728+
1729+
return edgeSet.size();
1730+
}
1731+
1732+
template <typename T>
1733+
unsigned int getNumberOfNodes(const PartitionMap<T> &partitionMap)
1734+
{
1735+
1736+
unsigned int numberOfNodes = 0;
1737+
std::list<const Node<T> *> nodeSet;
1738+
1739+
for (auto it = partitionMap.begin(); it != partitionMap.end(); ++it)
1740+
{
1741+
const std::list<const Node<T> *> partitionNodeSet = it->second->getNodeSet();
1742+
for (auto it2 = partitionNodeSet.begin(); it2 != partitionNodeSet.end(); ++it2)
1743+
{
1744+
if (std::find_if(nodeSet.begin(), nodeSet.end(), [it2](const Node<T> *node)
1745+
{ return (*(*it2) == *node); }) == nodeSet.end())
1746+
{
1747+
nodeSet.push_back(*it2);
1748+
}
1749+
}
1750+
}
1751+
1752+
return nodeSet.size();
1753+
}
1754+
1755+
template <typename T>
1756+
unsigned int getNumberOfReplicatedEdges(const PartitionMap<T> &partitionMap)
1757+
{
1758+
1759+
unsigned int numberOfEdges = 0;
1760+
for (auto it = partitionMap.begin(); it != partitionMap.end(); ++it)
1761+
{
1762+
numberOfEdges += it->second->getEdgeSet().size();
1763+
}
1764+
return numberOfEdges;
1765+
}
1766+
1767+
template <typename T>
1768+
unsigned int getNumberOfReplicatedNodes(const PartitionMap<T> &partitionMap)
1769+
{
1770+
unsigned int numberOfNodes = 0;
1771+
for (auto it = partitionMap.begin(); it != partitionMap.end(); ++it)
1772+
{
1773+
numberOfNodes += it->second->getNodeSet().size();
1774+
}
1775+
return numberOfNodes;
1776+
}
1777+
15971778
//ostream overload
15981779
template <typename T>
15991780
std::ostream &operator<<(std::ostream &os, const Node<T> &node)
@@ -1683,23 +1864,23 @@ namespace CXXGRAPH
16831864
}
16841865
return os;
16851866
}
1686-
1867+
/*
16871868
template <typename T>
1688-
std::ostream &operator<<(std::ostream &os, const PartioningStats &partitionStats)
1869+
std::ostream &operator<<(std::ostream &os, const PartitioningStats_struct &partitionStats)
16891870
{
16901871
os << "Partitioning Stats:\n";
1691-
os << "\tNumber of Partitions:" << partitionStats.numberOfPartions << "\n";
1692-
os << "\tNumber of Vertices: " << partitionStats.numberOfVertices << "\n";
1872+
os << "\tNumber of Partitions:" << partitionStats.numberOfPartitions << "\n";
1873+
os << "\tNumber of Nodes: " << partitionStats.numberOfNodes << "\n";
16931874
os << "\tNumber of Edges: " << partitionStats.numberOfEdges << "\n";
1694-
os << "\tNumber of Vertices Replica: " << partitionStats.replicatedVerticesCount << "\n";
1875+
os << "\tNumber of Nodes Replica: " << partitionStats.replicatedNodesCount << "\n";
16951876
os << "\tNumber of Edges Replica: " << partitionStats.replicatedEdgesCount << "\n";
1696-
os << "\tVertices Replication Factor: " << partitionStats.verticesReplicationFactor << "\n";
1877+
os << "\tNodes Replication Factor: " << partitionStats.nodesReplicationFactor << "\n";
16971878
os << "\tEdges Replication Factor: " << partitionStats.edgesReplicationFactor << "\n";
16981879
os << "\tMax Load: " << partitionStats.maxLoad << "\n";
16991880
os << "\tMin Load: " << partitionStats.minLoad << "\n";
17001881
os << "\tBalance Factor: " << partitionStats.balanceFactor << "\n";
17011882
return os;
17021883
}
1703-
1884+
*/
17041885
} // namespace CXXGRAPH
17051886
#endif // __CXXGRAPH_H__

test/PartitionTest.cpp

+54
Original file line numberDiff line numberDiff line change
@@ -51,3 +51,57 @@ TEST(PartitonTest, test_1)
5151
ASSERT_EQ(partitionMap.at(i)->getPartitionId(), i);
5252
}
5353
}
54+
55+
TEST(PartitonTest, test_2)
56+
{
57+
CXXGRAPH::Node<int> node1(1, 1);
58+
CXXGRAPH::Node<int> node2(2, 2);
59+
CXXGRAPH::Node<int> node3(3, 3);
60+
CXXGRAPH::Node<int> node4(4, 4);
61+
CXXGRAPH::Node<int> node5(5, 5);
62+
CXXGRAPH::Node<int> node6(6, 6);
63+
CXXGRAPH::Node<int> node7(7, 7);
64+
CXXGRAPH::Node<int> node8(8, 8);
65+
std::pair<const CXXGRAPH::Node<int> *, const CXXGRAPH::Node<int> *> pairNode(&node1, &node2);
66+
CXXGRAPH::DirectedWeightedEdge<int> edge1(1, pairNode, 1);
67+
CXXGRAPH::DirectedWeightedEdge<int> edge2(2, node2, node3, 1);
68+
CXXGRAPH::UndirectedWeightedEdge<int> edge3(3, node1, node3, 1);
69+
CXXGRAPH::UndirectedWeightedEdge<int> edge4(4, node4, node5, 1);
70+
CXXGRAPH::UndirectedWeightedEdge<int> edge5(5, node4, node6, 1);
71+
CXXGRAPH::UndirectedWeightedEdge<int> edge6(6, node3, node4, 1);
72+
CXXGRAPH::UndirectedWeightedEdge<int> edge7(7, node2, node8, 1);
73+
CXXGRAPH::UndirectedWeightedEdge<int> edge8(8, node7, node8, 1);
74+
CXXGRAPH::UndirectedWeightedEdge<int> edge9(9, node1, node6, 1);
75+
CXXGRAPH::UndirectedWeightedEdge<int> edge10(10, node3, node5, 1);
76+
CXXGRAPH::UndirectedWeightedEdge<int> edge11(11, node3, node6, 1);
77+
CXXGRAPH::UndirectedWeightedEdge<int> edge12(12, node4, node8, 1);
78+
std::list<const CXXGRAPH::Edge<int> *> edgeSet;
79+
edgeSet.push_back(&edge1);
80+
edgeSet.push_back(&edge2);
81+
edgeSet.push_back(&edge3);
82+
edgeSet.push_back(&edge4);
83+
edgeSet.push_back(&edge5);
84+
edgeSet.push_back(&edge6);
85+
edgeSet.push_back(&edge7);
86+
edgeSet.push_back(&edge8);
87+
edgeSet.push_back(&edge9);
88+
edgeSet.push_back(&edge10);
89+
edgeSet.push_back(&edge11);
90+
edgeSet.push_back(&edge12);
91+
CXXGRAPH::Graph<int> graph(edgeSet);
92+
ASSERT_EQ(graph.getEdgeSet().size(), 12);
93+
auto partitionMap = graph.partitionGraph(CXXGRAPH::Graph<int>::PartitionAlgorithm::GREEDY_VC, 4);
94+
unsigned int totalEdgeInPartition = 0;
95+
for (auto elem : partitionMap)
96+
{
97+
totalEdgeInPartition += elem.second->getEdgeSet().size();
98+
}
99+
ASSERT_EQ(totalEdgeInPartition, 12);
100+
for (int i = 0; i < 4; ++i)
101+
{
102+
ASSERT_EQ(partitionMap.at(i)->getPartitionId(), i);
103+
}
104+
105+
CXXGRAPH::PartitioningStats partitioningStats = CXXGRAPH::getPartitionStats(partitionMap);
106+
std::cout << partitioningStats << std::endl;
107+
}

0 commit comments

Comments
 (0)