分享免费的编程资源和教程

网站首页 > 技术教程 正文

「洛谷日报第47期」浅谈OI中的画图利器——Graphviz入门

goqiw 2024-10-05 19:16:37 技术教程 28 ℃ 0 评论

那是什么?

在写题解/博客时,我们有可能遇到需要画有向/无向图、流程图等等, Windows 自带的画图又不能满足我们的需求,我们就可以用到 Graphviz 来画图。

DOT :是一个纯文本图像描述语言。

Graphviz :是一个开源的软件,其中包含 DOT

如何下载&安装?

进入http://www.graphviz.org/download/

Ubuntu 用户下载 Ubuntu\ packages

Windows 用户下载 Stable\ 2.38\ Windows\ install\ packages \rightarrow \text{graphviz-2.38.zip}

Windows 用户下载之后需要配置环境变量,以下以 \rm Windows\ 10 为例,

首先,点击“此电脑”->“属性”

弹出来的窗口左侧“高级系统设置”->“环境变量(N)…”

上方“xxx的用户变量”->“ \rm Path ”->“编辑(E)…”

接下来分两种情况:

第一种:在弹出窗口内“变量值”后加上“你的解压后的目录\release\bin;”(注意分号)

第二种:在弹出窗口内点击“新建”,然后输入“你的解压后的目录\release\bin”然后确定。

然后,一路点确定下来即可。

如何验证是否完成?

打开命令行(win+R,输入cmd然后回车/shift+右键->在此处打开命令窗口/Linux 终端)输入

dot-version

如果没有报错,那么你设置完成

如何使用?

(以下操作在 Ubuntu\ 16.04\ LTS 中进行,其他操作系统没有太大差别。

建立一个文件 xxx.dot 。

使用纯文本编辑器(如记事本/notepad++/vim/gedit等)编辑。

我们有一个例子来测试它:

digraphexample{

node[shape=box]

a->b;
b->c;
}

(这里,我们使用vim做示范,其它编辑器同理)

在同样目录下,打开命令行(或使用cd命令),输入

dottest.dot-Tpng-otest.png

则会在目录下生成一个文件test.png

怎么写DOT ?(DOT入门)

无向图

无向图的格式如下:

graph名字(随意)

{
无向图的内容
}

无向图使用a--b的形式来描述边, dot 会帮你自动调整每个节点的位置。

例如:

graphexample

{
a--b;
a--c;
b--c;
}

效果:

如果边数太多,我们还可以使用a->{b;c;d;e}的方式来描述很多条边,比如:

graphexample

{
a--{b;c;d;e;f;g;h;i};
}

效果:

如果你还需要不同的形状/颜色,你可以参考以下的例子:

graphexample

{
a--b[color=red;label="233"];
a--c[label="2333"];
b--{d;e};
b[shape=box];
}

效果:

即边、点后面可以加[color=xxx]表示颜色

[label="xxx"]表示边权

[shape=xxx]表示形状

常用的形状(点)有:

box,oval,circle,point,egg,triangle,square,record等,可以到网上去找,这里不一一枚举。

还有一点,若所有的边或点都需要设置,可以使用

edge[xxx]
node[xxx]

的方式,比如:

graphexample

{
edge[color=red];
node[shape=box];

a--b;
b--c;
}

效果:

有向图的格式和无向图基本一样:

digraph名字(随意){

}

其中边使用a->b描述,比如:

digraphexample{
node[shape=circle];
root[shape=box];
root->{b;e};
b->{c;d};
}

效果:

进阶&实例

如何指定边射出的方向?

我们通过具体例子来说明:

digraphexample{
a0:w->b0;//其中w意思是west,支持w,e,n,s,sw,se,nw,ne
a1:e->b1;
a2:n->b2;
a3:s->b3;
a4:nw->b4;
a5:ne->b5;
a6:sw->b6;
a7:se->b7;
}

如何让修改图片的朝向?

我们把上面的例子做些修改,添加一句rankdir = LR;

digraphexample{
rankdir=LR;
a0:w->b0;//其中w意思是west,支持w,e,n,s,sw,se,nw,ne
a1:e->b1;
a2:n->b2;
a3:s->b3;
a4:nw->b4;
a5:ne->b5;
a6:sw->b6;
a7:se->b7;
}

效果:

想要”结构体“的效果?

我们以一个链表的例子来理解:

digraphexample

{
rankdir=LR;//让图片横过来
node[shape=record]//record形状是专门用来做类似”结构体“的东西的
a[label="{A|}"];//每个的'|'都是一列
b[label="{B|}"];
c[label="{C|}"];
d[label="{D|NULL}"];
a->b:w;
b->c:w;
c->d:w;
}

效果:

我们通过几个例子来熟悉record

digraphexample

{
a[shape=record;label="A|B|C|D"];
}

效果:

digraphexample

{
a[shape=record;label="{A|B|C|D}"];
}

效果:

(注意:rankdir = LR;也会影响方向)

后记

Graphviz 的功能还有很多,网上也有许多详细的教程,这边只选取一些常用功能进行介绍,再加上本人的水平还很低,所以出错是难免的,希望大家谅解。


本文发布于洛谷日报,特约作者:土间埋

原文地址:https://www.luogu.org/blog/34238/graphviz

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表