DepGraph.cc
/*
* Copyright (C) 2014 Mario Alviano (mario@alviano.net)
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include "DepGraph.h"
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/strong_components.hpp>
#include <vector>
#include <iostream>
using std::vector;
using std::cout;
using std::endl;
namespace aspino {
class AdjacencyList: public boost::adjacency_list<>
{
};
DepGraph::DepGraph()
: arcs(*new AdjacencyList()) {
}
DepGraph::~DepGraph() {
delete &arcs;
}
void DepGraph::add(int node) {
assert(node >= 0);
boost::add_edge(node + 1, 0, arcs);
}
void DepGraph::add(int from, int to) {
assert(from != to);
assert(from >= 0);
assert(to >= 0);
boost::add_edge(from + 1, to + 1, arcs);
}
void DepGraph::sccs(vec<int>& atom2comp, vec<vec<int> >& components, bool& tight) {
vector<int> sccs(boost::num_vertices(arcs)), discover_time(boost::num_vertices(arcs));
vector<boost::default_color_type> color(boost::num_vertices(arcs));
vector<boost::graph_traits<boost::adjacency_list<> >::vertex_descriptor> root(boost::num_vertices(arcs));
int n = boost::strong_components(arcs, &sccs[0] , boost::root_map(&root[0]).color_map(&color[0]).discover_time_map(&discover_time[0]));
tight = true;
components.clear();
if(n == 0) return;
components.growTo(n-1);
assert(sccs[0] == 0);
for(int i = 1; i < static_cast<int>(sccs.size()); i++) {
int scc = sccs[i] - 1;
assert(scc >= 0);
assert(scc < components.size());
atom2comp[i-1] = scc;
components[scc].push(i-1);
if(components[scc].size() > 1) tight = false;
}
}
class WeightedAdjacencyList : public boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, boost::no_property, boost::property<boost::edge_weight_t, unsigned> > {};
UndirectedWeightedGraph::UndirectedWeightedGraph()
: arcs(*new WeightedAdjacencyList()) {
}
UndirectedWeightedGraph::~UndirectedWeightedGraph() {
delete &arcs;
}
void UndirectedWeightedGraph::add(int node) {
assert(node >= 0);
boost::add_edge(node + 1, 0, 1, arcs);
}
void UndirectedWeightedGraph::add(int from, int to) {
assert(from != to);
assert(from >= 0);
assert(to >= 0);
std::pair<WeightedAdjacencyList::edge_descriptor, bool> edge = boost::edge(from + 1, to + 1, arcs);
if(edge.second) {
int weight = get(boost::edge_weight_t(), arcs, edge.first);
boost::put(boost::edge_weight_t(), arcs, edge.first, weight + 1);
edge = boost::edge(to + 1, from + 1, arcs);
assert(edge.second);
boost::put(boost::edge_weight_t(), arcs, edge.first, weight + 1);
}
else {
boost::add_edge(from + 1, to + 1, 1, arcs);
boost::add_edge(to + 1, from + 1, 1, arcs);
}
}
void UndirectedWeightedGraph::remove(int from, int to) {
assert(from != to);
assert(from >= 0);
assert(to >= 0);
std::pair<WeightedAdjacencyList::edge_descriptor, bool> edge = boost::edge(from + 1, to + 1, arcs);
assert(edge.second);
int weight = get(boost::edge_weight_t(), arcs, edge.first) - 1;
if(weight == 0) {
boost::remove_edge(from + 1, to + 1, arcs);
boost::remove_edge(to + 1, from + 1, arcs);
}
else {
boost::put(boost::edge_weight_t(), arcs, edge.first, weight);
edge = boost::edge(to + 1, from + 1, arcs);
assert(edge.second);
boost::put(boost::edge_weight_t(), arcs, edge.first, weight);
}
}
void UndirectedWeightedGraph::sccs(vec<int>& atom2comp, vec<vec<int> >& components) {
vector<int> sccs(boost::num_vertices(arcs)), discover_time(boost::num_vertices(arcs));
vector<boost::default_color_type> color(boost::num_vertices(arcs));
vector<boost::graph_traits<boost::adjacency_list<> >::vertex_descriptor> root(boost::num_vertices(arcs));
int n = boost::strong_components(arcs, &sccs[0] , boost::root_map(&root[0]).color_map(&color[0]).discover_time_map(&discover_time[0]));
components.clear();
if(n == 0) return;
components.growTo(n-1);
assert(sccs[0] == 0);
for(unsigned i = 1; i < sccs.size(); i++) {
int scc = sccs[i] - 1;
assert(scc >= 0);
assert(scc < components.size());
atom2comp[i-1] = scc;
components[scc].push(i-1);
}
}
} // namespace aspino