Arrays matlab中生长单元阵列的改进

Arrays matlab中生长单元阵列的改进,arrays,matlab,cluster-analysis,Arrays,Matlab,Cluster Analysis,我想知道如何有效地运行我的程序的这一部分。基本上,为了了解我的目标,我想对点进行聚类。大约有10000点。这些点计算了它们之间的“力”,这些力存储在矩阵F中。所以点1和点2之间的力是F(1,2)。然后,我想用足够的F对其进行“聚类”(强制设置/阈值),即两个点之间有足够的F属于同一聚类 我有一个代码,如下所示。制作了一个单元格数组集群,以包含集群分配。因此CLUSTER{i}是包含ith簇的单元,其中包含聚集点 但是,对于某些F设置,实现需要花费很长时间。我读过关于预分配和parfor(parf

我想知道如何有效地运行我的程序的这一部分。基本上,为了了解我的目标,我想对点进行聚类。大约有10000点。这些点计算了它们之间的“力”,这些力存储在矩阵
F
中。所以点1和点2之间的力是
F(1,2)
。然后,我想用足够的
F
对其进行“聚类”(强制设置/阈值),即两个点之间有足够的
F
属于同一聚类

我有一个代码,如下所示。制作了一个单元格数组
集群
,以包含集群分配。因此
CLUSTER{i}
是包含
i
th簇的单元,其中包含聚集点

但是,对于某些
F
设置,实现需要花费很长时间。我读过关于预分配和
parfor
parfor
无法完成,因为迭代中存在依赖关系)。但细胞阵列的预分配是否意味着单个细胞没有预先分配内存?还有别的办法吗?分析告诉我,
ismember
在计算领域占有最大份额。我希望通过您的建议来改进代码。非常感谢

CLUSTER = {};

for fi = 1:srow 
    for fj = 1:scol 
        if fj > fi % to eliminate redundancy, diagonal mirror elements of F !check on this 
            if F(fi,fj) >= 2000 % Force setting    
                if( (~ismember(1,cellfun(@(x)ismember(fi,x),CLUSTER))) && (~ismember(1,cellfun(@(x)ismember(fj,x),CLUSTER))) ) % fi & fj are not in CLUSTER
                    CLUSTER{end+1} = [fi fj];
                    end
                %%if( (ismember(1,cellfun(@(x)ismember(fi,x),CLUSTER))) && (ismember(1,cellfun(@(x)ismember(fj,x),CLUSTER))) ) % fi & fj are in CLUSTER   
                    %do nothing since lfi and fj are in CLUSTER    
                %%end    
                if( (ismember(1,cellfun(@(x)ismember(fi,x),CLUSTER))) && (~ismember(1,cellfun(@(x)ismember(fj,x),CLUSTER))) ) % fi in CLUSTER, fj not in CLUSTER
                    c = find(cellfun(@(x)ismember(fi,x),CLUSTER));
                    CLUSTER{c} = [CLUSTER{c} fj];
                end        
                if( (~ismember(1,cellfun(@(x)ismember(fi,x),CLUSTER))) && (ismember(1,cellfun(@(x)ismember(fj,x),CLUSTER))) ) % fi not in CLUSTER, fj in CLUSTER
                    c = find(cellfun(@(x)ismember(fj,x),CLUSTER));
                    CLUSTER{c} = [CLUSTER{c} fi];
                end
            end
        end
    end
end

我不确定这是否是最好的方法,但我的想法是,这应该可以通过某种更新算法来实现。从查看节点1开始。查找所有以节点1为群集的节点

clusteredNbr = find(F(1,:)>=2000); (a)
这将为您提供与节点1群集的所有节点的节点号。然后通过对所有新节点重复
(a)
,查找使用
clusteredNbr
群集的所有节点。然后可以将这些节点添加到与
clusteredNbr
中的旧节点相同的向量中。这里可能有一些重复项,但可以稍后删除。然后检查此结果向量中的新唯一节点。如果有,对这些部件重复
(a)
。继续,直到找到第一个集群中的所有节点。然后您就知道第一个集群中的任何节点都不会与其他节点集群在一起


对下一个集群重复此过程,以此类推。这样做的好处是,您可以使用
find
而不是
ismember
,并且操作可以矢量化,这使得您只能运行一个for循环。

您说
ismember
就是这个瓶颈。通过计算
ismember
一次(对于fi和fj),您的运行时将大大加快。进一步的矢量化操作通常更快,因此您应该尝试对代码进行矢量化。我不是100%确定你想要什么,你想要多少个集群。你想要两个集群吗?一个集群的F(fi,fj)>2000,其余集群的F(fi,fj)>2000。订单重要吗?还是您只想创建任何订单数量的一些集群?谢谢您的回复。我想澄清的是,我正在创建一个不断增长的细胞阵列簇,其中的细胞簇{I}包含由由于它们之间有足够的F而连接的点形成的簇。这些点之间的F不足的点不放置在单元阵列簇上,并被视为噪声。为了说明这一点,假设我们有点1和2,F(1,2)=2500。它们是第一个放在集群中的,这样它就变成了CLUSTER={[1,2]}。接下来,点1和点3的F(1,3)=1500。因此,由于第3点,单元格数组再次变为CLUSTER={[1,2]}。为了澄清,您需要一个一维非嵌套单元格,其中单元格中的每个元素都是坐标[i,j](或者更确切地说,每个元素对应一个1x2矩阵)?如果这是正确的,请回答我认为不太正确。集群可能会导致集群={[集群1中的点][集群2中的点][集群3中的点]…[集群n中的点]}我可以给出一个例子。F是沿对角线五点的镜像矩阵。假设F=[020000210018001000;2000,0220015001700;21002200,013001400;1800150013000200;1000170014002200,0],那么单元阵列集群={[1,2,3][4,5]}表示F>=2000。非常感谢您的建议。我会努力做到这一点,然后带着我得到的任何结果回来。