annotate src/graph_helpers.hpp @ 0:add35537fdbb tip

Initial import
author irh <ian.r.hobson@gmail.com>
date Thu, 25 Aug 2011 11:05:55 +0100
parents
children
rev   line source
ian@0 1 // Copyright 2011, Ian Hobson.
ian@0 2 //
ian@0 3 // This file is part of gpsynth.
ian@0 4 //
ian@0 5 // gpsynth is free software: you can redistribute it and/or modify
ian@0 6 // it under the terms of the GNU General Public License as published by
ian@0 7 // the Free Software Foundation, either version 3 of the License, or
ian@0 8 // (at your option) any later version.
ian@0 9 //
ian@0 10 // gpsynth is distributed in the hope that it will be useful,
ian@0 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
ian@0 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ian@0 13 // GNU General Public License for more details.
ian@0 14 //
ian@0 15 // You should have received a copy of the GNU General Public License
ian@0 16 // along with gpsynth in the file COPYING.
ian@0 17 // If not, see http://www.gnu.org/licenses/.
ian@0 18
ian@0 19 // Some helper functions for boost.graph
ian@0 20
ian@0 21 #pragma once
ian@0 22
ian@0 23 #include "boost/graph/adjacency_list.hpp"
ian@0 24 #include "boost/tuple/tuple.hpp"
ian@0 25
ian@0 26 // removes the tree starting at the specified edge from the graph
ian@0 27 template<typename GRAPH>
ian@0 28 void RemoveSubTree(typename boost::graph_traits<GRAPH>::edge_descriptor edge,
ian@0 29 GRAPH& graph) {
ian@0 30 typename boost::graph_traits<GRAPH>::vertex_descriptor source;
ian@0 31 typename boost::graph_traits<GRAPH>::vertex_descriptor target;
ian@0 32 source = boost::source(edge, graph);
ian@0 33 target = boost::target(edge, graph);
ian@0 34 // avoid iteration as removing edges invalidates iterators
ian@0 35 while (boost::in_degree(source, graph) > 0) {
ian@0 36 RemoveSubTree(*(boost::in_edges(source, graph).first), graph);
ian@0 37 }
ian@0 38 boost::remove_edge(source, target, graph);
ian@0 39 boost::remove_vertex(source, graph);
ian@0 40 }
ian@0 41
ian@0 42 // removes the tree starting at the specified vertex from the graph
ian@0 43 template<typename T>
ian@0 44 void RemoveSubTree(typename boost::graph_traits<T>::vertex_descriptor vertex,
ian@0 45 T& graph) {
ian@0 46 // avoid iteration as removing edges invalidates iterators
ian@0 47 while (boost::in_degree(vertex, graph) > 0) {
ian@0 48 RemoveSubTree(*(boost::in_edges(vertex, graph).first), graph);
ian@0 49 }
ian@0 50 boost::remove_vertex(vertex, graph);
ian@0 51 }
ian@0 52
ian@0 53 // inserts the subtree identified by source in to target_graph
ian@0 54 // returns the root vertex of the inserted subtree
ian@0 55 template<typename GRAPH>
ian@0 56 typename boost::graph_traits<GRAPH>::vertex_descriptor
ian@0 57 InsertSubTree(typename boost::graph_traits<GRAPH>::vertex_descriptor source,
ian@0 58 const GRAPH& source_graph,
ian@0 59 GRAPH& target_graph) {
ian@0 60 typedef typename boost::graph_traits<GRAPH>::vertex_descriptor Vertex;
ian@0 61 typedef typename boost::graph_traits<GRAPH>::in_edge_iterator InEdge;
ian@0 62 Vertex new_vertex = boost::add_vertex(source_graph[source], target_graph);
ian@0 63 InEdge in_edge;
ian@0 64 InEdge in_edges_end;
ian@0 65 boost::tie(in_edge, in_edges_end) = boost::in_edges(source, source_graph);
ian@0 66 while (in_edge != in_edges_end) {
ian@0 67 Vertex input = InsertSubTree(boost::source(*in_edge, source_graph),
ian@0 68 source_graph,
ian@0 69 target_graph);
ian@0 70 boost::add_edge(input, new_vertex, source_graph[*in_edge], target_graph);
ian@0 71 ++in_edge;
ian@0 72 }
ian@0 73 return new_vertex;
ian@0 74 }
ian@0 75
ian@0 76 // SwapSubTrees - swaps the subtrees starting at node_1 and node_2
ian@0 77 // writing to graphs passed in as targets
ian@0 78 template<typename GRAPH>
ian@0 79 void SwapSubTrees(typename boost::graph_traits<GRAPH>::vertex_descriptor node_1,
ian@0 80 typename boost::graph_traits<GRAPH>::vertex_descriptor node_2,
ian@0 81 const GRAPH& source_1, const GRAPH& source_2,
ian@0 82 GRAPH& target_1, GRAPH& target_2) {
ian@0 83
ian@0 84 typedef typename boost::graph_traits<GRAPH>::vertex_descriptor Vertex;
ian@0 85 typedef typename boost::graph_traits<GRAPH>::edge_descriptor Edge;
ian@0 86 // copy sources to targets
ian@0 87 target_1 = source_1;
ian@0 88 target_2 = source_2;
ian@0 89 // get connecting output edges
ian@0 90 Edge edge_1 = *(boost::out_edges(node_1, source_1).first);
ian@0 91 Edge edge_2 = *(boost::out_edges(node_2, source_2).first);
ian@0 92 // get connecting nodes on other end of outputs
ian@0 93 Vertex target_node_1 = boost::target(edge_1, source_1);
ian@0 94 Vertex target_node_2 = boost::target(edge_2, source_2);
ian@0 95 // delete subtrees
ian@0 96 RemoveSubTree(edge_1, target_1);
ian@0 97 RemoveSubTree(edge_2, target_2);
ian@0 98 // insert copies of subtrees in opposing target graphs
ian@0 99 Vertex new_node_1 = InsertSubTree(node_2, source_2, target_1);
ian@0 100 Vertex new_node_2 = InsertSubTree(node_1, source_1, target_2);
ian@0 101 // connect the new subtrees using the same edge properties as old connection
ian@0 102 boost::add_edge(new_node_1, target_node_1, source_1[edge_1], target_1);
ian@0 103 boost::add_edge(new_node_2, target_node_2, source_2[edge_2], target_2);
ian@0 104 }