pgr_contractionLinear
- 提议中¶
pgr_contractionLinear
— 执行图收缩并返回收缩后的顶点和边线。
可用性
Version 3.8.0
新提议的函数。
描述¶
收缩通过移除部分顶点和边来减小图的大小,例如,可以添加代表原始边序列的边,从而减少图算法所用的总时间和空间。
主要特点是:
仅在具有正成本的边进行处理。
不返回完整的收缩图。
仅返回图中的变更部分。
返回值包括:
线性收缩生成的新边线集。
断头节点收缩生成的修改后顶点集。
返回值的排序如下:
列
id
升序排列。列
id
中的负数,当它是一条新边时,负数依次递减。
签名¶
[directed, forbidden]
(type, id, contracted_vertices, source, target, cost)
- 示例:
无向图上的线性收缩。
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)
绿色节点为线性节点,不属于收缩图的一部分。
所有相邻边线均不纳入收缩图。
红线将成为收缩图的新边线。
![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 |
edge ( |
|
|
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)
该函数返回一行数据。该行的列包括:
列 |
类型 |
描述 |
---|---|---|
|
|
值 = |
|
|
边线的伪 id。
|
|
|
收缩顶点标识符数组。 |
|
|
当前边的源顶点的标识符。 |
|
|
当前边的目标顶点的标识符。 |
|
|
当前边线的权重值。 |
其他示例¶
线性边¶
无向图
节点连接两条(或多条)"线性 "边,当
相邻顶点的数量为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。
线性是对称的。
![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)
线性不对称¶
有向图
线性不对称的图形。
![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)
当图形作为有向图处理时,线性并不对称,因此图形无法收缩。
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)
无向图
当把同一图形作为无向图处理时,线性是对称的,因此图形可以收缩。
![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)
三条边可以用一条无向边代替
边线
。成本:
.边上的收缩顶点:
.
![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)
线性是对称的¶
有向图
线性对称的图形。
![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)
当图形作为有向图处理时,线性并不对称,因此图形无法收缩。
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)
四条边可以用两条有向边代替。
边线
。成本:
.边上的收缩顶点:
.
边线
.成本:
.边上的收缩顶点:
.
![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)
无向图
当把同一图形作为无向图处理时,线性是对称的,因此图形可以收缩。
![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)
四条边线可替换为一条无向边。
边线
。成本:
.边上的收缩顶点:
.
![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)
逐步线性收缩¶
线性收缩将在没有更多线性边时停止。例如,在下图中存在线性边
![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)
收缩顶点
顶点
已从图中移除边线
和 已从图中移除。插入一条新边
,用红色表示。
![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)
收缩顶点
顶点
已从图形中移除从图中删除边
和 。插入一条新边
,用红色表示。
![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)
边线
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)
创建收缩图¶
创建收缩图的步骤¶
添加额外的列。
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
将结果保存到表格中。
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
收缩后的顶点不包含在收缩图中。
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 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)
当出发地和目的地位于收缩图中时使用¶
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)
当出发地/目的地不在收缩图中时使用¶
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)
另请参阅¶
索引和表格