959 lines
28 KiB
C++
959 lines
28 KiB
C++
/*
|
|
----
|
|
This file is part of SECONDO.
|
|
|
|
Copyright (C) 2004, University in Hagen, Department of Computer Science,
|
|
Database Systems for New Applications.
|
|
|
|
SECONDO is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
SECONDO is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with SECONDO; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
----
|
|
|
|
//paragraph [1] Title: [{\Large \bf \begin {center}] [\end {center}}]
|
|
//[TOC] [\tableofcontents]
|
|
|
|
[1] Source File of a standard graph implementation
|
|
|
|
Dec, 2010 Mahmoud Sakr
|
|
|
|
[TOC]
|
|
|
|
1 Overview
|
|
|
|
2 Defines and includes
|
|
|
|
*/
|
|
|
|
#include<map>
|
|
#include<vector>
|
|
#include<set>
|
|
#include<algorithm>
|
|
#include"LightWeightGraph.h"
|
|
|
|
using namespace std;
|
|
namespace GPattern {
|
|
|
|
ostream& NewComponent::Print( ostream &os )
|
|
{
|
|
os<<endl<<"This NewComponent consists of components:";
|
|
for(vector<int>::iterator it= affectedComponents.begin(); it!=
|
|
affectedComponents.end(); ++it)
|
|
os<< *it<<", ";
|
|
os<<endl<<" It has additionally the nodes :";
|
|
for(set<int>::iterator it= newNodes.begin(); it!= newNodes.end(); ++it)
|
|
os<<*it<< ", ";
|
|
return os;
|
|
}
|
|
|
|
bool NewComponent::AffectsComponent(int label)
|
|
{
|
|
return(
|
|
find(this->affectedComponents.begin(), this->affectedComponents.end(),
|
|
label ) != this->affectedComponents.end());
|
|
}
|
|
void NewComponent::Union(NewComponent& arg)
|
|
{
|
|
for(unsigned int i= 0; i< arg.affectedComponents.size(); ++i)
|
|
{
|
|
if(
|
|
find(this->affectedComponents.begin(), this->affectedComponents.end(),
|
|
arg.affectedComponents[i]) == this->affectedComponents.end() )
|
|
this->affectedComponents.push_back(arg.affectedComponents[i]);
|
|
}
|
|
|
|
this->newNodes.insert(
|
|
arg.newNodes.begin(), arg.newNodes.end());
|
|
}
|
|
|
|
|
|
void Component::SetMessage(ComponentMessage msg)
|
|
{
|
|
this->message= msg;
|
|
}
|
|
bool Component::UpdateMessage(ComponentMessage newMsg)
|
|
{
|
|
bool debugme= false;
|
|
if(newMsg == this->message) return true;
|
|
string msgs[]= {"NotChanged", "AddedEdges",
|
|
"RemovedEdges", "AddRemoveMix",
|
|
"NewlyAdded", "RemoveNow", "SplitFromExtistingComponent",
|
|
"MergedFromExistingComponents", "ReDistribute"};
|
|
if(debugme)
|
|
cerr<< "\ncur message: "<< msgs[this->message] <<endl<<
|
|
"argument message"<< msgs[newMsg];
|
|
switch (this->message)
|
|
{
|
|
case Component::NotChanged:
|
|
{
|
|
this->message= newMsg;
|
|
return true;
|
|
}break;
|
|
case Component::AddedEdges:
|
|
{
|
|
if(newMsg== NotChanged || newMsg== AddedEdges)
|
|
{
|
|
this->message= AddedEdges;
|
|
return true;
|
|
}
|
|
if(newMsg== RemovedEdges || newMsg== AddRemoveMix)
|
|
{
|
|
this->message=AddRemoveMix;
|
|
return true;
|
|
}
|
|
if(newMsg == NewlyAdded)
|
|
return false;
|
|
if(newMsg == SplitFromExtistingComponent || newMsg== RemoveNow ||
|
|
newMsg== MergedFromExistingComponents || newMsg== ReDistribute)
|
|
{
|
|
this->message= newMsg;
|
|
return true;
|
|
}
|
|
}break;
|
|
case Component::RemovedEdges:
|
|
{
|
|
if(newMsg== NotChanged || newMsg== RemovedEdges)
|
|
return true;
|
|
if(newMsg== AddedEdges || newMsg== AddRemoveMix)
|
|
{
|
|
this->message=AddRemoveMix;
|
|
return true;
|
|
}
|
|
if(newMsg == NewlyAdded)
|
|
return false;
|
|
if(newMsg == SplitFromExtistingComponent || newMsg== RemoveNow ||
|
|
newMsg== MergedFromExistingComponents)
|
|
{
|
|
this->message= newMsg;
|
|
return true;
|
|
}
|
|
}break;
|
|
case Component::AddRemoveMix:
|
|
{
|
|
if(newMsg== NotChanged || newMsg== RemovedEdges ||
|
|
newMsg== AddedEdges || newMsg== AddRemoveMix)
|
|
{
|
|
this->message=AddRemoveMix;
|
|
return true;
|
|
}
|
|
if(newMsg == NewlyAdded)
|
|
return false;
|
|
if(newMsg == SplitFromExtistingComponent || newMsg== RemoveNow ||
|
|
newMsg== MergedFromExistingComponents)
|
|
{
|
|
this->message= newMsg;
|
|
return true;
|
|
}
|
|
}break;
|
|
case Component::NewlyAdded:
|
|
{
|
|
if(newMsg== NotChanged || newMsg== RemovedEdges ||
|
|
newMsg== AddedEdges || newMsg== AddRemoveMix ||
|
|
newMsg == SplitFromExtistingComponent)
|
|
return true;
|
|
if(newMsg == RemoveNow)
|
|
{
|
|
this->message= newMsg;
|
|
return true;
|
|
}
|
|
}break;
|
|
case Component::SplitFromExtistingComponent:
|
|
case Component::RemoveNow:
|
|
return false; break;
|
|
case Component::MergedFromExistingComponents:
|
|
{
|
|
if(newMsg== NotChanged || newMsg== RemovedEdges ||
|
|
newMsg== AddRemoveMix)
|
|
{
|
|
this->message= MergedFromExistingComponents;
|
|
return true;
|
|
}
|
|
if(newMsg== RemoveNow)
|
|
{
|
|
this->message= RemoveNow;
|
|
return true;
|
|
}
|
|
if(newMsg== SplitFromExtistingComponent)
|
|
{
|
|
this->message= ReDistribute;
|
|
return true;
|
|
}
|
|
}break;
|
|
default:
|
|
return false;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void Component::Cluster(LWGraph* g, list<set<int> >& splitComponents)
|
|
{
|
|
splitComponents.clear();
|
|
|
|
list<int> frontier;
|
|
set<int> already_added;
|
|
int curNode;
|
|
list< set< pair<int, int> > >::iterator curNodeNeighborsIt;
|
|
set< pair<int, int> >* curNodeNeighbors;
|
|
for(set<int>::iterator it= this->nodes.begin(); it!= this->nodes.end(); ++it)
|
|
{
|
|
curNode= *it;
|
|
if( already_added.find(curNode) != already_added.end()) continue;
|
|
frontier.push_back(curNode);
|
|
set<int> comp;
|
|
comp.insert(curNode);
|
|
while(!frontier.empty())
|
|
{
|
|
curNode= frontier.back();
|
|
frontier.pop_back();
|
|
if( already_added.find(curNode) != already_added.end()) continue;
|
|
already_added.insert(curNode);
|
|
curNodeNeighborsIt= g->node_index[curNode];
|
|
curNodeNeighbors= &(*curNodeNeighborsIt);
|
|
|
|
for(set<pair<int,int> >::iterator nIt= curNodeNeighbors->begin(); nIt!=
|
|
curNodeNeighbors->end(); ++nIt)
|
|
{
|
|
frontier.push_front( (*nIt).first);
|
|
comp.insert((*nIt).first);
|
|
}
|
|
}
|
|
splitComponents.push_back(comp);
|
|
}
|
|
}
|
|
|
|
void Component::SynchronizeNodes(LWGraph* g)
|
|
{
|
|
map<int, int>::iterator nodeComp;
|
|
set<int>::iterator nodeIt= nodes.begin();
|
|
while( nodeIt!= nodes.end())
|
|
{
|
|
nodeComp= g->node_component.find(*nodeIt);
|
|
if(nodeComp == g->node_component.end())
|
|
nodes.erase(nodeIt++);
|
|
else
|
|
++nodeIt;
|
|
//may raise
|
|
}
|
|
}
|
|
bool Component::IsConnected(LWGraph* g, int node1, int node2)
|
|
{
|
|
list<int> frontier;
|
|
set<int> already_added;
|
|
list< set< pair<int, int> > >::iterator curNodeNeighborsIt;
|
|
set< pair<int, int> >* curNodeNeighbors;
|
|
map<int,list< set< pair<int, int> > >::iterator>::iterator nodeIndexIt;
|
|
int curNode= node1;
|
|
frontier.push_back(curNode);
|
|
while(!frontier.empty())
|
|
{
|
|
curNode= frontier.back();
|
|
frontier.pop_back();
|
|
if( already_added.find(curNode) != already_added.end()) continue;
|
|
already_added.insert(curNode);
|
|
nodeIndexIt= g->node_index.find(curNode);
|
|
if(nodeIndexIt == g->node_index.end()) return false;
|
|
curNodeNeighborsIt= (*nodeIndexIt).second;
|
|
curNodeNeighbors= &(*curNodeNeighborsIt);
|
|
for(set<pair<int,int> >::iterator nIt= curNodeNeighbors->begin(); nIt!=
|
|
curNodeNeighbors->end(); ++nIt)
|
|
{
|
|
if((*nIt).first == node2)
|
|
return true;
|
|
frontier.push_front( (*nIt).first);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void Component::GetEdges(LWGraph* g, set<int>& compEdges)
|
|
{
|
|
compEdges.clear();
|
|
int curNode;
|
|
list< set< pair<int, int> > >::iterator curNodeNeighborsIt;
|
|
set< pair<int, int> >* curNodeNeighbors;
|
|
for(set<int>::iterator it= this->nodes.begin(); it!= this->nodes.end(); ++it)
|
|
{
|
|
curNode= *it;
|
|
curNodeNeighborsIt= g->node_index[curNode];
|
|
curNodeNeighbors= &(*curNodeNeighborsIt);
|
|
|
|
for(set<pair<int,int> >::iterator nIt= curNodeNeighbors->begin(); nIt!=
|
|
curNodeNeighbors->end(); ++nIt)
|
|
compEdges.insert( (*nIt).second);
|
|
}
|
|
}
|
|
|
|
void Component::Union(Component* arg)
|
|
{
|
|
assert(this->UpdateMessage(arg->message));
|
|
this->nodes.insert(arg->nodes.begin(), arg->nodes.end());
|
|
this->associatedResults.insert(this->associatedResults.end(),
|
|
arg->associatedResults.begin(), arg->associatedResults.end());
|
|
}
|
|
|
|
ostream& Component::Print( ostream &os )
|
|
{
|
|
os<<endl<<"Printing component "<<label<<": ";
|
|
for(set<int>::iterator it= nodes.begin(); it!= nodes.end(); ++it)
|
|
os<<*it<< ", ";
|
|
//os<<"\n Component is associated with "<<resStreams.size()<<" resStreams";
|
|
return os;
|
|
}
|
|
|
|
|
|
void Component::ExtendResStreamsTillNow(
|
|
vector<mset::CompressedMSet*>& resultsParts, int64_t endtime, bool rc)
|
|
{
|
|
if(ExtendedTillLastChange) return;
|
|
mset::CompressedUSetRef theUSet;
|
|
mset::CompressedMSet* theMSet;
|
|
list< vector<int> >::iterator associatedResultIt;
|
|
int resultPartToExtend;
|
|
for(unsigned int i=0; i < this->associatedResults.size(); ++i)
|
|
{
|
|
associatedResultIt= this->associatedResults[i];
|
|
resultPartToExtend= (*associatedResultIt).back();
|
|
theMSet= resultsParts[resultPartToExtend];
|
|
theMSet->units.Get(theMSet->GetNoComponents()-1, theUSet);
|
|
theUSet.endtime= endtime;
|
|
theUSet.rc= rc;
|
|
theMSet->units.Put(theMSet->GetNoComponents()-1, theUSet);
|
|
}
|
|
}
|
|
|
|
bool Component::Intersects(set<int>* arg)
|
|
{
|
|
return SetIntersects(&this->nodes, arg);
|
|
}
|
|
|
|
void Component::Reset()
|
|
{
|
|
this->SetMessage(Component::NotChanged);
|
|
this->addedEdges.clear();
|
|
this->removedEdges.clear();
|
|
}
|
|
|
|
int LWGraph::clear()
|
|
{
|
|
node_component.clear();
|
|
node_index.clear();
|
|
//(node label, index): stores the index of a node n in the "node" vector
|
|
neighbors.clear();
|
|
//the neighbors of a node (i.e. nodes that are directly connected
|
|
//with an edge). It is a parallel arary to "node"
|
|
return 0;
|
|
}
|
|
|
|
int LWGraph::copy_from(LWGraph* arg)
|
|
{
|
|
assert(arg->neighbors.size()== arg->node_index.size());
|
|
this->clear();
|
|
this->neighbors.assign(arg->neighbors.begin(), arg->neighbors.end());
|
|
list<set< pair<int, int> > >::iterator neighbor= this->neighbors.begin();
|
|
for(map<int, list< set< pair<int, int> > >::iterator>::iterator argIt=
|
|
arg->node_index.begin(); argIt != arg->node_index.end(); ++argIt)
|
|
{
|
|
this->node_index.insert(make_pair((*argIt).first, neighbor));
|
|
++neighbor;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
int LWGraph::insert_edge_directed(pair<int, int>* _edgeNodes, int& _edge)
|
|
{
|
|
int _first= _edgeNodes->first, _second= _edgeNodes->second;
|
|
return insert_edge_directed(_first, _second, _edge);
|
|
}
|
|
|
|
int LWGraph::insert_edge_directed(int& _first, int& _second, int& _edge)
|
|
{
|
|
int resCode=0;
|
|
map<int, list< set< pair<int, int> > >::iterator>::iterator _pos=
|
|
node_index.find(_first);
|
|
if(_pos != node_index.end())
|
|
(*(*_pos).second).insert(make_pair(_second, _edge));
|
|
else
|
|
{
|
|
set< pair<int, int> > adj; adj.insert(make_pair(_second, _edge));
|
|
neighbors.push_back(adj);
|
|
list< set< pair<int, int> > >::iterator it= --neighbors.end();
|
|
node_index.insert(make_pair(_first, it));
|
|
resCode= 1;
|
|
}
|
|
|
|
_pos= node_index.find(_second);
|
|
if(_pos == node_index.end())
|
|
{
|
|
set< pair<int, int> > tmp;
|
|
neighbors.push_back(tmp);
|
|
list< set< pair<int, int> > >::iterator it= --neighbors.end();
|
|
node_index.insert(make_pair(_second, it));
|
|
resCode+=2;
|
|
}
|
|
return resCode; //0 means that the edge introduces no new nodes to the graph
|
|
//1 means that _first is a new node
|
|
//2 means that _second is a new node
|
|
//3 means that both _first and _second are new nodes
|
|
}
|
|
|
|
bool LWGraph::remove_node_if_isolated(int _node)
|
|
{
|
|
//bool removed= false;
|
|
map<int, list< set< pair<int, int> > >::iterator>::iterator node_pos=
|
|
node_index.find(_node);
|
|
assertIf(node_pos != node_index.end());
|
|
list< set< pair<int, int> > >::iterator node_neighbors_it= (*node_pos).second;
|
|
|
|
//check whether the node has outbound edges
|
|
if(! (*node_neighbors_it).empty()) return false;
|
|
|
|
//check whether the node has inbound edges
|
|
for(list< set< pair<int, int> > >::iterator it=
|
|
this->neighbors.begin(); it!= this->neighbors.end(); ++it)
|
|
{
|
|
for(set<pair<int,int> >::iterator it2= (*it).begin(); it2!=
|
|
(*it).end(); ++it2)
|
|
if((*it2).first == _node) return false;
|
|
}
|
|
|
|
//there are no inbound or outbound edges for the node. We remove
|
|
//the node from the graph
|
|
neighbors.erase(node_neighbors_it);
|
|
node_index.erase(node_pos);
|
|
node_component.erase(_node);
|
|
|
|
return true; //node is found isolated and removed
|
|
}
|
|
|
|
int LWGraph::remove_edge_directed(pair<int, int>& _edgeNodes, int& _edge)
|
|
{
|
|
int _first= _edgeNodes.first, _second= _edgeNodes.second;
|
|
return remove_edge_directed(_first, _second, _edge);
|
|
}
|
|
|
|
int LWGraph::remove_edge_directed(int& _first, int& _second, int& _edge)
|
|
{
|
|
int resCode=0;
|
|
bool debugme= false;
|
|
if(debugme)
|
|
{
|
|
this->print(cerr);
|
|
cerr<< endl<< _first << " -> ("<< _second << ", "<< _edge<< ")"<< endl;
|
|
}
|
|
map<int, list< set< pair<int, int> > >::iterator>::iterator node_pos=
|
|
node_index.find(_first);
|
|
assertIf(node_pos != node_index.end());
|
|
|
|
list< set< pair<int, int> > >::iterator node_neighbors_it= (*node_pos).second;
|
|
unsigned int erased= (*node_neighbors_it).erase(make_pair(_second, _edge));
|
|
assertIf(erased==1);
|
|
|
|
if(remove_node_if_isolated(_first)) resCode=1;
|
|
if(remove_node_if_isolated(_second)) resCode+=2;
|
|
return resCode;//0 means that the edge removal removes zero nodes in the graph
|
|
//1 means that _first node is removed
|
|
//2 means that _second node is removed
|
|
//3 means that both _first and _second nodes are removed
|
|
}
|
|
|
|
int LWGraph::nodes_count()
|
|
{
|
|
assertIf(node_index.size() == neighbors.size());
|
|
return node_index.size();
|
|
}
|
|
|
|
int LWGraph::get_nodes(set<int>& res)
|
|
{
|
|
res.clear();
|
|
for(map<int, list< set< pair<int, int> > >::iterator>::iterator it=
|
|
node_index.begin(); it!= node_index.end(); ++it)
|
|
res.insert((*it).first);
|
|
assertIf(res.size() == node_index.size());
|
|
return 0;
|
|
}
|
|
|
|
vector< LWGraph* >* LWGraph::cluster()
|
|
{
|
|
vector< LWGraph* >* ress= new vector< LWGraph* >();
|
|
list<int> frontier;
|
|
set<int> already_added;
|
|
int curNode;
|
|
list< set< pair<int, int> > >::iterator curNodeNeighborsIt,
|
|
frontierNodeNeighborsIt;
|
|
set< pair<int, int> >* curNodeNeighbors, fromtierNodeNeighbors;
|
|
for(map<int, list< set< pair<int, int> > >::iterator>::iterator it=
|
|
node_index.begin(); it!= node_index.end(); ++it)
|
|
{
|
|
curNode= (*it).first;
|
|
if( already_added.find(curNode) != already_added.end()) continue;
|
|
frontier.push_back(curNode);
|
|
//already_added.insert(curNode);
|
|
LWGraph* res= new LWGraph();
|
|
|
|
while(!frontier.empty())
|
|
{
|
|
curNode= frontier.back();
|
|
frontier.pop_back();
|
|
if( already_added.find(curNode) != already_added.end()) continue;
|
|
already_added.insert(curNode);
|
|
curNodeNeighborsIt= node_index[curNode];
|
|
curNodeNeighbors= &(*curNodeNeighborsIt);
|
|
|
|
res->neighbors.push_back(*curNodeNeighbors);
|
|
list< set< pair<int, int> > >::iterator resNeighborsIt=
|
|
--res->neighbors.end();
|
|
res->node_index.insert(make_pair(curNode, resNeighborsIt));
|
|
for(set<pair<int,int> >::iterator nIt= curNodeNeighbors->begin(); nIt!=
|
|
curNodeNeighbors->end(); ++nIt)
|
|
frontier.push_front( (*nIt).first);
|
|
}
|
|
ress->push_back(res);
|
|
}
|
|
return ress;
|
|
}
|
|
|
|
vector< LWGraph* >* LWGraph::find_components_of(set<int>& _nodes)
|
|
{
|
|
vector< LWGraph* >* ress= new vector< LWGraph* >();
|
|
list<int> frontier;
|
|
set<int> already_added;
|
|
int curNode;
|
|
list< set< pair<int, int> > >::iterator curNodeNeighborsIt,
|
|
frontierNodeNeighborsIt;
|
|
set< pair<int, int> >* curNodeNeighbors, fromtierNodeNeighbors;
|
|
for(set<int>::iterator it= _nodes.begin(); it!= _nodes.end(); ++it)
|
|
{
|
|
curNode= *it;
|
|
if( already_added.find(curNode) != already_added.end()) continue;
|
|
frontier.push_back(curNode);
|
|
//already_added.insert(curNode);
|
|
LWGraph* res= new LWGraph();
|
|
|
|
while(!frontier.empty())
|
|
{
|
|
curNode= frontier.back();
|
|
frontier.pop_back();
|
|
if( already_added.find(curNode) != already_added.end()) continue;
|
|
already_added.insert(curNode);
|
|
curNodeNeighborsIt= node_index[curNode];
|
|
curNodeNeighbors= &(*curNodeNeighborsIt);
|
|
|
|
res->neighbors.push_back(*curNodeNeighbors);
|
|
list< set< pair<int, int> > >::iterator resNeighborsIt=
|
|
--res->neighbors.end();
|
|
res->node_index.insert(make_pair(curNode, resNeighborsIt));
|
|
for(set<pair<int,int> >::iterator nIt= curNodeNeighbors->begin(); nIt!=
|
|
curNodeNeighbors->end(); ++nIt)
|
|
frontier.push_front( (*nIt).first);
|
|
}
|
|
ress->push_back(res);
|
|
}
|
|
return ress;
|
|
}
|
|
|
|
ostream& LWGraph::print( ostream &os )
|
|
{
|
|
os<<endl;
|
|
for(map<int, list< set< pair<int, int> > >::iterator>::iterator it=
|
|
node_index.begin(); it!= node_index.end(); ++it)
|
|
{
|
|
os<< (*it).first<<" : ";
|
|
for(set< pair<int, int> >::iterator n= (*(*it).second).begin(); n!=
|
|
(*(*it).second).end(); ++n)
|
|
os<<"("<<(*n).first<<", "<< (*n).second<< "), ";
|
|
os<<endl;
|
|
}
|
|
os<< "\n node/component pairs:";
|
|
for(map< int, int >::iterator it=
|
|
node_component.begin(); it!= node_component.end(); ++it)
|
|
os<< "("<< (*it).first<<", " <<(*it).second<<")," ;
|
|
return os;
|
|
}
|
|
|
|
void InsertEdgesUndirected(
|
|
LWGraph* g, set<int>& edges, vector<pair<int,int> >& edge2nodes)
|
|
{
|
|
int edge;
|
|
pair<int, int> *edgeNodes;
|
|
for(set<int>::iterator it= edges.begin(); it!= edges.end(); ++it)
|
|
{
|
|
edge= *it;
|
|
edgeNodes= &edge2nodes[edge];
|
|
g->insert_edge_directed(edgeNodes, edge);
|
|
g->insert_edge_directed(edgeNodes->second, edgeNodes->first, edge);
|
|
}
|
|
}
|
|
|
|
void InsertEdgesUndirected(
|
|
LWGraph* g, set<int>& edges, vector<pair<int,int> >& edge2nodes,
|
|
set<int>& newNodes)
|
|
{
|
|
int resCode;
|
|
int edge;
|
|
pair<int, int> *edgeNodes;
|
|
newNodes.clear();
|
|
for(set<int>::iterator it= edges.begin(); it!= edges.end(); ++it)
|
|
{
|
|
edge= *it;
|
|
edgeNodes= &edge2nodes[edge];
|
|
resCode= g->insert_edge_directed(edgeNodes, edge);
|
|
g->insert_edge_directed(edgeNodes->second, edgeNodes->first, edge);
|
|
switch(resCode)
|
|
{
|
|
case 0: break;
|
|
case 1: newNodes.insert(edgeNodes->first); break;
|
|
case 2: newNodes.insert(edgeNodes->second); break;
|
|
case 3: {newNodes.insert(edgeNodes->second);
|
|
newNodes.insert(edgeNodes->first);}break;
|
|
default: assert(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
list<Component*>::iterator
|
|
GetComponentIt(list<Component*>* components, int label)
|
|
{
|
|
list<Component*>::iterator it= components->begin();
|
|
while((*it)->label != label && it != components->end()) ++it;
|
|
return it;
|
|
}
|
|
|
|
void FindComponentsOf(LWGraph* g, list<Component*>* components,
|
|
set<int>& newEdges, vector<pair<int,int> >& edge2nodes,
|
|
vector<NewComponent>& newComponents)
|
|
{
|
|
bool debugme= false;
|
|
if(debugme)
|
|
g->print(cerr);
|
|
newComponents.clear();
|
|
|
|
int edge;
|
|
pair<int, int> *edgeNodes;
|
|
set<int> nodes;
|
|
set<int> newNodes, curNewNodes;
|
|
set<int> affectedComponents, curAffectedComponents;
|
|
NewComponent* newComp;
|
|
|
|
for(set<int>::iterator it= newEdges.begin(); it!= newEdges.end(); ++it)
|
|
{
|
|
edge= *it;
|
|
edgeNodes= &edge2nodes[edge];
|
|
if(newNodes.find(edgeNodes->first) != newNodes.end()||
|
|
newNodes.find(edgeNodes->second) != newNodes.end()) continue;
|
|
curAffectedComponents.clear(); curNewNodes.clear();
|
|
ExpandInGraph(g, edgeNodes, curAffectedComponents, curNewNodes);
|
|
newNodes.insert(curNewNodes.begin(), curNewNodes.end());
|
|
affectedComponents.insert(
|
|
curAffectedComponents.begin(), curAffectedComponents.end());
|
|
newComponents.resize(newComponents.size() +1);
|
|
newComp= &newComponents.back();
|
|
newComp->affectedComponents.assign(
|
|
curAffectedComponents.begin(), curAffectedComponents.end());
|
|
newComp->newNodes= curNewNodes;
|
|
if(debugme)
|
|
newComp->Print(cerr);
|
|
}
|
|
MergeNewComponents(newComponents, affectedComponents);
|
|
}
|
|
|
|
void ExpandInGraph(LWGraph* graph, pair<int, int>* edgeNodes,
|
|
set<int>& affectedComponents, set<int>& newNodes)
|
|
{
|
|
set<int> frontier;
|
|
set<int> already_added;
|
|
frontier.insert(edgeNodes->first);
|
|
frontier.insert(edgeNodes->second);
|
|
int curNode;
|
|
map<int,list< set< pair<int, int> > >::iterator>::iterator nodeIndexIt;
|
|
list< set< pair<int, int> > >::iterator curNodeNeighborsIt;
|
|
set< pair<int, int> >* curNodeNeighbors;
|
|
while (!frontier.empty())
|
|
{
|
|
curNode = *(frontier.begin());
|
|
frontier.erase(frontier.begin());
|
|
if(already_added.find(curNode)!= already_added.end()) continue;
|
|
already_added.insert(curNode);
|
|
map<int, int>::iterator nodeComp= graph->node_component.find(curNode);
|
|
if(nodeComp != graph->node_component.end())
|
|
affectedComponents.insert((*nodeComp).second);
|
|
else
|
|
{
|
|
newNodes.insert(curNode);
|
|
nodeIndexIt= graph->node_index.find(curNode);
|
|
assertIf(nodeIndexIt != graph->node_index.end());
|
|
curNodeNeighborsIt= (*nodeIndexIt).second;
|
|
curNodeNeighbors= &(*curNodeNeighborsIt);
|
|
for(set<pair<int,int> >::iterator nIt= curNodeNeighbors->begin(); nIt!=
|
|
curNodeNeighbors->end(); ++nIt)
|
|
frontier.insert( (*nIt).first);
|
|
}
|
|
}
|
|
}
|
|
|
|
/*
|
|
Given a vector (newComponents), where an element $v_i \in $newComponent is a
|
|
set of integers $s_i$. And given a set of integers (affectedComponents). Merge
|
|
together every $v_i, v_j$, where $s_i \cap s_j \cap $affectedComponents.
|
|
|
|
*/
|
|
|
|
void MergeNewComponents(vector<NewComponent>& newComponents,
|
|
set<int>& affectedComponents)
|
|
{
|
|
bool debugme= false;
|
|
if(debugme)
|
|
{
|
|
cerr<<"\n affectedComponents: ";
|
|
PrintSet(affectedComponents, cerr);
|
|
cerr<<"\n newComponents: ";
|
|
for(vector<NewComponent>::iterator it= newComponents.begin(); it!=
|
|
newComponents.end(); ++it)
|
|
(*it).Print(cerr);
|
|
}
|
|
if(newComponents.size() <= 1) return;
|
|
vector<NewComponent> mergedComponents;
|
|
vector<int> intersectingNewComponents;
|
|
for(set<int>::iterator it= affectedComponents.begin(); it!=
|
|
affectedComponents.end(); ++it)
|
|
{
|
|
intersectingNewComponents.clear();
|
|
for(unsigned int i=0; i<newComponents.size(); ++i)
|
|
if(newComponents[i].AffectsComponent(*it))
|
|
intersectingNewComponents.push_back(i);
|
|
|
|
assertIf(!intersectingNewComponents.empty());
|
|
if(intersectingNewComponents.size() == 1) continue;
|
|
NewComponent bigComp= newComponents[intersectingNewComponents[0]];
|
|
for(size_t j= 1; j< intersectingNewComponents.size(); ++j)
|
|
bigComp.Union(newComponents[intersectingNewComponents[j]]);
|
|
|
|
for(int j= intersectingNewComponents.size() -1; j>=0 ; --j)
|
|
newComponents.erase(newComponents.begin() + intersectingNewComponents[j]);
|
|
|
|
newComponents.push_back(bigComp);
|
|
if(newComponents.size() == 1) return;
|
|
}
|
|
}
|
|
|
|
void RemoveEdgesUndirected(
|
|
LWGraph* g, set<int>& edges, vector<pair<int,int> >& edge2nodes)
|
|
{
|
|
int edge;
|
|
pair<int, int> *edgeNodes;
|
|
for(set<int>::iterator it= edges.begin(); it!= edges.end(); ++it)
|
|
{
|
|
edge= *it;
|
|
edgeNodes= &edge2nodes[edge];
|
|
g->remove_edge_directed(*edgeNodes, edge);
|
|
g->remove_edge_directed(edgeNodes->second, edgeNodes->first, edge);
|
|
}
|
|
}
|
|
|
|
void RemoveEdgesUndirected(
|
|
LWGraph* g, set<int>& edges, vector<pair<int,int> >& edge2nodes,
|
|
set<int>& removedNodes)
|
|
{
|
|
int edge;
|
|
int resCode;
|
|
pair<int, int> *edgeNodes;
|
|
removedNodes.clear();
|
|
for(set<int>::iterator it= edges.begin(); it!= edges.end(); ++it)
|
|
{
|
|
edge= *it;
|
|
edgeNodes= &edge2nodes[edge];
|
|
g->remove_edge_directed(*edgeNodes, edge);
|
|
resCode= g->remove_edge_directed(edgeNodes->second, edgeNodes->first, edge);
|
|
switch(resCode)
|
|
{
|
|
case 0: break;
|
|
case 1: removedNodes.insert(edgeNodes->second); break;
|
|
case 2: removedNodes.insert(edgeNodes->first); break;
|
|
case 3: {removedNodes.insert(edgeNodes->second);
|
|
removedNodes.insert(edgeNodes->first);}break;
|
|
default: assert(0);
|
|
}
|
|
}
|
|
}
|
|
|
|
int RemoveEdgeUndirected(LWGraph* g, int edge, pair<int,int>* edgeNodes)
|
|
{
|
|
g->remove_edge_directed(*edgeNodes, edge);
|
|
return(g->remove_edge_directed(edgeNodes->second, edgeNodes->first, edge));
|
|
}
|
|
|
|
void SetGraphNodesComponent(LWGraph* g, set<int>& nodes, int label)
|
|
{
|
|
for(set<int>::iterator nodeIt= nodes.begin(); nodeIt!= nodes.end(); ++nodeIt)
|
|
{
|
|
assertIf(g->node_component.find(*nodeIt) == g->node_component.end());
|
|
g->node_component.insert(make_pair(*nodeIt, label));
|
|
}
|
|
}
|
|
|
|
void RemoveGraphNodesComponent(LWGraph* g, set<int>& nodes)
|
|
{
|
|
map<int, int>::iterator pos;
|
|
|
|
for(set<int>::iterator nodeIt= nodes.begin(); nodeIt!=
|
|
nodes.end(); ++nodeIt)
|
|
{
|
|
pos= g->node_component.find(*nodeIt);
|
|
assertIf(pos != g->node_component.end());
|
|
g->node_component.erase(pos);
|
|
}
|
|
}
|
|
|
|
void UpdateGraphNodesComponent(LWGraph* g, set<int>& nodes, int label)
|
|
{
|
|
map<int, int>::iterator pos;
|
|
for(set<int>::iterator nodeIt= nodes.begin(); nodeIt!=
|
|
nodes.end(); ++nodeIt)
|
|
{
|
|
pos= g->node_component.find(*nodeIt);
|
|
assertIf(pos != g->node_component.end());
|
|
(*pos).second= label;
|
|
}
|
|
}
|
|
|
|
int FindEdgeComponent(LWGraph* g, pair<int, int>* _edge)
|
|
{
|
|
map<int, int>::iterator pos1= g->node_component.find(_edge->first),
|
|
pos2= g->node_component.find(_edge->second);;
|
|
if(pos1 == g->node_component.end() && pos2 == g->node_component.end())
|
|
return -1;
|
|
|
|
int comp1= (*pos1).second;
|
|
int comp2= (*pos2).second;
|
|
assertIf(comp1 == comp2);
|
|
return comp1;
|
|
}
|
|
|
|
ostream& PrintSet( set<int>& arg, ostream &os )
|
|
{
|
|
for(set<int>::iterator it= arg.begin(); it!= arg.end(); ++it)
|
|
os<< *it<<", ";
|
|
return os;
|
|
}
|
|
|
|
ostream& PrintVector( vector<int>& arg, ostream &os )
|
|
{
|
|
for(vector<int>::iterator it= arg.begin(); it!= arg.end(); ++it)
|
|
os<< *it<<", ";
|
|
return os;
|
|
}
|
|
|
|
bool HasOneComponent(set<int> edges, vector<pair<int,int> >& edge2nodes)
|
|
{
|
|
bool debugme=false;
|
|
bool res=false;
|
|
LWGraph* graph= new LWGraph();
|
|
InsertEdgesUndirected(graph, edges, edge2nodes);
|
|
vector< LWGraph* >* comps= graph->cluster();
|
|
if(comps->size()==1) res= true;
|
|
else
|
|
{
|
|
if(debugme)
|
|
{
|
|
cerr<<"\nThe graph is:\n";
|
|
graph->print(cerr);
|
|
for(vector< LWGraph* >::iterator it= comps->begin(); it!= comps->end();
|
|
++it)
|
|
{
|
|
cerr<<"\nFound Component:\n";
|
|
(*it)->print(cerr);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
for(vector< LWGraph* >::iterator it= comps->begin(); it!= comps->end(); ++it)
|
|
delete *it;
|
|
delete comps;
|
|
return res;
|
|
}
|
|
|
|
bool IsOneComponent(mset::CompressedMSet* _mset, int n,
|
|
vector<pair<int,int> >& edge2nodes)
|
|
{
|
|
set<int> lastSet;
|
|
mset::CompressedInMemUSet uset;
|
|
mset::CompressedUSetRef unitRef;
|
|
int elem, cnt;
|
|
set<int> toAdd, toRemove;
|
|
int i= 0;
|
|
int size= _mset->units.Size();
|
|
for(; i< size; ++i)
|
|
{
|
|
_mset->units.Get( i, unitRef );
|
|
toAdd.clear(); toRemove.clear();
|
|
for(int j=unitRef.addedstart; j<= unitRef.addedend; ++j)
|
|
{
|
|
_mset->added.Get(j, elem);
|
|
lastSet.insert(elem);
|
|
}
|
|
for(int j=unitRef.removedstart; j<= unitRef.removedend; ++j)
|
|
{
|
|
_mset->removed.Get(j, elem);
|
|
lastSet.erase(elem);
|
|
}
|
|
cnt= lastSet.size();
|
|
assertIf(cnt == unitRef.count);
|
|
if(! HasOneComponent(lastSet, edge2nodes))
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
int GetNumComponents(
|
|
set<int>& edges, int n, vector< pair<int,int> > & edge2nodes)
|
|
{
|
|
//bool debugme=false;
|
|
int numComps=0;
|
|
LWGraph* graph= new LWGraph();
|
|
InsertEdgesUndirected(graph, edges, edge2nodes);
|
|
vector< LWGraph* >* comps= graph->cluster();
|
|
for(unsigned int i=0; i< comps->size(); ++i)
|
|
{
|
|
if((*comps)[i]->nodes_count() >= n) ++numComps;
|
|
delete (*comps)[i];
|
|
}
|
|
comps->clear();
|
|
delete comps;
|
|
delete graph;
|
|
return numComps;
|
|
}
|
|
|
|
bool SetIntersects(set<int>* set1, set<int>* set2)
|
|
{
|
|
if(set1->empty() || set2->empty()) return false;
|
|
set<int>::iterator first1= set1->begin(),
|
|
first2= set2->begin(),
|
|
last1 = --set1->end(),
|
|
last2 = --set2->end();
|
|
|
|
if( (*last1 < *first2) || (*last2 < *first1) ) return false;
|
|
++last1; ++last2;
|
|
|
|
while (first1 != last1 && first2 != last2)
|
|
{
|
|
if (*first1 < *first2)
|
|
++first1;
|
|
else if (*first2 < *first1)
|
|
++first2;
|
|
else return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
}
|