From 7b0388d8ff39fb4c6afa05fc2b6f9679abad081e Mon Sep 17 00:00:00 2001 From: Rohan Badlani Date: Sun, 16 Dec 2018 17:55:19 -0800 Subject: [PATCH 1/4] Neighbors implementation for Undirected Graph --- snap-core/graph.cpp | 40 ++++++++++++++++++++++++++++++++++++++++ snap-core/graph.h | 2 ++ 2 files changed, 42 insertions(+) diff --git a/snap-core/graph.cpp b/snap-core/graph.cpp index 707f0fcc9..ddd87cc76 100644 --- a/snap-core/graph.cpp +++ b/snap-core/graph.cpp @@ -203,6 +203,46 @@ bool TUNGraph::IsOk(const bool& ThrowExcept) const { return RetVal; } +void TUNGraph::GetNeighbors(const int& NId, TIntV& NeighborsIdV){ + //check if the node exists + AssertR(IsNode(NId), TStr::Fmt("NodeId %d does not exist", NId)); + + //get the snap node corresponding to nodeId + TNode& Node = GetNode(NId); + + int neighborCount = Node.GetDeg(); + + NeighborsIdV.Gen(neighborCount, 0); + + //go through the entire degree (as it is undirected) of this node + //NEdges -= Node.GetDeg(); + + for (int e = 0; e < Node.GetDeg(); e++) { + + const int nbr = Node.GetNbrNId(e); + + if (nbr == NId) + { + continue; + } + + TNode& N = GetNode(nbr); + + const int n = N.NIdV.SearchBin(NId); + + IAssert(n != -1); // if NId points to N, then N also should point back + + //add neighbor to neighbors list + if (n != -1) { + NeighborsIdV.Add(nbr); + } + + } + + //for (int N=NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) { + // NIdV.Add(NodeH.GetKey(N)); } +} + // Print the graph in a human readable form to an output stream OutF. void TUNGraph::Dump(FILE *OutF) const { const int NodePlaces = (int) ceil(log10((double) GetNodes())); diff --git a/snap-core/graph.h b/snap-core/graph.h index 13f51ab7e..55c1f3d6f 100644 --- a/snap-core/graph.h +++ b/snap-core/graph.h @@ -239,6 +239,8 @@ class TUNGraph { void Defrag(const bool& OnlyNodeLinks=false); /// Checks the graph data structure for internal consistency. ##TUNGraph::IsOk bool IsOk(const bool& ThrowExcept=true) const; + /// Fills in the neighbor list of the node in the provided vector ##TUNGraph::GetNeighbors + void GetNeighbors(const int& NId, TIntV& NeighborsIdV); /// Print the graph in a human readable form to an output stream OutF. void Dump(FILE *OutF=stdout) const; /// Returns a small graph on 5 nodes and 5 edges. ##TUNGraph::GetSmallGraph From 505d2371e63d4e7f5272409ea2149c4cdea3ec2a Mon Sep 17 00:00:00 2001 From: Rohan Badlani Date: Sun, 16 Dec 2018 18:03:13 -0800 Subject: [PATCH 2/4] Neighbors implementation for Directed Graphs in SNAP --- snap-core/graph.cpp | 54 ++++++++++++++++++++++++++++++++++++++++++--- snap-core/graph.h | 3 +++ 2 files changed, 54 insertions(+), 3 deletions(-) diff --git a/snap-core/graph.cpp b/snap-core/graph.cpp index ddd87cc76..5c2a16706 100644 --- a/snap-core/graph.cpp +++ b/snap-core/graph.cpp @@ -238,9 +238,6 @@ void TUNGraph::GetNeighbors(const int& NId, TIntV& NeighborsIdV){ } } - - //for (int N=NodeH.FFirstKeyId(); NodeH.FNextKeyId(N); ) { - // NIdV.Add(NodeH.GetKey(N)); } } // Print the graph in a human readable form to an output stream OutF. @@ -474,6 +471,57 @@ bool TNGraph::IsOk(const bool& ThrowExcept) const { return RetVal; } +void TNGraph::GetNeighbors(const int& NId, TIntV& NeighborsIdV, bool outDegreeNeighbors){ + //check if the node exists + AssertR(IsNode(NId), TStr::Fmt("NodeId %d does not exist", NId)); + + //get the snap node corresponding to nodeId + TNode& Node = GetNode(NId); + + int neighborCount = 0; + + if(outDegreeNeighbors){ + neighborCount = Node.GetOutDeg(); + } + else{ + neighborCount = Node.GetInDeg(); + } + + NeighborsIdV.Gen(neighborCount, 0); + + //go through the entire degree (as it is undirected) of this node + for (int e = 0; e < neighborCount; e++) { + int nbr; + + if(outDegreeNeighbors){ + nbr = Node.GetOutNId(e); + } + else{ + nbr = Node.GetInNId(e); + } + + if (nbr == NId) + { + continue; + } + + TNode& N = GetNode(nbr); + + if(outDegreeNeighbors){ + const int n = N.InNIdV.SearchBin(NId); + if (n != -1) { + NeighborsIdV.Add(nbr); + } + } + else{ + const int n = N.OutNIdV.SearchBin(NId); + if (n != -1) { + NeighborsIdV.Add(nbr); + } + } + } +} + void TNGraph::Dump(FILE *OutF) const { const int NodePlaces = (int) ceil(log10((double) GetNodes())); fprintf(OutF, "-------------------------------------------------\nDirected Node Graph: nodes: %d, edges: %d\n", GetNodes(), GetEdges()); diff --git a/snap-core/graph.h b/snap-core/graph.h index 55c1f3d6f..ee8f5a82f 100644 --- a/snap-core/graph.h +++ b/snap-core/graph.h @@ -327,6 +327,7 @@ class TNGraph { bool IsOutNId(const int& NId) const { return NodeHI.GetDat().IsOutNId(NId); } /// Tests whether node with ID NId is a neighbor of the current node. bool IsNbrNId(const int& NId) const { return IsOutNId(NId) || IsInNId(NId); } + friend class TNGraph; }; /// Edge iterator. Only forward iteration (operator++) is supported. @@ -472,6 +473,8 @@ class TNGraph { void Defrag(const bool& OnlyNodeLinks=false); /// Checks the graph data structure for internal consistency. ##TNGraph::IsOk bool IsOk(const bool& ThrowExcept=true) const; + /// Fills in the neighbor list of the node in the provided vector ##TNGraph::GetNeighbors + void GetNeighbors(const int& NId, TIntV& NeighborsIdV, bool outDegreeNeighbors=true); /// Print the graph in a human readable form to an output stream OutF. void Dump(FILE *OutF=stdout) const; /// Returns a small graph on 5 nodes and 6 edges. ##TNGraph::GetSmallGraph From ce0d8e2fb23232ad5cbdbf0936b0b8a781224f9b Mon Sep 17 00:00:00 2001 From: Rohan Badlani Date: Sun, 16 Dec 2018 18:07:58 -0800 Subject: [PATCH 3/4] Adding in Tests for Undirected Graphs. Tests Passing --- test/test-TUNGraph.cpp | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/test/test-TUNGraph.cpp b/test/test-TUNGraph.cpp index 2660a4367..cdb9dad99 100644 --- a/test/test-TUNGraph.cpp +++ b/test/test-TUNGraph.cpp @@ -1,6 +1,7 @@ #include #include "Snap.h" +#include // Test the default constructor TEST(TUNGraph, DefaultConstructor) { @@ -288,5 +289,39 @@ TEST(TUNGraph, GetSmallGraph) { EXPECT_EQ(1,Graph->IsOk()); EXPECT_EQ(0,Graph->Empty()); + EXPECT_EQ(0,Graph->HasFlag(gfDirected)); +} + +// Test Neighbors +TEST(TUNGraph, TestNeighbors) { + PUNGraph Graph; + + Graph = TUNGraph::GetSmallGraph(); + + TIntV NeighborNodeIds; + + Graph->GetNeighbors(1, NeighborNodeIds); + + TUNGraph::TNodeI NodeI = Graph->GetNI(1); + int degree = NodeI.GetDeg(); + std::set st; + + for(int i=0;iIsOk()); + EXPECT_EQ(0,Graph->HasFlag(gfDirected)); } \ No newline at end of file From 2f90f277da5f22b75a90ef7bf194587286cc436e Mon Sep 17 00:00:00 2001 From: Rohan Badlani Date: Sun, 16 Dec 2018 18:08:55 -0800 Subject: [PATCH 4/4] Tests for Directed Graphs. Tests Passing. --- test/test-TNGraph.cpp | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/test/test-TNGraph.cpp b/test/test-TNGraph.cpp index e90b84d8c..895517b67 100644 --- a/test/test-TNGraph.cpp +++ b/test/test-TNGraph.cpp @@ -157,5 +157,39 @@ TEST(TNGraph, GetSmallGraph) { EXPECT_EQ(1,Graph->IsOk()); EXPECT_EQ(0,Graph->Empty()); + EXPECT_EQ(1,Graph->HasFlag(gfDirected)); +} + +// Test Neighbors +TEST(TNGraph, TestNeighbors) { + PNGraph Graph; + + Graph = TNGraph::GetSmallGraph(); + + TIntV NeighborNodeIds; + + Graph->GetNeighbors(0, NeighborNodeIds); + + TNGraph::TNodeI NodeI = Graph->GetNI(0); + int degree = NodeI.GetOutDeg(); + std::set st; + + for(int i=0;iIsOk()); + EXPECT_EQ(1,Graph->HasFlag(gfDirected)); } \ No newline at end of file