Skip to content

Commit

Permalink
added component counting
Browse files Browse the repository at this point in the history
  • Loading branch information
djryn committed Apr 10, 2022
1 parent 442ba7a commit 5027618
Show file tree
Hide file tree
Showing 2 changed files with 181 additions and 25 deletions.
196 changes: 172 additions & 24 deletions src/Graph_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,21 @@ void Graph_helper::read_graphml(const char* file) {

}

void Graph_helper::girvan_newman() {
numNodes = (int)boost::num_vertices(graph);
numEdges = (int)boost::num_edges(graph);


void Graph_helper::girvan_newman() {
auto vpair = boost::vertices(graph);
for(auto iter = vpair.first; iter != vpair.second; iter++) {
graph[*iter].origDegree = (int)boost::degree(*iter, graph);
}

girvan_newman_helper();

}

void Graph_helper::girvan_newman_helper() {


// While Girvan-Neumann modularity is not satisfied
Expand All @@ -60,37 +72,50 @@ void Graph_helper::girvan_newman() {
// keep track of modularity and compare against current max
// keep doing it until no more edges, or until it decreases (idk which is better)

//Breadth First Search to find shortest paths
auto vpair = boost::vertices(graph);
for(vertexIt iter = vpair.first; iter != vpair.second; iter++) {

std::cout << "source: " << *iter << std::endl;
std::cout << "visited: ";
std::vector<int> component(numNodes);
size_t num_components = boost::connected_components(graph, &component[0]);
size_t new_num = num_components;
std::cout << num_components << std::endl;

std::map<vd, vd> prev;
while(new_num <= num_components) {
//Breadth First Search to find shortest paths
auto vpair = boost::vertices(graph);
for(vertexIt iter = vpair.first; iter != vpair.second; iter++) {

breadth_first_search(prev, iter);
reconstruct_paths(prev, iter);
reset_tracking_data(iter); // Resets tracking data for path construction
}
std::cout << "source: " << *iter << std::endl;
std::cout << "visited: ";

// Finds the Highest Value
auto e = boost::edges(graph);
auto max = *(e.first);
int maxCount = -1;
for(auto ed = e.first; ed != e.second; ed++) {
if(graph[*ed].count > maxCount) {
max = *ed;
maxCount = graph[*ed].count;
std::map<vd, vd> prev;

breadth_first_search(prev, iter);
reconstruct_paths(prev, iter);
reset_tracking_data(iter); // Resets tracking data for path construction
}
graph[*ed].count = 0;
}
std::cout << "max edge: " << max.m_source << " to " << max.m_target << std::endl;
boost::remove_edge(max.m_source, max.m_target, graph);
std::cout << "edge removed" << std::endl;

// Finds the Highest Value
auto e = boost::edges(graph);
auto max = *(e.first);
int maxCount = -1;
for(auto ed = e.first; ed != e.second; ed++) {
if(graph[*ed].count > maxCount) {
max = *ed;
maxCount = graph[*ed].count;

}
graph[*ed].count = 0;
}
std::cout << "max edge: " << max.m_source << " to " << max.m_target << std::endl;
boost::remove_edge(max.m_source, max.m_target, graph);
std::cout << "edge removed" << std::endl;
// remove edge with highest value

new_num = boost::connected_components(graph, &component[0]);
std::cout << "new comp num: " << new_num << std::endl;


}

// find communities

}
Expand Down Expand Up @@ -153,3 +178,126 @@ void Graph_helper::reset_tracking_data(vertexIt iter) {
for(auto v = vpair.first; v != vpair.second; v++)
graph[*v].used = false;
}





/* def buildG(G, file_, delimiter_):
#construct the weighted version of the contact graph from cgraph.dat file
#reader = csv.reader(open("/home/kazem/Data/UCI/karate.txt"), delimiter=" ")
reader = csv.reader(open(file_), delimiter=delimiter_)
for line in reader:
if len(line) > 2:
if float(line[2]) != 0.0:
#line format: u,v,w
G.add_edge(int(line[0]),int(line[1]),weight=float(line[2]))
else:
#line format: u,v
G.add_edge(int(line[0]),int(line[1]),weight=1.0)
# This method keeps removing edges from Graph until one of the connected components of Graph splits into two
# compute the edge betweenness
def CmtyGirvanNewmanStep(G):
if _DEBUG_:
print("Running CmtyGirvanNewmanStep method ...")
init_ncomp = nx.number_connected_components(G) #no of components
ncomp = init_ncomp
while ncomp <= init_ncomp:
bw = nx.edge_betweenness_centrality(G, weight='weight') #edge betweenness for G
#find the edge with max centrality
max_ = max(bw.values())
#find the edge with the highest centrality and remove all of them if there is more than one!
for k, v in bw.items():
if float(v) == max_:
G.remove_edge(k[0],k[1]) #remove the central edge
ncomp = nx.number_connected_components(G) #recalculate the no of components
# This method compute the modularity of current split
def _GirvanNewmanGetModularity(G, deg_, m_):
New_A = nx.adj_matrix(G)
New_deg = {}
New_deg = UpdateDeg(New_A, G.nodes())
#Let's compute the Q
comps = nx.connected_components(G) #list of components
print('No of communities in decomposed G: {}'.format(nx.number_connected_components(G)))
Mod = 0 #Modularity of a given partitionning
for c in comps:
EWC = 0 #no of edges within a community
RE = 0 #no of random edges
for u in c:
EWC += New_deg[u]
RE += deg_[u] #count the probability of a random edge
Mod += ( float(EWC) - float(RE*RE)/float(2*m_) )
Mod = Mod/float(2*m_)
if _DEBUG_:
print("Modularity: {}".format(Mod))
return Mod
def UpdateDeg(A, nodes):
deg_dict = {}
n = len(nodes) #len(A) ---> some ppl get issues when trying len() on sparse matrixes!
B = A.sum(axis = 1)
i = 0
for node_id in list(nodes):
deg_dict[node_id] = B[i, 0]
i += 1
return deg_dict
# This method runs GirvanNewman algorithm and find the best community split by maximizing modularity measure
def runGirvanNewman(G, Orig_deg, m_):
#let's find the best split of the graph
BestQ = 0.0
Q = 0.0
while True:
CmtyGirvanNewmanStep(G)
Q = _GirvanNewmanGetModularity(G, Orig_deg, m_);
print("Modularity of decomposed G: {}".format(Q))
if Q > BestQ:
BestQ = Q
Bestcomps = list(nx.connected_components(G)) #Best Split
print("Identified components: {}".format(Bestcomps))
if G.number_of_edges() == 0:
break
if BestQ > 0.0:
print("Max modularity found (Q): {} and number of communities: {}".format(BestQ, len(Bestcomps)))
print("Graph communities: {}".format(Bestcomps))
else:
print("Max modularity (Q):", BestQ)
def main(argv):
if len(argv) < 2:
sys.stderr.write("Usage: %s <input graph>\n" % (argv[0],))
return 1
graph_fn = argv[1]
G = nx.Graph() #let's create the graph first
buildG(G, graph_fn, ',')
if _DEBUG_:
print('G nodes: {} & G no of nodes: {}'.format(G.nodes(), G.number_of_nodes()))
n = G.number_of_nodes() #|V|
A = nx.adj_matrix(G) #adjacenct matrix
m_ = 0.0 #the weighted version for number of edges
for i in range(0,n):
for j in range(0,n):
m_ += A[i,j]
m_ = m_/2.0
if _DEBUG_:
print("m: {}".format(m_))
#calculate the weighted degree for each node
Orig_deg = {}
Orig_deg = UpdateDeg(A, G.nodes())
#run Newman alg
runGirvanNewman(G, Orig_deg, m_)
if __name__ == "__main__":
sys.exit(main(sys.argv)) */
10 changes: 9 additions & 1 deletion src/Graph_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include <boost/graph/graphml.hpp>
#include <boost/property_map/dynamic_property_map.hpp>
#include <boost/property_map/property_map.hpp>
#include <boost/graph/connected_components.hpp>
#include <typeinfo>
#include <cxxabi.h>
#include <fstream>
Expand All @@ -25,13 +26,15 @@ struct VertexProperty {
bool foundPaths = false;
bool used = false;
int distance = -1;
int origDegree = 0;
int newDegree = 0;
};
struct EdgeProperty {
std::string Name = "m";
int count = 0;
};

using Graph = boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS, VertexProperty, EdgeProperty>;
typedef boost::adjacency_list<boost::setS, boost::vecS, boost::undirectedS, VertexProperty, EdgeProperty> Graph;
typedef boost::range_detail::integer_iterator<unsigned long> vertexIt;
typedef boost::graph_traits<Graph>::vertex_descriptor vd;

Expand All @@ -40,14 +43,19 @@ typedef boost::graph_traits<Graph>::vertex_descriptor vd;
class Graph_helper {
private:
Graph graph;
int numNodes;
int numEdges;

public:
void print_graph();
void print_edges();
void print_vertices();

void read_graphml(const char*);
void set_degree();
void get_modularity();
void girvan_newman();
void girvan_newman_helper();
void breadth_first_search(std::map<vd, vd>&, vertexIt);
void reconstruct_paths(std::map<vd, vd>&, vertexIt);
void reset_tracking_data(vertexIt);
Expand Down

0 comments on commit 5027618

Please sign in to comment.