bipartite graph matching to match two sets

匆匆过客 提交于 2020-01-05 09:02:12

问题


I'm a newbie to igraph package in R. I have two sets A and B, each with N vertices (A1, A2, ..., AN) and (B1, B2, ..., BN). There is an edge between every element of A to every element of B, and I have a function fWgt(Ai, Bj) that returns the weights of the edge between Ai and Bj.

I have been trying to use the igraph package in R to do a weighted maximum bipartite matching, but I haven't been able to formulate the problem as per the igraph package. For instance, in the example given for maximum.bipartite.matching function in the igraph package:

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)

I couldn't figure out how to reformulate my problem (sets A, B, edges by fWgt function) using graph.formula? The str function in the example appears to set the edges, but what would be the equivalent of the str function for my case?

* EDIT *

Thanks for both your replies. I can only select one on SO.


回答1:


I'm not familiar with the maximum.bipartite.matching function in the igraph package, but you can solve this as an assignment problem with the lp.assign function in the 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

In this solution, the node 1 from A is assigned to node 8 from B, node 2 from A is assigned to node 7 from B, etc.




回答2:


The igraph package comes with a nice built-in function graph.full.bipartite which you could use to create your bipartite graph, instead of graph.formula. Note that str is not setting the edges, it is a way to inspect that the graph you create is indeed what you wanted.

Once you have created the bipartite graph and set the edge weights, it is just a one line to get the maximal matching.

Here's an example with N=5. (Total of 10 vertices, 5 on each side.)

#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" 


来源:https://stackoverflow.com/questions/22426295/bipartite-graph-matching-to-match-two-sets

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!