找到数组的等效分区

时间:2016-12-01 10:47:50

标签: matlab performance

假设有一个算法根据一些最小化问题找到数组nodes=[1:10]的分区。算法的输出将是一个索引数组,指示某个节点被分配给哪个分区。例如:part=[1 1 1 1 3 3 2 2 2 2]

此算法存在问题。它有一个随机组件,有时它可以返回相同的分区但具有不同的编号。例如part2=[2 2 2 2 3 3 1 1 1 1]。在这种情况下,part1part2实际上是同一个分区。

假设我需要运行分区算法5次。输出将是5x10矩阵A。最后,我需要看看算法找到了多少个不同的分区。这意味着我需要知道A中存在多少等效分区。

我写了一个algorithm来做这件事,但对于大输入来说真的慢。

这是输入的一个例子:

clusters=[ 1,1,2,2;
           1,1,2,2;
           2,2,1,1;
           1,2,1,2;
           2,1,2,1;
           3,1,2,1;
           2,1,2,1;
           3,1,2,1;
           1,2,1,2];

我获取了不同的分区,最频繁的分区及其出现的次数m

true_clusters =

 1     1     2     2
 1     2     1     2
 3     1     2     1


frequest =

 1     2     1     2

m =

 4

有谁知道解决问题的快捷方法?

2 个答案:

答案 0 :(得分:2)

我不知道它对你来说是否足够快:

2.0.0.1

答案 1 :(得分:2)

这是一个矢量化版本:

考虑具有相同模式的行[1 2 1 2][3 1 2 1]以及[ 2 1 2 1],因为在所有这些行中,每个向量的连续元素彼此不同,因此diff(clusters,1,2)~=0对于那些行生成相同的模式[1 1 1]。 但这还不足以为算法得到正确的答案。 此外,对于每一行,都需要具有出现在其中的唯一元素。 因此在[1 1 2 2]中,唯一元素为[1 2][3 1 2 1]个唯一元素为[1 2 3] 同样,可以创建一个逻辑向量来表示每个[1 2 3]是否为行的成员,因此[1 1 2 2]逻辑向量为[1 1 0][3 1 2 1][1 1 1] accumarray执行上述任务。 将两个模式连接为[diff(clusters,1,2)~=0 , ac]创建一个数组,它的行代表不同的分区。然后可以应用unique函数来提取唯一分区

ac=accumarray([ repmat((1:size(clusters,1)).',size(clusters,2),1) clusters(:)],1,[],@any);
[~, v, I]=unique([diff(clusters,1,2)~=0 , ac],'rows');
many= hist(I,I(v));
true_clusters = clusters(v,:);
[m,im] = max(many);
frequest = true_clusters(im,:);

结果:

many = 3 4 2

true_clusters =

   2   2   1   1
   1   2   1   2
   3   1   2   1

m = 4

frequest = 1 2 1 2