# 有限状态机与行为树的C++学习与实践sudo apt-get install libxmu-dev sudo apt-get install libxmu-dev libxi-dev

git clone https://github.com/jll63/yomm11.git

http://www.aisharing.com/

http://www.aisharing.com/archives/90

http://chsm.sourceforge.net/

http://www.cplusplus.com/forum/general/141582/

https://github.com/miccol/Behavior-Tree

https://github.com/miccol/ROS-Behavior-Tree

https://www.codeproject.com/articles/1734/tree-data-class-for-c

http://docs.cryengine.com/display/SDKDOC4/Behavior+Trees

http://codearea.in/program-to-implement-b-tree-in-c/

http://docs.cryengine.com/display/SDKDOC4/Behavior+Trees

http://www.cnblogs.com/bastard/archive/2012/02/02/2336150.html

# Decorator模式——设计模式学习笔记

https://stackoverflow.com/questions/37615083/boost-and-graphviz

http://www.poirrier.be/~jean-etienne/articles/graphviz/

# GraphViz and C++

http://collaboration.cmc.ec.gc.ca/science/rpn/biblio/ddj/Website/articles/CUJ/2005/0512/0512platis/0512platis.html

C/C++ Users Journal December, 2005

## Drawing directed and undirected graphs

### By Nikos Platis and Mihalis Tsoukalos

Nikos Platis holds a Ph.D. in computer science from the University of Athens, Greece. His research interests are in multiresolution methods for computer graphics. He can be reached at nplatis@di.uoa.gr. Mihalis Tsoukalos holds a B.S. in mathematics from the University of Patras in Greece and an M.S. in IT from the University College, London. His research interests are in DBMS. He can be reached at tsoukalos@sch.gr.

GraphViz is a software package for drawing directed and undirected graphs [1]. Developed by AT&T [2], GraphViz is mainly written in C, although newer parts are written in C++ and Java. Bindings for GraphViz exist in many high-level languages. For C++, mfgraph [6] is a simple binding to dot, the GraphViz language, although it appears unmaintained. A more recent binding is contained in the Boost Graph Library (BGL) [7]. The BGL offers a generic interface for representing and manipulating graphs, so its connection to GraphViz is natural. In this article, we present examples of using the BGL to create GraphViz graphs. Although there are graphical tools based on GraphViz that can graphically create graphs, in this article we focus on command-line tools in combination with C++. We use GraphViz 2.0, g++ 3.4.1, and Boost 1.32.0.

There are three major programs for creating graphs, all of which use the dot language:

• dot is a utility program for drawing directed graphs [5].
• NEATO is a utility program for drawing undirected graphs. This kind of graph is commonly used in telecommunications and computer programming. NEATO uses an implementation of the Kamada-Kawai algorithm for "symmetric" layouts [4].
• twopi can draw graphs using a circular layout. One of the nodes is chosen as the center, and the other nodes are placed around the center node in a circular way. If a node is connected to the center node, it is placed at distance 1; if a node is connected to a node that is directly connected to the center node, it is placed at distance 2, and so on.

A graph contains nodes and edges, each of them having attributes. Table 1 shows some of the available attributes for dot nodes, while Table 2 shows part of the available edge attributes. There are also attributes for the graph that are not mentioned here. Similar attributes exist for the NEATO program.

Before getting the output of a GraphViz source file, the source file should be compiled. The general form of execution is:

toolname -Tps ftc.dot -o output.ps
where toolname denotes the name of the tool to execute (dot, NEATO, or twopi); -Tps denotes that the output file is in PostScript (other supported output formats are GIF, PNG, JPEG, HP-GL/2 vector format, VRML, and FrameMaker MIF); ftc.dot shows the name of the file to be processed; and -o output.ps tells what the output filename should be.



To illustrate how you can use the GraphViz language, we start with the familiar "Hello world!" example. This code produces the output in Figure 1:

digraph G
{
"Hello world!";
}



while this command produces the PostScript file for Figure 1:

dot -Tps hw.dot -o hw.ps



The word digraph means that a directed graph is going to be created. For creating an undirected graph, use the word graph instead.

Listing 1 is dot code to draw the hash table in Figure 2. The command rankdir = LR denotes that the graph nodes are going to be drawn from left to right. The command node [shape=record, width=.1, height=.1] defines some node attributes. The {} characters inside the label parameter of the nodes tell the dot language to arrange the record parts left to right instead of one above another. Commands of the type nd0:p2 -> nd6:e create the connections between the nodes (the edges of the graph). The command that produces Figure 2 is:

dot -Tps hashtable.dot -o hashtable.ps



### Integrating GraphViz and C++

The BGL contains an interface to the dot language. The function read_graphviz(fname, g) can be used to construct a BGL graph g from its representation in the .dot file with the given filename, and the function write_graphviz(fname, g) writes a BGL graph g in dot language in the given file. The graph g that can be used in these functions must be of the specific type boost::GraphvizGraph or boost::GraphvizDigraph, for undirected and directed graphs, respectively. These types carry node and edge attributes in a form suitable for expression in the dot language, namely as pairs of std::string(s), where the first string is the dot attribute name (for instance, shape) and the second one is the attribute value (box, for example). These attributes are accessed through attribute maps (they really are multimaps, in STL terms), which map a vertex to its attributes.

Suppose you want to draw a graph representing the directory structure of a filesystem. In this graph, the nodes will be the directories of the filesystem, and the (directed) edges will connect each directory to its subdirectories. The traversal of the directory hierarchy can be performed in a simple and portable way with the help of the Boost Filesystem Library. Listing 2 is our program.

The hierarchy traversal starts at a given path. For each subdirectory encountered, a node is added to the graph labeled with its name, and an edge connects it with its parent directory. The process continues recursively, until either no more subdirectories exist or a maximum recursion depth is reached.

The resulting file must be processed with dot to produce the graphical representation of the directory tree. Unfortunately, for deep and involved hierarchies, the graph produced can be very complex. Figure 3 presents a sample directory structure visualized as a graph.

Another example is a sparse matrix, which is a matrix in which most values are equal to zero. To reduce storage costs, such matrices are represented by storing only the values and coordinates of their non-zero elements. One interface to sparse matrices is provided by uBLAS, the Boost Basic Linear Algebra Library. uBLAS provides different storage models for the sparse matrices, each of them suitable for different access patterns. Typical of C++, their interface is identical, and for this example we use the class sparse_matrix. Iteration through the matrix elements is provided by two iterator classes for the rows and columns of the matrix, respectively.

Listing 3 presents functions for the row-major and column-major traversal of the tables. Let us describe the first one briefly, which creates a row-major graph representation of a sparse matrix. A node is created for each row (a "row head"), labeled with its number. Then, for each element of that row, a node is created, labeled with the column number of the element and its value; these nodes are shaped as dot "records" so that they can be subdivided into two fields, just like the nodes of the aforementioned hash table. Figure 4 is a graph representation of a sparse matrix; Figure 5 is the graph representation of the same sparse matrix.

### Conclusion

GraphViz is a useful set of tools for drawing both directed and undirected graphs. It offers great flexibility either alone or combined with C++ with the help of the Boost Graph Library. In this article, we presented examples that demonstrate how various data structures can be represented as graphs in the BGL and visualized with GraphViz. More advanced uses of the Boost GraphViz C++ interface are possible, which will require more complex handling of the graph structure.

### References

1. GraphViz development web site: http://www.graphviz.org/.
2. Official GraphViz web site: http://www.research.att.com/sw/tools/ graphviz/.
3. Junger, Michael and Petra Mutzel (editors). Graph Drawing Software, Mathematics + Visualization, Springer, ISBN 3540008810.
4. Kamada, T. and S. Kawai. "An Algorithm for Drawing General Undirected Graphs," Information Processing Letters, April 1989.
5. Gansner, Emden R., Eleftherios Koutsofios, Stephen C. North, and Kiem-Phong Vo. "A Technique for Drawing Directed Graphs," IEEE Trans. Software Engineering, May 1993.
6. http://www.geocities.com/foetsch/mfgraph/index.htm.
7. Boost Library web site: http://www.boost.org/.
##### CUJ

csnafu

#include <stdio.h>

#include <graphviz/gvc.h>
#ifdef WITH_CGRAPH
# include <graphviz/cgraph.h>
#else
# include <graphviz/graph.h>
#endif

int main(int argc, char **argv)
{
GVC_t *gvc;
Agraph_t *g;
Agnode_t *t, *h;

#ifdef WITH_CGRAPH
g = agopen("test", Agdirected, NULL);
printf("agopen %p\n", g);
t = agnode(g, "a", 1);
h = agnode(g, "b", 1);
agedge(g, t, h, "x", 1);
#else
aginit();
g = agopen("test", AGDIGRAPH);
printf("agopen %p\n", g);
t = agnode(g, "a");
h = agnode(g, "b");
agedge(g, t, h);
#endif

FILE *f = fopen("foo.dot", "w");
agwrite(g, f);
fclose(f);
agclose(g);

gvc = gvContext();
printf("gvContext %p\n", gvc);
gvLayout(gvc, g, "dot");
printf("gvLayout\n");

return 0;
}

************************************************************************************8

$pkg-config libcgraph --cflags --libs -I/usr/include/graphviz -lcgraph -lcdt$ pkg-config libgvc --cflags --libs
-I/usr/include/graphviz  -lgvc -lgraph -lcdt
$gcc foo.c -o foo -DWITH_CGRAPH pkg-config libcgraph libgvc --cflags --libs$ ./foo
agopen 0x956d050
Segmentation fault (core dumped)
---

I've been trying to resolve this for hours now and couldn't find anything useful. All posts and tutorials I can find are all using libcgraph or libgraph only and not also libgvc.

libgvc requires libgraph but even if I rewrite the program to use libgraph it crashes (although then it crahes at gvLayout).
Does anybody know how this stuff works? I've only done my first graphviz stuff today so I'm not too familiar with all this.

Code:
$uname -a Linux mybox 3.2.0-32-generic #51-Ubuntu SMP Wed Sep 26 21:32:50 UTC 2012 i686 i686 i386 GNU/Linux$ dpkg -l | grep -E "libgraph|libcgraph|libgvc|libcdt"
ii  libcdt4                                2.26.3-10ubuntu1                           rich set of graph drawing tools - cdt library
ii  libcgraph5                             2.26.3-10ubuntu1                           rich set of graph drawing tools - cgraph library
ii  libgraph4                              2.26.3-10ubuntu1                           rich set of graph drawing tools - graph library
ii  libgraphicsmagick3                     1.3.12-1.1build1                           format-independent image processing - C shared library
ii  libgraphviz-dev                        2.26.3-10ubuntu1                           graphviz libs and headers against which to build applications
ii  libgvc5                                2.26.3-10ubuntu1                           rich set of graph drawing tools - gvc library

First Cup of Ubuntu
Join Date
Jun 2012
Beans
3

## Re: Graphviz using gvc and cgraph in one program

Could at least someone compile this and tell me if it segfaults for him as well?

Iced Almond Soy Ubuntu, No Foam
Join Date
Feb 2006
Beans
1,086
Distro
Ubuntu 13.10 Saucy Salamander

## Re: Graphviz using gvc and cgraph in one program

I compiled it. It segmentation faults for me to. A backtrace shows that it is from your agopen call. I haven't looked any deeper than that though.

Graphviz学习（一）

https://my.oschina.net/goodmoon/blog/756533

Graphviz学习（一）
• 发表于 9个月前
• 阅读 60
• 收藏 1
• 评论0

最近接触了一个图形绘制神器graphviz，其神奇之处在于着一个软件提供了诸多接口，从最基本的图形界面、到专门用于描述DOT脚本语言、到C语言和Python语言接口都有，可以说不仅是一个功能强大的软件，它的模块化设计也非常值得我们学习。

但不足的是，graphviz再资料方面、尤其是中文资料方面明显缺少，从网上查到的中文资料都是一些基础用法，因此最近一段时间我花了一点功夫去阅读graphviz的英文文档，并且将所学到的知识写于上面，同时也算是一个笔记。由于本人的英语水平确实不咋的，里面也有很多专业术语，我的翻译和理解难免会有不当之处，所以欢迎各位读者和大神的批评指正。

（一）、Graphviz的安装

Graphviz主要应用于Linux系统，如果要在Windows上面安装，一般要使用Cygwin环境，非常麻烦，因此在这里面我只介绍在Ubuntu上面的安装，其他平台请读者自己查询资料。

在Ubuntu上面的安装非常简单，使用apt即可，由于我还要学习graphviz的C语言接口，因此安装graphviz-dev而不是graphviz：

sudo apt-get install graphviz-dev

输入下面的命令加以验证：

dot -version

（二）、Graphviz脚本语言接口之小试牛刀

新建myfirst.gv文件，输入以下代码：

digraph G {
a[label="node a",shape=record];
b[label="node b",shape=ellipse];
a->b[label="edge a-> b"];
}

在本目录的Shell中输入命令;

dot myfirst.gv -T png -o myfirst.png

输出一个图片文件myfirst.png，如下：

解释：

首先解释一下源代码文件，文件名后缀没有强制要求，但一般使用gv、dot等后缀。

再源文件内部，代码布局是这样的：

digraph/graph graph_name {
command_line1;
command_line2;
......
}

graph代表此图是无向图（就是连线没有箭头），digraph就是有向图，后面时图的名字（可有可无），再后面就是用花括号括起来的图的元素——子图、节点和连线——以命令的形式表示，并且用分号隔开。

在本例中，此图是一个有向图，名字为G，有三个元素：节点a，标题为“node a”，形状是矩形；节点b，标题为“node b”，形状是椭圆（默认）；有向连线a->b，标题为“edge a -> b ”。

在命令行中，最开始的dot是一个解释程序，对源文件进行解释并采用dot布局算法，计算图的形状，类似的算法还有neato、fdp、sfdp、twopi、circo等等，对应的命令跟它们的名称一样，例如，我想使用neato，而不是dot算法计算布局，输入以下命令：

neato myfirst.gv -T png -o myfirst.png

输出如下：

可以看出，使用的布局算法不同，得到的结果也是不同的，以后我们可以看到，布局算法是Graphviz中的精华部分，非常值得一学。

跟GCC一样，命令的第二个参数是输入文件，-o 后面是输出文件，-T后面是输出文件的格式，可以是各种图形格式例如：PNG、JPG、GIF、SVG、PDF、PS甚至是非图形的DOT语言自己，在这里你可能会说，DOT格式不是变回自己吗，这也有意义？答案是，有，但不是这里。再以后的章节我会详细说明。

（三）、Graphviz的C语言接口之小试牛刀

新建myfirst.cpp文件，加上以下内容：

#include <stdio>
#include <gvc.h>

int main(){
GVC_t * gv;
Agraph_t * g;
Agnode_t * a,* b;
Agedge_t * e;

gv=gvContext();
g=agopen("G",Agdirected,0);
a=agnode(g,"node a",1);
b=agnode(g,"node b",1);
agsafeset(a,"shape","record","ellipse");
agsafeset(a,"shape","ellipse","ellipse");
e=agedge(g,a,b,"edge e",1);
agsafeset(e,"label","edge a -> b","");
gvLayout(gv,g);
gvRenderFilename(gv,g,"png","myfirst.png");
gvRender(gv,g,"dot",stdout);
gvFreeLyout(gv,g);
agclose(g);
gvFreeContext(gv);
}

同目录终端输入以下命令，编译运行，编译时有可能会有很多警告，这是由于gvc接口的字符串参数类型为char *，而源代码中字符串类型为const char *，可以忽略：

g++ myfirst.cpp -o myfirst pkg-config --libs --cflags libgvc
./myfirst

可以得到图片（myfirst.png），以及以DOT语言为格式的，再标准输出上显示的代码：

digraph G {
graph [bb="0,0,97.447,123"];
node [label="\N",
shape=ellipse
];
"node a"	 [height=0.5,
pos="34.447,105",
width=0.95686];
"node b"	 [height=0.5,
pos="34.447,18",
width=0.95686];
"node a" -> "node b" [key="edge e",
label="edge a -> b",
lp="65.947,61.5",
pos="e,34.447,36.175 34.447,86.799 34.447,75.163 34.447,59.548 34.447,46.237"];
}


可以看到，图片输出的效果跟使用dot命令解释脚本一模一样，DOT格式输出也差不多（多了精确坐标信息）。这是由于，脚本解释器其实就是C接口的封装。下面解释一下这个过程，要使用C接口，必需导入libgvc库，使用pkg：

pkg-config --libs --cflags libgvc

获取程式库的头文件搜索路径和链接库。

在文件的开头，包含文件gvc.h，此文件包含操作软件的所需函数和数据结构的声明。

使用之前，必需导入程式库的句柄——gv，是一个GVC_t 类型的指针，包含对图进行布局和渲染输出的必要函数，通过gvContext()获取，使用完毕后通过gvFreeContext()释放。

在这两个函数之间就是构造并操作用于描述图的数据结构了——g(Agraph_t)、a(Agndoe_t)、b(Agnode_t)、(Agedge_t)，有关他们的具体细节，我会在以后的章节详细描述。

最后是布局和渲染，布局制定使用dot算法，渲染可以制定文件名或文件流。

----------------------------------------------------------------

Iced Almond Soy Ubuntu, No Foam
Join Date
Feb 2006
Beans
1,086
Distro
Ubuntu 13.10 Saucy Salamander

## Re: Graphviz using gvc and cgraph in one program

I compiled it. It segmentation faults for me to. A backtrace shows that it is from your agopen call. I haven't looked any deeper than that though.
-------------------------------------------------------------------

Iced Almond Soy Ubuntu, No Foam
Join Date
Feb 2006
Beans
1,086
Distro
Ubuntu 13.10 Saucy Salamander

## Re: Graphviz using gvc and cgraph in one program

Actually, I didn't look close enough. I get the same crash points as you do.

• 本文已收录于以下专栏：

举报原因： 您举报文章：有限状态机与行为树的C++学习与实践sudo apt-get install libxmu-dev sudo apt-get install libxmu-dev libxi-dev 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)