【问题标题】:Faster alternative for find and sort in MATLAB在 MATLAB 中查找和排序的更快替代方案
【发布时间】:2017-11-23 14:16:53
【问题描述】:

我正在使用遗传算法进行社区检测。社区以基于位点的表示形式表示,每个索引(基因)及其值都在同一个社区中。

例如在下图中,如果染色体是 (b),则社区将是 (d)

所以要从染色体中提取社区,我需要迭代地找到索引和值,为此,我编写了以下代码:

while (SumComms)~=nVar
    j=find(Sol>0,1,'first');%find the first node which has not placed in any community
    Com=[j,Sol(j)];%index of the node and it's value
    Comsize=0;
    while Comsize<numel(Com)
        Comsize=numel(Com);
        x=find(ismembc(Sol,sort([Com,Sol(Com)])));%Indexes which Com occure in Sol
        Com=unique([Com,x,Sol(x)]);
    end
    Sol(Com)=0;
    i=i+1;
    SumComms=SumComms+numel(Com);
    Communities{i}=Com;
end

x=find(ismembc(Sol,sort([Com,Sol(Com)]))) 即使在中型网络中也非常耗时。你知道更快的方法吗?

【问题讨论】:

  • 是的,你的图片是为我显示的。
  • 提供SumCommsnVarSol 开头的示例,并提供并解释这些变量的输出结果
  • SumCumms是集群节点数,nVar是总节点数,所以终止条件是while (SumComms)~=nVar,也就是说,直到所有节点都放入一个社区循环将运行。 Sol 是染色体
  • 例如在图片中,Sol 是基因型,nVar 是 9(0 到 8)。 SumComms 在循环中增长直到 9,(nVar)
  • @SardarUsama,一个数字数组。(代表基因)

标签: matlab sorting find


【解决方案1】:

这是一个使用逻辑向量的解决方案。我们可以将Com 定义为逻辑向量,而不是对索引的操作,这样对诸如ismember 之类的索引的操作可以简化为索引操作:

i=0;
SumComms=0;
nVar = 9;
Sol = [3 0 3 1 5 6 4 7 7]+1;
while SumComms ~= nVar
    j=find(Sol>1,1,'first');
    Com = false(1,nVar);
    Com([j Sol(j)])=true;
    Comsize=0;
    sumcom = 2;
    while Comsize<sumcom
        Comsize=sum(Com);
        Com(Sol(Com))=true;
        Com = Com(Sol);
        Com(Sol(Com))=true;
        sumcom = sum(Com);
    end
    Sol(Com)=1;
    i = i + 1;
    SumComms=SumComms+sumcom;
    Communities{i}=find(Com);
end

在 Octave 中的测试结果表明,所提出的方法至少比原始方法快 10 倍。

【讨论】:

  • 感谢您的解决方案,但我对此进行了测试,我的函数运行速度快了大约 10%,您如何运行速度快 10 倍?我用的是matlab 2017a,你觉得Octave这么快?
  • 还有一件事,在我的数据中,一些节点可以为空,它们的值为-1,我的代码可以使用它,如何更改代码以处理负值?例如:Sol = [3 0 3 1 5 6 4 7 7 -1]
  • 我用随机数据测试了它,例如 nVar = 1000;Sol = randi(nVar,1,nVar); 。您可以上传您的数据,以便我们进行测试。通常 MATLAB 比 Octave 快。
  • 您应该将1 添加到值Sol = [3 0 3 1 5 6 4 7 7 -1]+1 中,这里的空值将是0。考虑更改函数的这些部分:j=find(Sol&gt;1,1,'first');Sol(Com)=1;
  • 这是一个online Octave test。你可以看到我的方法快了将近 7 倍。我使用了ismember,因为 Octave 没有ismembc。您可以测试这两种方法并使用isequal 来查看方法的结果是否相等。
猜你喜欢
  • 1970-01-01
  • 2022-01-09
  • 1970-01-01
  • 1970-01-01
  • 2018-12-11
  • 2012-07-05
  • 2012-01-23
  • 2013-07-13
相关资源
最近更新 更多