如何从一组 N 个对象中 select n 个对象,最大化它们之间的成对距离之和

How to select n objects from a set of N objects, maximizing the sum of pairwise distances between them

你有一组 N=400 个对象,每个对象在 19 维空间中都有自己的坐标 space。

您计算(欧几里德)距离矩阵(所有成对距离)。

现在你想要 select n=50 个对象,使得 selected 对象之间所有成对距离的总和最大。

我设计了一种通过线性规划解决这个问题的方法(下面的代码,一个较小的例子),但对我来说似乎效率低下,因为我使用的是 N*(N-1)/2 个二进制变量,对应于距离矩阵的所有非冗余元素,然后很多约束保证解向量的自洽

我怀疑一定有更简单的方法,只使用 N 个变量,但我不能马上想到一个。

This post 简要提到一些 'Bron–Kerbosch' 算法,显然解决了距离和部分。
但是在那个例子中,距离的总和是一个特定的数字,所以我看不到直接适用于我的情况。

我简要了解了二次规划,但我还是看不到与我的情况直接平行的情况,尽管 'b %*% bT' 矩阵(其中 b 是(列)二元解向量)在理论上可以用于乘以距离矩阵等;但是我真的不熟悉这个技术。

任何人都可以建议(/让我指向其他解释的帖子)是否以及如何通过仅使用 N 个二进制变量的线性规划来解决此类问题?
或者就如何更有效地解决问题提供任何其他建议?

谢谢!

PS: 这是我上面提到的代码。

require(Matrix)

#distmat defined manually for this example as a sparseMatrix
distmat <- sparseMatrix(i=c(rep(1,4),rep(2,3),rep(3,2),rep(4,1)),j=c(2:5,3:5,4:5,5:5),x=c(0.3,0.2,0.9,0.5,0.1,0.8,0.75,0.6,0.6,0.15))

N = 5
n = 3

distmat_summary <- summary(distmat)
distmat_summary["ID"] <- 1:NROW(distmat_summary)
i.mat <- xtabs(~i+ID,distmat_summary,sparse=T)
j.mat <- xtabs(~j+ID,distmat_summary,sparse=T)
ij.mat <- rbind(i.mat,"5"=rep(0,10))+rbind("1"=rep(0,10),j.mat)
ij.mat.rowSums <- rowSums(ij.mat)
ij.diag.mat <- .sparseDiagonal(n=length(ij.mat.rowSums),-ij.mat.rowSums)
colnames(ij.diag.mat) <- dimnames(ij.mat)[[1]]
mat <- rbind(cbind(ij.mat,ij.diag.mat),cbind(ij.mat,ij.diag.mat),c(rep(0,NCOL(ij.mat)),rep(1,NROW(ij.mat)) ))

dir <- c(rep("<=",NROW(ij.mat)),rep(">=",NROW(ij.mat)),"==")
rhs <- c(rep(0,NROW(ij.mat)),1-unname(ij.mat.rowSums),n)

obj <- xtabs(x~ID,distmat_summary)
obj <- c(obj,setNames(rep(0, NROW(ij.mat)), dimnames(ij.mat)[[1]]))

if (length(find.package(package="Rsymphony",quiet=TRUE))==0) install.packages("Rsymphony")
require(Rsymphony)
LP.sol <- Rsymphony_solve_LP(obj,mat,dir,rhs,types="B",max=TRUE)
items.sol <- (names(obj)[(1+NCOL(ij.mat)):(NCOL(ij.mat)+NROW(ij.mat))])[as.logical(LP.sol$solution[(1+NCOL(ij.mat)):(NCOL(ij.mat)+NROW(ij.mat))])]
items.sol
ID.sol <- names(obj)[1:NCOL(ij.mat)][as.logical(LP.sol$solution[1:NCOL(ij.mat)])]
as.data.frame(distmat_summary[distmat_summary$ID %in% ID.sol,])

这个问题叫做p-dispersion-sum问题。它可以使用 N 个二进制变量来表示,但使用二次项。据我所知,不可能在 linear 程序中仅使用 N 个二进制变量来表示它。

This paper by Pisinger 给出二次公式并讨论边界和 branch-and-bound 算法。

希望对您有所帮助。