Skip to content

Commit 90a9973

Browse files
sbaldusbaldu
and
sbaldu
authored
Feature getters for set of neighbors (#318)
* Remove static_cast of 0 to template type T in best_first_search * Change all the raw pointers in the library to smart pointers * Rewrite tests to use smart pointers * Finish converting tests to smart pointers * Add setter for nodes in Edge nodePair * Fix addition of edges and construction of adjacency matrix * Add overloads of algorithms which take raw pointers to mantain interface * Fix typos in tests * Change dynamic_casts into dynamic_pointer_casts * Decrease the number of random edges and nodes in RW and partition tests * Add out/inOutEdges convenience methods for Graph * Add tests for the out/inOutEdges methods * Add overload of equality operators and hash functions for pointers of nodes * Implement new hash functions for pointers of nodes and edges * Increase number of nodes and edges in partition and RW tests * Fix typo * Use shared pointers in random node/edge generators * Convert pointers in TransitiveReductionTest.cpp * Add overload of addEdge for raw pointers * Fix typo * Fix edge insertion in FloydWarshall benchmark * Fix typo in benchmark * Remove all the calls to new in the tests * Fix typo in benchmark FloydWarshall Fix typo in benchmark FloydWarshall * Conversion of example codes * Formatting * Add test for overloads of out/inOutEdges * Change name of out/inOutEdges methods to out/inOutNeighbors --------- Co-authored-by: sbaldu <[email protected]>
1 parent 4569d22 commit 90a9973

File tree

2 files changed

+357
-56
lines changed

2 files changed

+357
-56
lines changed

include/Graph/Graph.hpp

+131-21
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
#include "Partitioning/Utility/Globals.hpp"
6161
#include "Utility/ConstString.hpp"
6262
#include "Utility/ConstValue.hpp"
63+
#include "Utility/PointerHash.hpp"
6364
#include "Utility/Reader.hpp"
6465
#include "Utility/ThreadSafe.hpp"
6566
#include "Utility/Typedef.hpp"
@@ -209,7 +210,8 @@ class Graph {
209210
* @returns a list of Nodes of the graph
210211
*
211212
*/
212-
virtual const std::unordered_set<shared<const Node<T>>, nodeHash<T>> getNodeSet() const;
213+
virtual const std::unordered_set<shared<const Node<T>>, nodeHash<T>>
214+
getNodeSet() const;
213215
/**
214216
* \brief
215217
* Function that sets the data contained in a node
@@ -244,6 +246,47 @@ class Graph {
244246
* corrispondent to the link Note: No Thread Safe
245247
*/
246248
virtual const std::shared_ptr<AdjacencyMatrix<T>> getAdjMatrix() const;
249+
/**
250+
* \brief This function generates a set of nodes linked to the provided node in a
251+
* directed graph
252+
* Note: No Thread Safe
253+
*
254+
* @param Pointer to the node
255+
*
256+
*/
257+
virtual const std::unordered_set<shared<const Node<T>>, nodeHash<T>> outNeighbors(
258+
const Node<T> *node) const;
259+
/**
260+
* \brief This function generates a set of nodes linked to the provided node in a
261+
* directed graph
262+
* Note: No Thread Safe
263+
*
264+
* @param Pointer to the node
265+
*
266+
*/
267+
virtual const std::unordered_set<shared<const Node<T>>, nodeHash<T>> outNeighbors(
268+
shared<const Node<T>> node) const;
269+
/**
270+
* \brief This function generates a set of nodes linked to the provided node in
271+
* any graph
272+
* Note: No Thread Safe
273+
*
274+
* @param Pointer to the node
275+
*
276+
*/
277+
virtual const std::unordered_set<shared<const Node<T>>, nodeHash<T>>
278+
inOutNeighbors(const Node<T> *node) const;
279+
/**
280+
* \brief
281+
* \brief This function generates a set of nodes linked to the provided node in
282+
* any graph
283+
* Note: No Thread Safe
284+
*
285+
* @param Pointer to the node
286+
*
287+
*/
288+
virtual const std::unordered_set<shared<const Node<T>>, nodeHash<T>>
289+
inOutNeighbors(shared<const Node<T>> node) const;
247290
/**
248291
* @brief This function finds the subset of given a nodeId
249292
* Subset is stored in a map where keys are the hash-id of the node & values
@@ -261,7 +304,8 @@ class Graph {
261304
* @brief This function finds the subset of given a nodeId
262305
* Subset is stored in a map where keys are the hash-id of the node & values
263306
* is the subset.
264-
* @param shared pointer to subset query subset, we want to find target in this subset
307+
* @param shared pointer to subset query subset, we want to find target in
308+
* this subset
265309
* @param elem elem that we wish to find in the subset
266310
*
267311
* @return parent node of elem
@@ -744,7 +788,8 @@ bool Graph<T>::findEdge(shared<const Node<T>> v1, shared<const Node<T>> v2,
744788
}
745789

746790
template <typename T>
747-
const std::unordered_set<shared<const Node<T>>, nodeHash<T>> Graph<T>::getNodeSet() const {
791+
const std::unordered_set<shared<const Node<T>>, nodeHash<T>>
792+
Graph<T>::getNodeSet() const {
748793
std::unordered_set<shared<const Node<T>>, nodeHash<T>> nodeSet;
749794
for (const auto &edgeSetIt : edgeSet) {
750795
nodeSet.insert(edgeSetIt->getNodePair().first);
@@ -863,11 +908,11 @@ int Graph<T>::writeToDot(const std::string &workingDir,
863908
}
864909
if (edgePtr->isWeighted().has_value() && edgePtr->isWeighted().value()) {
865910
// Weights in dot files must be integers
866-
edgeLine +=
867-
" [weight=" +
868-
std::to_string(static_cast<int>(
869-
std::dynamic_pointer_cast<const Weighted>(edgePtr)->getWeight())) +
870-
']';
911+
edgeLine += " [weight=" +
912+
std::to_string(static_cast<int>(
913+
std::dynamic_pointer_cast<const Weighted>(edgePtr)
914+
->getWeight())) +
915+
']';
871916
}
872917
edgeLine += ";\n";
873918
ofileGraph << edgeLine;
@@ -917,7 +962,8 @@ void Graph<T>::writeGraphToStream(std::ostream &oGraph, std::ostream &oNodeFeat,
917962
oEdgeWeight
918963
<< edge->getId() << sep
919964
<< (edge->isWeighted().has_value() && edge->isWeighted().value()
920-
? (std::dynamic_pointer_cast<const Weighted>(edge))->getWeight()
965+
? (std::dynamic_pointer_cast<const Weighted>(edge))
966+
->getWeight()
921967
: 0.0)
922968
<< sep
923969
<< (edge->isWeighted().has_value() && edge->isWeighted().value() ? 1
@@ -1179,7 +1225,8 @@ template <typename T>
11791225
unsigned long long Graph<T>::setFind(
11801226
std::unordered_map<unsigned long long, Subset> *subsets,
11811227
const unsigned long long nodeId) const {
1182-
auto subsets_ptr = make_shared<std::unordered_map<unsigned long long, Subset>>(*subsets);
1228+
auto subsets_ptr =
1229+
make_shared<std::unordered_map<unsigned long long, Subset>>(*subsets);
11831230
// find root and make root as parent of i
11841231
// (path compression)
11851232
if ((*subsets)[nodeId].parent != nodeId) {
@@ -1205,18 +1252,21 @@ unsigned long long Graph<T>::setFind(
12051252
}
12061253

12071254
template <typename T>
1208-
void Graph<T>::setUnion(
1209-
std::unordered_map<unsigned long long, Subset> *subsets,
1210-
const unsigned long long elem1, const unsigned long long elem2) const {
1211-
/* auto subsets_ptr = make_shared<std::unordered_map<unsigned long long, Subset>>(*subsets); */
1255+
void Graph<T>::setUnion(std::unordered_map<unsigned long long, Subset> *subsets,
1256+
const unsigned long long elem1,
1257+
const unsigned long long elem2) const {
1258+
/* auto subsets_ptr = make_shared<std::unordered_map<unsigned long long,
1259+
* Subset>>(*subsets); */
12121260
// if both sets have same parent
12131261
// then there's nothing to be done
1214-
/* if ((*subsets_ptr)[elem1].parent == (*subsets_ptr)[elem2].parent) return; */
1262+
/* if ((*subsets_ptr)[elem1].parent == (*subsets_ptr)[elem2].parent) return;
1263+
*/
12151264
/* auto elem1Parent = Graph<T>::setFind(subsets_ptr, elem1); */
12161265
/* auto elem2Parent = Graph<T>::setFind(subsets_ptr, elem2); */
12171266
/* if ((*subsets_ptr)[elem1Parent].rank < (*subsets_ptr)[elem2Parent].rank) */
12181267
/* (*subsets_ptr)[elem1].parent = elem2Parent; */
1219-
/* else if ((*subsets_ptr)[elem1Parent].rank > (*subsets_ptr)[elem2Parent].rank) */
1268+
/* else if ((*subsets_ptr)[elem1Parent].rank >
1269+
* (*subsets_ptr)[elem2Parent].rank) */
12201270
/* (*subsets_ptr)[elem2].parent = elem1Parent; */
12211271
/* else { */
12221272
/* (*subsets_ptr)[elem2].parent = elem1Parent; */
@@ -1329,6 +1379,59 @@ const std::shared_ptr<AdjacencyMatrix<T>> Graph<T>::getAdjMatrix() const {
13291379
return adj;
13301380
}
13311381

1382+
template <typename T>
1383+
const std::unordered_set<shared<const Node<T>>, nodeHash<T>> Graph<T>::outNeighbors(
1384+
const Node<T> *node) const {
1385+
auto node_shared = make_shared<const Node<T>>(*node);
1386+
1387+
return outNeighbors(node_shared);
1388+
}
1389+
1390+
template <typename T>
1391+
const std::unordered_set<shared<const Node<T>>, nodeHash<T>> Graph<T>::outNeighbors(
1392+
shared<const Node<T>> node) const {
1393+
auto adj = getAdjMatrix();
1394+
if (adj->find(node) == adj->end()) {
1395+
return std::unordered_set<shared<const Node<T>>, nodeHash<T>>();
1396+
}
1397+
auto nodeEdgePairs = adj->at(node);
1398+
1399+
std::unordered_set<shared<const Node<T>>, nodeHash<T>> outNeighbors;
1400+
for (auto pair : nodeEdgePairs) {
1401+
if (pair.second->isDirected().has_value() &&
1402+
pair.second->isDirected().value()) {
1403+
outNeighbors.insert(pair.first);
1404+
}
1405+
}
1406+
1407+
return outNeighbors;
1408+
}
1409+
1410+
template <typename T>
1411+
const std::unordered_set<shared<const Node<T>>, nodeHash<T>>
1412+
Graph<T>::inOutNeighbors(const Node<T> *node) const {
1413+
auto node_shared = make_shared<const Node<T>>(*node);
1414+
1415+
return inOutNeighbors(node_shared);
1416+
}
1417+
1418+
template <typename T>
1419+
const std::unordered_set<shared<const Node<T>>, nodeHash<T>>
1420+
Graph<T>::inOutNeighbors(shared<const Node<T>> node) const {
1421+
auto adj = Graph<T>::getAdjMatrix();
1422+
if (adj->find(node) == adj->end()) {
1423+
return std::unordered_set<shared<const Node<T>>, nodeHash<T>>();
1424+
}
1425+
auto nodeEdgePairs = adj->at(node);
1426+
1427+
std::unordered_set<shared<const Node<T>>, nodeHash<T>> inOutNeighbors;
1428+
for (auto pair : nodeEdgePairs) {
1429+
inOutNeighbors.insert(pair.first);
1430+
}
1431+
1432+
return inOutNeighbors;
1433+
}
1434+
13321435
template <typename T>
13331436
const DijkstraResult Graph<T>::dijkstra(const Node<T> &source,
13341437
const Node<T> &target) const {
@@ -1466,7 +1569,8 @@ const BellmanFordResult Graph<T>::bellmanford(const Node<T> &source,
14661569
return result;
14671570
}
14681571
// setting all the distances initially to INF_DOUBLE
1469-
std::unordered_map<shared<const Node<T>>, double, nodeHash<T>> dist, currentDist;
1572+
std::unordered_map<shared<const Node<T>>, double, nodeHash<T>> dist,
1573+
currentDist;
14701574
// n denotes the number of vertices in graph
14711575
auto n = nodeSet.size();
14721576
for (const auto &elem : nodeSet) {
@@ -1555,7 +1659,8 @@ const Graph<T> Graph<T>::transitiveReduction() const {
15551659
Graph<T> result(this->edgeSet);
15561660

15571661
unsigned long long edgeId = 0;
1558-
std::unordered_set<shared<const Node<T>>, nodeHash<T>> nodes = this->getNodeSet();
1662+
std::unordered_set<shared<const Node<T>>, nodeHash<T>> nodes =
1663+
this->getNodeSet();
15591664
for (auto x : nodes) {
15601665
for (auto y : nodes) {
15611666
if (this->findEdge(x, y, edgeId)) {
@@ -1849,7 +1954,8 @@ const MstResult Graph<T>::kruskal() const {
18491954
sortedEdges;
18501955
for (const auto &edge : edgeSet) {
18511956
if (edge->isWeighted().has_value() && edge->isWeighted().value()) {
1852-
auto weight = (std::dynamic_pointer_cast<const Weighted>(edge))->getWeight();
1957+
auto weight =
1958+
(std::dynamic_pointer_cast<const Weighted>(edge))->getWeight();
18531959
sortedEdges.push(std::make_pair(weight, edge));
18541960
} else {
18551961
// No Weighted Edge
@@ -2838,8 +2944,12 @@ double Graph<T>::fordFulkersonMaxFlow(const Node<T> &source,
28382944
return -1;
28392945
}
28402946
double maxFlow = 0;
2841-
std::unordered_map<shared<const Node<T>>, shared<const Node<T>>, nodeHash<T>> parent;
2842-
std::unordered_map<shared<const Node<T>>, std::unordered_map<shared<const Node<T>>, double, nodeHash<T>>, nodeHash<T>>
2947+
std::unordered_map<shared<const Node<T>>, shared<const Node<T>>, nodeHash<T>>
2948+
parent;
2949+
std::unordered_map<
2950+
shared<const Node<T>>,
2951+
std::unordered_map<shared<const Node<T>>, double, nodeHash<T>>,
2952+
nodeHash<T>>
28432953
weightMap;
28442954
// build weight map
28452955
auto edgeSet = this->getEdgeSet();

0 commit comments

Comments
 (0)