如何在图形中为某些边缘分配边缘权重

时间:2019-08-20 16:14:42

标签: r igraph

我想为最短路径中使用的某些边缘分配较小的非负边缘权重。这是一个示例图:

library(igraph)
data <- read.table(text="
1 2
1 4
1 5
2 3
2 4
3 4
5 7
5 8
3 6", header=FALSE)
gmatrix <- data.matrix(data, rownames.force = NA) #convert into a matrix to use in igraph
g <- graph_from_edgelist(gmatrix, directed = FALSE) 

如果我发现节点1和节点3之间的最短路径,则使用的边是1-2和1-3。

get.shortest.paths(g, 1,3)
$vpath
$vpath[[1]]
+ 3/9 vertices, from 634c426:
[1] 1 2 3

我要做的是为这些边缘分配一个小的epsilon值。然后,我想调用get.shortest.paths(g, 1,3)来测试该函数是否将标识相同的路径。

2 个答案:

答案 0 :(得分:1)

好的,我可以帮忙:

使用E()查询从get.shortest.paths获取的ID的边缘,并将值分配给新的边缘属性名称(例如“ weight”或其他名称):

p <- get.shortest.paths(g, 1, 3)$vpath[[1]]

E(g, path = p)$weight <- 0.1

检查结果:

> E(g)
+ 9/9 edges from 605e8c7:
[1] 1--2 1--4 1--5 2--3 2--4 3--4 5--7 5--8 3--6
> E(g)$weight
[1] 0.1  NA  NA 0.1  NA  NA  NA  NA  NA

从1到2和2到3的路径现在具有加权边。

现在,将零分配给其他边,并且'get.shortest.paths`标识另一条路径:

> E(g)$weight <- ifelse(is.na(E(g)$weight), 0, E(g)$weight)
> E(g)$weight
[1] 0.1 0.0 0.0 0.1 0.0 0.0 0.0 0.0 0.0
> get.shortest.paths(g, 1, 3, weights = E(g)$weight)
$vpath
$vpath[[1]]
+ 3/8 vertices, from 605e8c7:
[1] 1 4 3


$epath
NULL

$predecessors
NULL

$inbound_edges
NULL

更加简洁:

g <- set_edge_attr(g, "weight", value = ifelse(E(g) %in% E(g, path = p), 0.1, 0))

E(g)$weight
[1] 0.1 0.0 0.0 0.1 0.0 0.0 0.0 0.0 0.0

答案 1 :(得分:1)

在下面的代码中,我将使用函数all_shortest_paths而不是get.shortest.paths来获取所有最短路径。这是因为稍后我将权重分配给其中之一的边缘。

由于存在两条路径,因此要求的路径在顶点35之间。

首先,查看get.shortest.paths返回的内容。

get.shortest.paths(g, 3, 5)
#$vpath
#$vpath[[1]]
#+ 4/8 vertices, from 98e8e26:
#[1] 3 2 1 5
#
#
#$epath
#NULL
#
#$predecessors
#NULL
#
#$inbound_edges
#NULL

该函数仅返回一个路径:3 2 1 5。但是顶点35之间有两条最短的路径。

p <- all_shortest_paths(g, 3, 5)
p
#$res
#$res[[1]]
#+ 4/8 vertices, from fc330b4:
#[1] 3 2 1 5
#
#$res[[2]]
#+ 4/8 vertices, from fc330b4:
#[1] 3 4 1 5
#
#
#$nrgeo
#[1] 2 1 1 1 2 1 0 0

现在将 epsilon 权重分配给其中一个路径(第一个路径)的边缘。

E(g, path = p$res[[1]])$weight <- .Machine$double.eps^0.5
E(g)$weight
#[1] 1.490116e-08           NA 1.490116e-08 1.490116e-08           NA
#[6]           NA           NA           NA           NA

再次获取所有最短路径。

all_shortest_paths(g, 3, 5)
#$res
#$res[[1]]
#+ 4/8 vertices, from fc330b4:
#[1] 3 4 1 5
#
#
#$nrgeo
#[1] 1 0 1 1 1 1 0 0

现在只有一条路径,即路径3 4 1 5,以前的路径p$res[[1]]现在较重,不再是最短的路径。

get.shortest.paths也返回一个路径。

get.shortest.paths(g, 3, 5)
#$vpath
#$vpath[[1]]
#+ 4/8 vertices, from 98e8e26:
#[1] 3 4 1 5
#
#
#$epath
#NULL
#
#$predecessors
#NULL
#
#$inbound_edges
#NULL

编辑。

在用户commentpaqmo之后,以下代码仅使用函数get.shortest.paths来获取 a 最短路径。在为其边缘分配权重之后,同一函数返回的路径不再是p2,它与上面的代码相同。

只有在没有权重属性的情况下重新初始化图形时,此代码才有意义。

p2 <- get.shortest.paths(g, 3, 5)
p2
#$vpath
#$vpath[[1]]
#+ 4/8 vertices, from 61bfc89:
#[1] 3 2 1 5
#
#
#$epath
#NULL
#
#$predecessors
#NULL
#
#$inbound_edges
#NULL


E(g, path = p2$vpath[[1]])$weight <- .Machine$double.eps^0.5
E(g)$weight
get.shortest.paths(g, 3, 5)
#$vpath
#$vpath[[1]]
#+ 4/8 vertices, from 61bfc89:
#[1] 3 4 1 5
#
#
#$epath
#NULL
#
#$predecessors
#NULL
#
#$inbound_edges
#NULL