1 // Copyright 2004 The Trustees of Indiana University.
3 // Use, modification and distribution is subject to the Boost Software
4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
7 // Authors: Douglas Gregor
9 #include <boost/graph/fruchterman_reingold.hpp>
10 #include <boost/graph/random_layout.hpp>
11 #include <boost/graph/adjacency_list.hpp>
12 #include <boost/graph/topology.hpp>
13 #include <boost/lexical_cast.hpp>
18 #include <boost/random/linear_congruential.hpp>
19 #include <boost/progress.hpp>
20 #include <boost/shared_ptr.hpp>
22 using namespace boost
;
26 std::cerr
<< "Usage: fr_layout [options] <width> <height>\n"
28 << "\t<width>\tWidth of the display area (floating point)\n"
29 << "\t<Height>\tHeight of the display area (floating point)\n\n"
31 << "\t--iterations n\tNumber of iterations to execute.\n"
32 << "\t\t\tThe default value is 100.\n"
34 << " Input is read from standard input as a list of edges, one per line.\n"
35 << " Each edge contains two string labels (the endpoints) separated by a space.\n\n"
37 << " Vertices and their positions are written to standard output with the label,\n x-position, and y-position of a vertex on each line, separated by spaces.\n";
40 typedef boost::rectangle_topology
<> topology_type
;
41 typedef topology_type::point_type point_type
;
43 typedef adjacency_list
<listS
, vecS
, undirectedS
,
44 property
<vertex_name_t
, std::string
> > Graph
;
46 typedef graph_traits
<Graph
>::vertex_descriptor Vertex
;
48 typedef std::map
<std::string
, Vertex
> NameToVertex
;
50 Vertex
get_vertex(const std::string
& name
, Graph
& g
, NameToVertex
& names
)
52 NameToVertex::iterator i
= names
.find(name
);
54 i
= names
.insert(std::make_pair(name
, add_vertex(name
, g
))).first
;
58 class progress_cooling
: public linear_cooling
<double>
60 typedef linear_cooling
<double> inherited
;
63 explicit progress_cooling(std::size_t iterations
) : inherited(iterations
)
65 display
.reset(new progress_display(iterations
+ 1, std::cerr
));
71 return inherited::operator()();
75 shared_ptr
<boost::progress_display
> display
;
78 int main(int argc
, char* argv
[])
82 if (argc
< 3) { usage(); return -1; }
87 for (int arg_idx
= 1; arg_idx
< argc
; ++arg_idx
) {
88 std::string arg
= argv
[arg_idx
];
89 if (arg
== "--iterations") {
91 if (arg_idx
>= argc
) { usage(); return -1; }
92 iterations
= lexical_cast
<int>(argv
[arg_idx
]);
94 if (width
== 0.0) width
= lexical_cast
<double>(arg
);
95 else if (height
== 0.0) height
= lexical_cast
<double>(arg
);
103 if (width
== 0.0 || height
== 0.0) {
111 std::string source
, target
;
112 while (std::cin
>> source
>> target
) {
113 add_edge(get_vertex(source
, g
, names
), get_vertex(target
, g
, names
), g
);
116 typedef std::vector
<point_type
> PositionVec
;
117 PositionVec
position_vec(num_vertices(g
));
118 typedef iterator_property_map
<PositionVec::iterator
,
119 property_map
<Graph
, vertex_index_t
>::type
>
121 PositionMap
position(position_vec
.begin(), get(vertex_index
, g
));
124 topology_type
topo(gen
, -width
/2, -height
/2, width
/2, height
/2);
125 random_graph_layout(g
, position
, topo
);
126 fruchterman_reingold_force_directed_layout
128 cooling(progress_cooling(iterations
)));
130 graph_traits
<Graph
>::vertex_iterator vi
, vi_end
;
131 for (boost::tie(vi
, vi_end
) = vertices(g
); vi
!= vi_end
; ++vi
) {
132 std::cout
<< get(vertex_name
, g
, *vi
) << '\t'
133 << position
[*vi
][0] << '\t' << position
[*vi
][1] << std::endl
;