Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fixing bfs_dist, adding METIS separator, add fuse_vertices() #34

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 3 additions & 1 deletion lib_graphd/inc/Graph.h
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,10 @@ namespace Graph {
int add_vertex();
bool remove_edge(int u, int v);
void remove_vertex(int u);

int edge_subdivision(int u, int v, int w);
int contract_edge(int u, int v);
int fuse_vertices(int u, int v, bool contract_edge);
void resize_graph(int n);
void resize_adj_vec(int n);
void eliminate_vertex(int v, list<int> *forward_neighbors, bool remove);
void initialize_params();
Expand Down
4 changes: 3 additions & 1 deletion lib_graphd/inc/GraphUtil.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,13 +68,15 @@ namespace Graph {
int vertex_separator(Graph *g, list<int> *V,
vector<list<int> *> *members);

//ConstructSeparator from metis
void metis_ConstructSeparator(VertexWeightedGraph *g, list<int> *top, list<int> *bottom);

//runs a BFS from start using
//only vertices with allowed[v] = true.
//you need to delete the memory in the returned bool array.
//num_reached is the number of vertices which are reachable. This does not include
//disallowed vertices, and does include the start.
bool *bfs(Graph *g, int start, bool *allowed, int *num_reached);
bool *bfs_old(Graph *g, int start, bool *allowed, int *num_reached);
int *bfs_dist(Graph *g, int start, bool *allowed, int *num_reached);
int *bfs_dist(Graph *g, int start, bool *allowed, int *num_reached, int *ecc);

Expand Down
98 changes: 86 additions & 12 deletions lib_graphd/src/Graph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ namespace Graph {

int Graph::get_num_edges_in_subgraph(list<int> *vertices){
vertices->sort();
int highest_index = vertices->back();
//int highest_index = vertices->back();
vector<bool> v(this->num_nodes,false);
list<int>::iterator ii;
for(ii = vertices->begin(); ii != vertices->end(); ++ii){
Expand Down Expand Up @@ -413,7 +413,67 @@ namespace Graph {
num_nodes--;
} // remove_vertex

int Graph::edge_subdivision(int u, int v, int w) {
if (nodes[u].label == -1 || nodes[v].label == -1){
fatal_error(
"%s: Cannot remove edge (%d, %d) as one of its vertices is undefined!\n",
__FUNCTION__, u, v);
}
list<int>::iterator it;

// check that v is a neighbour of u
bool foundv = false;
for (it = nodes[u].nbrs.begin(); it != nodes[u].nbrs.end(); ++it){
if(*it == v)
foundv = true;
}
if(foundv == false){
return false;
}

// if w provided, check that it is in bounds
if(w > capacity){
nodes.resize(2*capacity);
capacity*=2;
}

nodes[w].nbrs.clear();
if(!nodes[w].nbrs.empty()){
FERROR("%s: node is not empty", __FUNCTION__);
throw GraphException("node is not empty\n");
}
else{
nodes[w].label=w;
degree[w] = 2;
nodes[w].nbrs.push_back(u);
nodes[w].nbrs.push_back(v);

// remove u from v's nbrs list and vice versa
for(it = nodes[u].nbrs.begin() ; it != nodes[u].nbrs.end();it++){
if(*it==v) {
*it=w;
break;
}
}
for(it = nodes[v].nbrs.begin() ; it != nodes[v].nbrs.end();it++){
if(*it==u) {
*it=w;
break;
}
}
}
num_edges++;
next_label++;
num_nodes++;
return w;
}

// contract_edge and fuse_vertices, differ only in whether or not e=(u,v) has to be an edge
int Graph::contract_edge(int u, int v){
return fuse_vertices(u,v,true);
}

int Graph::fuse_vertices(int u, int v, bool contract_edge=false){
int i;
if(simple != true){
fatal_error("%s: called on a non-simple graph!\n", __FUNCTION__);
Expand All @@ -426,24 +486,26 @@ namespace Graph {
vector<bool> neighbors(capacity);
fill(neighbors.begin(), neighbors.end(), false);
list<int>::iterator it;

if (v == u)//maybe don't need this
return false;

bool foundv = false;
it = nodes[u].nbrs.begin();
while(it != nodes[u].nbrs.end()){
for (it = nodes[u].nbrs.begin(); it != nodes[u].nbrs.end(); ++it){
neighbors[*it] = true;
if(*it == v){
foundv = true;
}

++it;
}
if(foundv == false){
return false;

if(contract_edge){ // for fuse_vertices alone, don't need to be neighbours. for contract_edge you do
if(foundv == false){
return false;
}
}

it = nodes[v].nbrs.begin();
while(it != nodes[v].nbrs.end()){
for (it = nodes[v].nbrs.begin(); it != nodes[v].nbrs.end(); ++it){
neighbors[*it] = true;
++it;
}
remove_vertex(u);
remove_vertex(v);
Expand All @@ -461,9 +523,21 @@ namespace Graph {
}
}
}

return u;
} // contract_edge
} // fuse_vertices

void Graph::resize_graph(int size){
if(size < capacity){
fatal_error(
"%s: resize_graph() called with new size %d less than capacity %d\n",
__FUNCTION__, size, capacity);
}
else{
nodes.resize(size,Node());
degree.resize(size,0);
this->set_capacity(size);
}
}

void Graph::set_simple(bool si){
simple = si;
Expand Down