假设有一个算法根据一些最小化问题找到数组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]
。在这种情况下,part1
和part2
实际上是同一个分区。
假设我需要运行分区算法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
有谁知道解决问题的快捷方法?
答案 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