pgr_contractionLinear
- Proposed¶
pgr_contractionLinear
— Performs graph contraction and returns the contracted
vertices and edges.
可用性
Version 3.8.0
新提议的函数。
描述¶
收缩通过移除部分顶点和边来减小图的大小,例如,可以添加代表原始边序列的边,从而减少图算法所用的总时间和空间。
主要特点是:
仅在具有正成本的边进行处理。
Does not return the full contracted graph.
Only changes on the graph are returned.
The returned values include:
The new edges generated by linear contraction.
The modified vertices generated by dead end contraction.
返回值的排序如下:
column
id
ascending when its a modified vertex.column
id
with negative numbers descending when its a new edge.
签名¶
[directed, forbidden]
(type, id, contracted_vertices, source, target, cost)
- 示例:
Linear contraction on an undirected graph.
SELECT * FROM pgr_contractionLinear(
'SELECT id, source, target, cost, reverse_cost FROM edges',
directed => false);
type | id | contracted_vertices | source | target | cost
------+----+---------------------+--------+--------+------
e | -1 | {3} | 1 | 7 | 2
e | -2 | {17} | 12 | 16 | 2
e | -3 | {15} | 10 | 16 | 2
(3 rows)
The green nodes are linear nodes and will not be part of the contracted graph.
All edges adjacent will not be part of the contracted graph.
The red lines will be new edges of the contracted graph.
![graph G {
splines=false;
3,15,17 [shape=circle;style=filled;color=lightgreen;fontsize=8;width=0.3;fixedsize=true];
1,2,4,5,6,7,8,9,10,11,12,13,14,16 [shape=circle;style=filled;color=cyan;fontsize=8;width=0.3;fixedsize=true];
1:n -- 7:n [label="-1",fontsize=8,color=red];
12:s -- 17:sw -- 16:w [label="-2",fontsize=8,color=red];
10:n -- 15:nw -- 16:w [label="-3",fontsize=8,color=red];
5 -- 6 [label="1",fontsize=8]; 6 -- 10 [label="2",fontsize=8];
10 -- 15 [label="3",fontsize=8]; 6 -- 7 [label="4",fontsize=8];
10 -- 11 [label="5",fontsize=8]; 1 -- 3 [label="6",fontsize=8];
3 -- 7 [label="7",fontsize=8]; 7 -- 11 [label="8",fontsize=8];
11 -- 16 [label="9",fontsize=8]; 7 -- 8 [label="10",fontsize=8];
11 -- 12 [label="11",fontsize=8]; 8 -- 12 [label="12",fontsize=8];
12 -- 17 [label="13",fontsize=8]; 8 -- 9 [label="",fontsize=8];
16 -- 17 [label="15",fontsize=8]; 15 -- 16 [label="16",fontsize=8];
2 -- 4 [label="17",fontsize=8]; 13 -- 14 [label="18",fontsize=8];
1 [pos="0,2!"]; 2 [pos="0.5,3.5!"];
3 [pos="1,2!"]; 4 [pos="2,3.5!"];
5 [pos="2,0!"]; 6 [pos="2,1!"];
7 [pos="2,2!"]; 8 [pos="2,3!"];
9 [pos="2,4!"]; 10 [pos="3,1!"];
11 [pos="3,2!"]; 12 [pos="3,3!"];
13 [pos="3.5,2.3!"]; 14 [pos="3.5,4!"];
15 [pos="4,1!"]; 16 [pos="4,2!"];
17 [pos="4,3!"];
}](_images/graphviz-069192ad4349ef79e70153b36d4506142c52a931.png)
参数¶
参数 |
类型 |
描述 |
---|---|---|
|
Edges SQL 如下所述。 |
|
contraction Order |
|
有序收缩操作。
|
可选参数¶
列 |
类型 |
默认 |
描述 |
---|---|---|---|
|
|
|
|
可选收缩参数¶
列 |
类型 |
默认 |
描述 |
---|---|---|---|
|
|
Empty |
禁止收缩的顶点标识符。 |
|
|
对 |
内部查询¶
Edges SQL¶
列 |
类型 |
默认 |
描述 |
---|---|---|---|
|
ANY-INTEGER |
边的标识符。 |
|
|
ANY-INTEGER |
边的第一个端点顶点的标识符。 |
|
|
ANY-INTEGER |
边的第二个端点顶点的标识符。 |
|
|
ANY-NUMERICAL |
边( |
|
|
ANY-NUMERICAL |
-1 |
边(
|
其中:
- ANY-INTEGER:
SMALLINT
,INTEGER
,BIGINT
- ANY-NUMERICAL:
SMALLINT
,INTEGER
,BIGINT
,REAL
,FLOAT
结果列¶
Returns set of (type, id, contracted_vertices, source, target, cost)
该函数返回一行数据。该行的列包括:
列 |
类型 |
描述 |
---|---|---|
|
|
Value = |
|
|
A pseudo id of the edge.
|
|
|
收缩顶点标识符数组。 |
|
|
当前边的源顶点的标识符。 |
|
|
当前边的目标顶点的标识符。 |
|
|
Weight of the current edge. |
其他示例¶
线性边¶
无向图
A node connects two (or more) linear edges when
相邻顶点的数量为2。
![graph G {
label = "Linear edges"
2 [shape=circle;style=filled;color=lightgreen;fontsize=8;width=0.3;fixedsize=true];
1,3 [shape=circle;style=filled;color=cyan;fontsize=8;width=0.3;fixedsize=true];
1 -- 2 -- 3 -- 2;
1 [pos="0,2!"]; 2 [pos="1,2!"]; 3 [pos="2,2!"];
}](_images/graphviz-c915ca43812bfb7afeeffd1d2f7e072f6593f696.png)
![graph G {
label = "Non linear edges"
4,5,6,7 [shape=circle;style=filled;color=cyan;fontsize=8;width=0.3;fixedsize=true];
4 -- 5 -- 6 -- 5; 5 --7;
4 [pos="0,0!"]; 5 [pos="1,0!"]; 6 [pos="2,0!"];
7 [pos="1,1!"];
}](_images/graphviz-80d04e0ac46c2ac58db33ed33833b8376ea87eef.png)
在有向图的情况下,当满足以下条件时,节点被视为`线性`节点
相邻顶点的数量为2。
Linearity is symmetrical.
![digraph G {
label = "Linearity is symmetrical."
2 [shape=circle;style=filled;color=lightgreen;fontsize=8;width=0.3;fixedsize=true];
1,3 [shape=circle;style=filled;color=cyan;fontsize=8;width=0.3;fixedsize=true];
1 -> 2 -> 3 -> 2 -> 1;
1 [pos="0,2!"]; 2 [pos="1,2!"]; 3 [pos="2,2!"];
}](_images/graphviz-ec0146321e74ae314bab5090db3f7e72f2fa1f65.png)
![digraph G {
label = "Linearity is not symmetrical."
2 [shape=circle;style=filled;color=lightgreen;fontsize=8;width=0.3;fixedsize=true];
1,3 [shape=circle;style=filled;color=cyan;fontsize=8;width=0.3;fixedsize=true];
1 -> 2 -> 3 -> 2;
1 [pos="0,2!"]; 2 [pos="1,2!"]; 3 [pos="2,2!"];
}](_images/graphviz-93233ecad7b6cf2ed672bd846f53b9d50a980a50.png)
Linearity is not symmetrical¶
有向图
Graph where linearity is not symmetrical.
![digraph G {
2 [shape=circle;style=filled;color=lightgreen;fontsize=8;width=0.3;fixedsize=true];
1,3 [shape=circle;style=filled;color=cyan;fontsize=8;width=0.3;fixedsize=true];
1 -> 2 [label="1",fontsize=8];
2 -> 3 [label="3",fontsize=8];
3 -> 2 [label="4",fontsize=8];
1 [pos="0,2!"]; 2 [pos="1,2!"]; 3 [pos="2,2!"];
}](_images/graphviz-2956b8517f0df69088225a55990846dbb9ae75e4.png)
When the graph is processed as a directed graph, linearity is not symmetrical, therefore the graph can not be contracted.
SELECT * FROM pgr_contractionLinear(
$$SELECT * FROM (VALUES
(1, 1, 2, 1, -1),
(2, 2, 3, 3, 4))
AS edges(id,source,target,cost,reverse_cost)$$,
directed => true);
type | id | contracted_vertices | source | target | cost
------+----+---------------------+--------+--------+------
(0 rows)
无向图
When the same graph is processed as an undirected graph, linearity is symmetrical, therefore the graph can be contracted.
![graph G {
2 [shape=circle;style=filled;color=lightgreen;fontsize=8;width=0.3;fixedsize=true];
1,3 [shape=circle;style=filled;color=cyan;fontsize=8;width=0.3;fixedsize=true];
1 -- 2 [label="1",fontsize=8];
2 -- 3 [label="3",fontsize=8];
3 -- 2 [label="4",fontsize=8];
1 [pos="0,2!"]; 2 [pos="1,2!"]; 3 [pos="2,2!"];
}](_images/graphviz-946e80eb77cb0529d96e6199cc314eac3c039ad6.png)
SELECT * FROM pgr_contractionLinear(
$$SELECT * FROM (VALUES
(1, 1, 2, 1, -1),
(2, 2, 3, 3, 4))
AS edges(id,source,target,cost,reverse_cost)$$,
directed => false);
type | id | contracted_vertices | source | target | cost
------+----+---------------------+--------+--------+------
e | -1 | {2} | 1 | 3 | 4
(1 row)
The three edges can be replaced by one undirected edge
Edge
.With cost:
.Contracted vertices in the edge:
.
![graph G {
1,3 [shape=circle;style=filled;color=cyan;fontsize=8;width=0.3;fixedsize=true];
1 -- 3 [label="4, {2}",fontsize=8;color=red];
1 [pos="0,2!"]; 3 [pos="2,2!"];
}](_images/graphviz-d625f5035052b5ad79de074aa489048c0241ff78.png)
线性是对称的¶
有向图
Graph where linearity is symmetrical.
![digraph G {
2 [shape=circle;style=filled;color=lightgreen;fontsize=8;width=0.3;fixedsize=true];
1,3 [shape=circle;style=filled;color=cyan;fontsize=8;width=0.3;fixedsize=true];
1 -> 2 [label="1",fontsize=8];
2 -> 1 [label="2",fontsize=8];
2 -> 3 [label="3",fontsize=8];
3 -> 2 [label="4",fontsize=8];
1 [pos="0,2!"]; 2 [pos="1,2!"]; 3 [pos="2,2!"];
}](_images/graphviz-49002a1065b9c5bc7564f25175a447b0cccd5c80.png)
When the graph is processed as a directed graph, linearity is not symmetrical, therefore the graph can not be contracted.
SELECT * FROM pgr_contractionLinear(
$$SELECT * FROM (VALUES
(1, 1, 2, 1, 2),
(2, 2, 3, 3, 4))
AS edges(id,source,target,cost,reverse_cost)$$,
directed => true);
type | id | contracted_vertices | source | target | cost
------+----+---------------------+--------+--------+------
e | -1 | {2} | 1 | 3 | 4
e | -2 | {2} | 3 | 1 | 6
(2 rows)
The four edges can be replaced by two directed edges.
Edge
.With cost:
.Contracted vertices in the edge:
.
Edge
.With cost:
.Contracted vertices in the edge:
.
![digraph G {
1,3 [shape=circle;style=filled;color=cyan;fontsize=8;width=0.3;fixedsize=true];
1 -> 3 [label="4, {2}",fontsize=8;color=red];
3 -> 1 [label="6, {2}",fontsize=8;color=red];
1 [pos="0,2!"]; 3 [pos="2,2!"];
}](_images/graphviz-6f75bf8e66681aa20c069d3ead197ce9e62f267c.png)
无向图
When the same graph is processed as an undirected graph, linearity is symmetrical, therefore the graph can be contracted.
![graph G {
2 [shape=circle;style=filled;color=lightgreen;fontsize=8;width=0.3;fixedsize=true];
1,3 [shape=circle;style=filled;color=cyan;fontsize=8;width=0.3;fixedsize=true];
1 -- 2 [label="1",fontsize=8];
2 -- 1 [label="2",fontsize=8];
2 -- 3 [label="3",fontsize=8];
3 -- 2 [label="4",fontsize=8];
1 [pos="0,2!"]; 2 [pos="1,2!"]; 3 [pos="2,2!"];
}](_images/graphviz-4772c46a98d0df937b2ce4687655644d65810756.png)
SELECT * FROM pgr_contractionLinear(
$$SELECT * FROM (VALUES
(1, 1, 2, 1, 2),
(2, 2, 3, 3, 4))
AS edges(id,source,target,cost,reverse_cost)$$,
directed => false);
type | id | contracted_vertices | source | target | cost
------+----+---------------------+--------+--------+------
e | -1 | {2} | 1 | 3 | 4
(1 row)
The four edges can be replaced by one undirected edge.
Edge
.With cost:
.Contracted vertices in the edge:
.
![graph G {
1,3 [shape=circle;style=filled;color=cyan;fontsize=8;width=0.3;fixedsize=true];
1 -- 3 [label="4, {2}",fontsize=8;color=red];
1 [pos="0,2!"]; 3 [pos="2,2!"];
}](_images/graphviz-6bec6c1f2e220906e102c9d21ef8783219c7ec42.png)
Step by step linear contraction¶
The linear contraction will stop when there are no more linear edges. For example from the following graph there are linear edges
![digraph G {
1, 2, 3, 4, G [fontsize=8;fixedsize=true;style=filled];
1, 2, 3, 4 [shape=circle];
1, 4 [color=deepskyblue];
2, 3 [color=green];
G [shape=tripleoctagon;width=1.5;color=deepskyblue;label = "Rest of the Graph"];
G -> {1, 4} [dir=none, weight=1, penwidth=3];
1 -> 2 [label="1";fontsize=8;fixedsize=true];
2 -> 3 [label="1";fontsize=8;fixedsize=true];
3 -> 4 [label="1";fontsize=8;fixedsize=true];
G [pos="1,1!"];
1 [pos="0,0!"]; 2 [pos="1,0!"]; 3 [pos="2,0!"]; 4 [pos="3,0!"];
}](_images/graphviz-6567892805665a7ce5981b1a08fc9041d392b59b.png)
Contracting vertex
The vertex
is removed from the graphThe edges
and are removed from the graph.A new edge
is inserted represented with red color.
![digraph G {
1, 2, 4, G [fontsize=8;fixedsize=true;style=filled];
1, 2, 4 [shape=circle];
1, 4 [color=deepskyblue];
2 [color=green];
G [shape=tripleoctagon;width=1.5;color=deepskyblue;label = "Rest of the Graph"];
G -> {1, 4} [dir=none, weight=1, penwidth=3];
1 -> 2 [label="1";fontsize=8;fixedsize=true];
2 -> 4 [label="2, {3}";color=red;fontsize=8;fixedsize=true];
G [pos="1,1!"];
1 [pos="0,0!"]; 2 [pos="1,0!"]; 4 [pos="3,0!"];
}](_images/graphviz-9979db882d187d41972ef525a3409d772accfd18.png)
Contracting vertex
The vertex
is removed from the graphThe edges
and are removed from the graph.A new edge
is inserted represented with red color.
![digraph G {
1, 4, G [fontsize=8;fixedsize=true;style=filled];
1, 4 [shape=circle];
1, 4 [color=deepskyblue];
G [shape=tripleoctagon;width=1.5;color=deepskyblue;label = "Rest of the Graph"];
G -> {1, 4} [dir=none, weight=1, penwidth=3];
1 -> 4 [label="3, {2,3}";color=red;fontsize=8;fixedsize=true]
G [pos="1,1!"];
1 [pos="0,0!"]; 4 [pos="3,0!"];
}](_images/graphviz-db2920cace480487d7d9f480027b6e67177e2663.png)
Edge
SELECT * FROM pgr_contractionLinear(
$$SELECT * FROM (VALUES
(1, 1, 2, 1),
(2, 2, 3, 1),
(2, 3, 4, 1))
AS edges(id,source,target,cost)$$);
type | id | contracted_vertices | source | target | cost
------+----+---------------------+--------+--------+------
e | -1 | {2,3} | 1 | 4 | 3
(1 row)
Creating the contracted graph¶
Steps for the creation of the contracted graph¶
Add additional columns.
ALTER TABLE vertices ADD is_contracted BOOLEAN DEFAULT false;
ALTER TABLE
ALTER TABLE edges ADD is_new BOOLEAN DEFAULT false;
ALTER TABLE
ALTER TABLE edges ADD contracted_vertices BIGINT[];
ALTER TABLE
Save results into a table.
SELECT * INTO contraction_results
FROM pgr_contractionLinear(
'SELECT id, source, target, cost, reverse_cost FROM edges',
directed => false);
SELECT 3
使用 is_contracted
列来指示收缩的顶点。
UPDATE vertices
SET is_contracted = true
WHERE id IN (SELECT unnest(contracted_vertices) FROM contraction_results);
UPDATE 3
The contracted vertices are not part of the contracted graph.
SELECT id, is_contracted
FROM vertices WHERE is_contracted ORDER BY id;
id | is_contracted
----+---------------
3 | t
15 | t
17 | t
(3 rows)
插入由 pgr_contraction 生成的新边。
INSERT INTO edges(source, target, cost, reverse_cost, contracted_vertices, is_new)
SELECT source, target, cost, -1, contracted_vertices, true
FROM contraction_results;
INSERT 0 3
Create the contracted graph.
CREATE VIEW contracted_graph AS
WITH
vertices_in_graph AS (
SELECT id FROM vertices WHERE NOT is_contracted
)
SELECT id, source, target, cost, reverse_cost
FROM edges
WHERE source IN (SELECT * FROM vertices_in_graph)
AND target IN (SELECT * FROM vertices_in_graph)
ORDER BY id;
CREATE VIEW
收缩图¶
SELECT * FROM contracted_graph ORDER by id;
id | source | target | cost | reverse_cost
----+--------+--------+------+--------------
1 | 5 | 6 | 1 | 1
2 | 6 | 10 | -1 | 1
4 | 6 | 7 | 1 | 1
5 | 10 | 11 | 1 | -1
8 | 7 | 11 | 1 | 1
9 | 11 | 16 | 1 | 1
10 | 7 | 8 | 1 | 1
11 | 11 | 12 | 1 | -1
12 | 8 | 12 | 1 | -1
14 | 8 | 9 | 1 | 1
17 | 2 | 4 | 1 | 1
18 | 13 | 14 | 1 | 1
19 | 1 | 7 | 2 | -1
20 | 12 | 16 | 2 | -1
21 | 10 | 16 | 2 | -1
(15 rows)
![graph G {
splines=false;
1,2,4,5,6,7,8,9,10,11,12,13,14,16 [shape=circle;style=filled;color=cyan;fontsize=8;width=0.3;fixedsize=true];
1 -- 7 [label="19, (2, {3})",fontsize=8];
12 -- 16 [label="20, (2, {17})",fontsize=8];
10 -- 16 [label="21, (2, {15})",fontsize=8];
5 -- 6 [label="1",fontsize=8]; 6 -- 10 [label="2",fontsize=8];
6 -- 7 [label="4",fontsize=8];
10 -- 11 [label="5",fontsize=8];
7 -- 11 [label="8",fontsize=8];
11 -- 16 [label="9",fontsize=8]; 7 -- 8 [label="10",fontsize=8];
11 -- 12 [label="11",fontsize=8]; 8 -- 12 [label="12",fontsize=8];
8 -- 9 [label="",fontsize=8];
2 -- 4 [label="17",fontsize=8]; 13 -- 14 [label="18",fontsize=8];
1 [pos="0,2!"]; 2 [pos="0.5,3.5!"];
4 [pos="2,3.5!"];
5 [pos="2,0!"]; 6 [pos="2,1!"];
7 [pos="2,2!"]; 8 [pos="2,3!"];
9 [pos="2,4!"]; 10 [pos="3,1!"];
11 [pos="3,2!"]; 12 [pos="3,3!"];
13 [pos="3.5,2.3!"]; 14 [pos="3.5,4!"];
16 [pos="4,2!"];
}](_images/graphviz-0539f2097024ee3664e745ed5dadc5882fc6bb36.png)
Using when departure and destination are in the contracted graph¶
SELECT *
FROM pgr_dijkstra('SELECT * FROM contracted_graph', 7, 16);
seq | path_seq | start_vid | end_vid | node | edge | cost | agg_cost
-----+----------+-----------+---------+------+------+------+----------
1 | 1 | 7 | 16 | 7 | 8 | 1 | 0
2 | 2 | 7 | 16 | 11 | 9 | 1 | 1
3 | 3 | 7 | 16 | 16 | -1 | 0 | 2
(3 rows)
![graph G {
splines=false;
1,2,4,5,6,7,8,9,10,11,12,13,14,16 [shape=circle;style=filled;color=cyan;fontsize=8;width=0.3;fixedsize=true];
1 -- 7 [label="19, (2, {3})",fontsize=8];
12 -- 16 [label="20, (2, {17})",fontsize=8];
10 -- 16 [label="21, (2, {15})",fontsize=8];
5 -- 6 [label="1",fontsize=8]; 6 -- 10 [label="2",fontsize=8];
6 -- 7 [label="4",fontsize=8];
10 -- 11 [label="5",fontsize=8];
7 -- 11 [label="8",fontsize=8;color=red];
11 -- 16 [label="9",fontsize=8;color=red]; 7 -- 8 [label="10",fontsize=8];
11 -- 12 [label="11",fontsize=8]; 8 -- 12 [label="12",fontsize=8];
8 -- 9 [label="",fontsize=8];
2 -- 4 [label="17",fontsize=8]; 13 -- 14 [label="18",fontsize=8];
1 [pos="0,2!"]; 2 [pos="0.5,3.5!"];
4 [pos="2,3.5!"];
5 [pos="2,0!"]; 6 [pos="2,1!"];
7 [pos="2,2!"]; 8 [pos="2,3!"];
9 [pos="2,4!"]; 10 [pos="3,1!"];
11 [pos="3,2!"]; 12 [pos="3,3!"];
13 [pos="3.5,2.3!"]; 14 [pos="3.5,4!"];
16 [pos="4,2!"];
}](_images/graphviz-a3f31bc8a0a6461912a48c178829e7fd344a7244.png)
Using when departure/destination is not in the contracted graph¶
SELECT * FROM pgr_dijkstra(
'WITH in_line AS (SELECT contracted_vertices FROM edges WHERE 17 = ANY(contracted_vertices))
SELECT id, source, target, cost, reverse_cost
FROM edges, in_line
WHERE source = ANY(in_line.contracted_vertices) OR target = ANY(in_line.contracted_vertices)
UNION
SELECT id, source, target, cost, reverse_cost FROM contracted_graph',
1, 17);
seq | path_seq | start_vid | end_vid | node | edge | cost | agg_cost
-----+----------+-----------+---------+------+------+------+----------
1 | 1 | 1 | 17 | 1 | 19 | 2 | 0
2 | 2 | 1 | 17 | 7 | 8 | 1 | 2
3 | 3 | 1 | 17 | 11 | 9 | 1 | 3
4 | 4 | 1 | 17 | 16 | 15 | 1 | 4
5 | 5 | 1 | 17 | 17 | -1 | 0 | 5
(5 rows)
![graph G {
17 [shape=circle;style=filled;color=lightgreen;fontsize=8;width=0.3;fixedsize=true];
1,2,4,5,6,7,8,9,10,11,12,13,14,16 [shape=circle;style=filled;color=cyan;fontsize=8;width=0.3;fixedsize=true];
1 -- 7 [label="19, (2, {3})",fontsize=8;color=red];
12 -- 16 [label="20, (2, {17})",fontsize=8];
10 -- 16 [label="21, (2, {15})",fontsize=8];
5 -- 6 [label="1",fontsize=8]; 6 -- 10 [label="2",fontsize=8];
6 -- 7 [label="4",fontsize=8];
10 -- 11 [label="5",fontsize=8];
7 -- 11 [label="8",fontsize=8;color=red]; 12 -- 17 [label="13",fontsize=8];
11 -- 16 [label="9",fontsize=8;color=red]; 7 -- 8 [label="10",fontsize=8];
11 -- 12 [label="11",fontsize=8]; 8 -- 12 [label="12",fontsize=8];
8 -- 9 [label="",fontsize=8]; 16 -- 17 [label="15",fontsize=8;color=red];
2 -- 4 [label="17",fontsize=8]; 13 -- 14 [label="18",fontsize=8];
1 [pos="0,2!"]; 2 [pos="0.5,3.5!"];
4 [pos="2,3.5!"];
5 [pos="2,0!"]; 6 [pos="2,1!"];
7 [pos="2,2!"]; 8 [pos="2,3!"];
9 [pos="2,4!"]; 10 [pos="3,1!"];
11 [pos="3,2!"]; 12 [pos="3,3!"];
13 [pos="3.5,2.3!"]; 14 [pos="3.5,4!"];
16 [pos="4,2!"]; 17 [pos="4,3!"];
}](_images/graphviz-083b6038b8df39caaf7f1ed454f2e4c2a8921297.png)
另请参阅¶
索引和表格