我是R中igraph
套餐的新手。我有两套A
和B
,每套N
个顶点(A1, A2, ..., AN)
和{{} 1}}。 (B1, B2, ..., BN)
的每个元素与A
的每个元素之间存在边缘,我有一个函数B
,它返回fWgt(Ai, Bj)
和{{1}之间边的权重}}。
我一直在尝试使用R中的Ai
包进行加权最大二分匹配,但我无法根据Bj
包来制定问题。例如,在igraph
包中为igraph
函数提供的示例中:
maximum.bipartite.matching
我无法弄清楚如何使用igraph
重新构建我的问题(设置Usage:
maximum.bipartite.matching(graph, types = NULL, weights = NULL,
eps = .Machine$double.eps)
Example:
g2 <- graph.formula( a-b-c-d-e-f-g )
V(g2)$type <- rep(c(FALSE,TRUE), length=vcount(g2))
str(g2, v=TRUE)
maximum.bipartite.matching(g2)
,A
,B
函数的边缘)?示例中的fWgt
函数似乎设置了边缘,但对于我的情况,graph.formula
函数的等价物是什么?
*编辑*
感谢您的回复。我只能在SO上选择一个。
答案 0 :(得分:3)
igraph
软件包附带了一个很好的内置函数graph.full.bipartite
,可用于创建二分图,而不是graph.formula
。请注意,str
不是设置边缘,它是检查的一种方式,您创建的图形确实是您想要的。
创建二分图并设置边权重后,只需一行即可获得最大匹配。
这是一个N = 5的例子。 (总共10个顶点,每边5个。)
#create the graph
N <- 5
g3 <- graph.full.bipartite (N,N)
#Name the vertices A1...AN and B1..BN
V(g3)$name <- c(paste0("A", 1:N), paste0("B", 1:N))
#set the edge weights
set.seed(122)
E(g3)$weight <- sample(10,N^2, replace=T) #use your fWgt function here instead
#verifty if we did things right
str(g3, TRUE)
is.bipartite(g3)
maximum.bipartite.matching(g3)
#$matching_size
#[1] 5
#
#$matching_weight
#[1] 37
#
#$matching
# A1 A2 A3 A4 A5 B1 B2 B3 B4 B5
#"B1" "B2" "B4" "B3" "B5" "A1" "A2" "A4" "A3" "A5"
答案 1 :(得分:2)
我不熟悉maximum.bipartite.matching
包中的igraph
函数,但您可以将此解决为lp.assign
lpSolve
函数的赋值问题} package:
library(lpSolve)
set.seed(144)
# For example, generate random weights
fWgt <- function(Ai, Bj) runif(1)
N <- 10
wts <- sapply(1:N, function(col) sapply(1:N, function(row) fWgt(row, col)))
res <- lp.assign(wts, "max")
res$solution
# [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
# [1,] 0 0 0 0 0 0 0 1 0 0
# [2,] 0 0 0 0 0 0 1 0 0 0
# [3,] 0 0 0 0 0 0 0 0 0 1
# [4,] 0 0 0 1 0 0 0 0 0 0
# [5,] 0 0 0 0 0 0 0 0 1 0
# [6,] 0 0 1 0 0 0 0 0 0 0
# [7,] 0 0 0 0 0 1 0 0 0 0
# [8,] 1 0 0 0 0 0 0 0 0 0
# [9,] 0 1 0 0 0 0 0 0 0 0
# [10,] 0 0 0 0 1 0 0 0 0 0
res$objval
# [1] 8.557704
在此解决方案中,A
的节点1从B
分配给节点8,A
的节点2从B
分配给节点7,等等。