【发布时间】:2013-05-21 16:34:16
【问题描述】:
我的问题:需要从一组集合中找到所有不相交(不重叠)的集合。
背景:我正在使用比较系统发育方法来研究鸟类的性状进化。我有一棵树,大约有 300 种。这棵树可以分为子分支(即子树)。如果两个子分支不共享物种,则它们是独立的。我正在寻找一种算法(如果可能的话,还有一个 R 实现),它将找到所有可能的子进化枝分区,其中每个子进化枝具有大于 10 个分类单元并且都是独立的。每个子进化枝可以被认为是一个集合,当两个子进化枝是独立的(不共享物种)时,这些子进化枝是不相交的集合。
希望这很清楚,有人可以提供帮助。
干杯, 格伦
以下代码生成示例数据集。其中 subclades 是所有可能的子分支(集合)的列表,我想从中采样 X 不相交的集合,其中集合的长度是 Y。
###################################
# Example Dataset
###################################
library(ape)
library(phangorn)
library(TreeSim)
library(phytools)
##simulate a tree
n.taxa <- 300
tree <- sim.bd.taxa(n.taxa,1,lambda=.5,mu=0)[[1]][[1]]
tree$tip.label <- seq(n.taxa)
##extract all monophyletic subclades
get.all.subclades <- function(tree){
tmp <- vector("list")
nodes <- sort(unique(tree$edge[,1]))
i <- 282
for(i in 1:length(nodes)){
x <- Descendants(tree,nodes[i],type="tips")[[1]]
tmp[[i]] <- tree$tip.label[x]
}
tmp
}
tmp <- get.all.subclades(tree)
##set bounds on the maximum and mininum number of tips of the subclades to include
min.subclade.n.tip <- 10
max.subclade.n.tip <- 40
##function to replace trees of tip length exceeding max and min with NA
replace.trees <- function(x, min, max){
if(length(x) >= min & length(x)<= max) x else NA
}
#apply testNtip across all the subclades
tmp2 <- lapply(tmp, replace.trees, min = min.subclade.n.tip, max = max.subclade.n.tip)
##remove elements from list with NA,
##all remaining elements are subclades with number of tips between
##min.subclade.n.tip and max.subclade.n.tip
subclades <- tmp2[!is.na(tmp2)]
names(subclades) <- seq(length(subclades))
【问题讨论】:
-
因此您将每个子树视为一个子集,并且您希望找到一个子集的集合,使得 each 元素只包含一次;或者你不在乎是否遗漏了一些元素?
-
如果您的意思是“恰好一次”的解释,那么这就是Exact cover problem。它是 NP 完全的,这意味着您不会比简单地回溯和测试所有可能性做得更好。
-
我想说的是,en.wikipedia.org/wiki/Knuth%27s_Algorithm_X 听起来像是个问题。
-
如果您的数据集不是特别大,则首先收集所有
length(clade.x) >=10,然后对该子集的所有组合运行intersect。 -
与@CarlWitthoft 一致,您可以执行
i <- 3; j <- 4; length(intersect(A[[i]],A[[j]]))>0之类的操作
标签: r algorithm subset set data-partitioning