从一组对中,找到所有子集s.t.子集中没有对共享任何不在子集中的对的元素

时间:2014-08-07 03:42:36

标签: r algorithm sorting vector vectorization

我有一对配对。每对都表示为[i,1:2]。也就是说,ith对是ith行中第一列和第二列中的数字。

我需要将这些对分成不同的组,s.t。 jth组中的任何一对中没有任何元素都在j的任何组中。例如:

示例1:数据

> col1 <- c(3, 4, 6, 7, 10, 8)
> col2 <- c(6, 7, 3, 4, 3,  1)
> 
> dat <- cbind(col1, col2)
> rownames(dat) <- 1:nrow(dat)
> 
> dat
  col1 col2
1    3    6
2    4    7
3    6    3
4    7    4
5   10    3
6    8    1

对于所有对,如果数字在第1列或第2列中无关紧要,则应将这些对分组到组中。每个组中每对中的每个数字仅存在于一个组中。所以解决的例子看起来像这样。

  col1 col2 groups
1    3    6      1
2    4    7      2
3    6    3      1
4    7    4      2
5   10    3      1
6    8    1      3

第1,3和5行组合在一起,因为1和3包含相同的数字,5与3共享,因此必须将它们分组。 2和4共享相同的不同数字,因此它们被组合在一起,6具有唯一的数字,因此它是独立的。

如果我们稍微更改数据,请注意以下内容。

示例2:新数据

注意当我们添加一行与第6行和第5行共享元素时会发生什么。

  col1 col2 groups
1    3    6      1
2    4    7      2
3    6    3      1
4    7    4      2
5   10    3      1
6    8    1      1
7    1   10      1

第7行中的10将其连接到第一组,因为它与第5行共享元素。它还与第6行(数字1)共享一个元素,因此第6行将改为第1行。

问题

有没有简单的方法组成团体?矢量运算?排序算法?如果您尝试使用循环,它会非常快速地变得非常讨厌,因为每个后续行都可以更改先前行的成员资格,如示例中所示。

2 个答案:

答案 0 :(得分:2)

要在identify groups of linked episodes which chain together上绘制旧答案,为每个单独的值分配一个组,您可以尝试将其分配给每个链接对:

library(igraph)
g <- graph.data.frame(dat)
links <- data.frame(col1=V(g)$name,group=clusters(g)$membership)
merge(dat,links,by="col1",all.x=TRUE,sort=FALSE)

#  col1 col2 group
#1    3    6     1
#2    4    7     2
#3    6    3     1
#4    7    4     2
#5   10    3     1
#6    8    1     3

答案 1 :(得分:2)

您的元素可以被视为无向图中的顶点,您的对可以被视为边,然后(假设您想要找到最小尺寸的组 - 如果您不这样做,那么例如整套货币对可以标记为&#34;第1组&#34;)您要查找的组是此图表中的connected components。它们都可以在线性时间内找到深度优先或广度优先搜索。