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