如何在 MATLAB 中对连接的点进行聚类?

2024-02-26

想象一下,我们有很多点,其中一些点连接在一起,我们想要将它们聚类。

请看下图。

如果我们有“连接矩阵“点,我们如何将它们聚类为两组(连接点组)?

ConnectivityMatrix=
                    [1 2
                     1 3
                     2 4
                     2 3
                     2 1
                     3 1
                     3 2
                     3 4
                     4 3
                     4 2
                     5 8
                     5 7
                     5 6
                     6 5
                     6 7
                     7 6
                     7 5
                     7 8
                     8 7
                     8 5]

最终结果应该是节点1,2,3,4在第一组(集群)和节点5,6,7,8在第二组(集群)中。


这里有一些代码可以帮助您入门。我基本上实现了深度优先搜索……无论如何,这是一个非常粗略的实现。

深度优先搜索 http://en.wikipedia.org/wiki/Depth-first_search是一种用于遍历树的算法。图本质上是树的一种特殊情况,其中存在连接回根的叶节点。深度优先搜索的基本算法如下:

  • 从树的根开始并将其添加到堆栈中
  • 对于连接到根的每个节点,将其添加到堆栈中并将其放入已访问节点列表中
  • While there is still a node on the stack...
    1. 从堆栈中弹出一个节点
    2. 检查访问过的节点列表。如果这是我们已经访问过的节点,则跳过。
    3. 否则,访问连接到我们弹出的该节点的任何节点并将其添加到堆栈中

如果我们有断开连接像上面的图表一样,我们基本上运行深度优先搜索多次。每次都针对一个簇。在一次深度优先搜索结果之后,我们将发现属于一个集群的节点。我们再次使用我们尚未触及的任何节点重新启动深度优先搜索,该节点将是来自我们尚未访问过的另一个集群的节点。由于您的图形结构中显然有两个集群,因此我们必须运行深度优先搜索两次。这通常被称为查找总体图中的所有连通分量.

要查找连接的组件,我执行了以下步骤:

  1. 创建连接矩阵
  2. 初始化一个布尔列表,告诉我们是否访问过图中的节点
  3. 初始化一个空的簇列表
  4. 初始化一个空堆栈,其中包含我们应该访问的节点。
  5. While there is at least one node we need to visit...
    • 找到这样一个节点
    • 初始化我们的堆栈以包含该节点
    • While our stack is not empty
      1. 从堆栈中弹出一个节点
      2. 如果我们已经访问过这个节点,则继续
      3. 否则标记为已访问
      4. 检索与该节点连接的所有节点
      5. 删除(4)中不在栈中的节点
      6. 将这些节点添加到堆栈和集群列表中
  6. 一旦堆栈为空,我们就有了单个集群中包含的所有节点的列表。将此集群添加到最终列表中。
  7. 重复 1 - 6 直到我们访问所有节点

话不多说,这就是代码。请记住,这还没有经过战斗考验。如果您的图形结构会产生错误,则需要您自行修复:)

ConnectivityMatrix = [1 2
                     1 3
                     2 4
                     2 3
                     2 1
                     3 1
                     3 2
                     3 4
                     4 3
                     4 2
                     5 8
                     5 7
                     5 6
                     6 5
                     6 7
                     7 6
                     7 5
                     7 8
                     8 7
                     8 5];

%// Find all possible node IDs
nodeIDs = unique(ConnectivityMatrix(:));

%// Flag that tells us if there are any nodes we should visit
nodeIDList = false(1,numel(nodeIDs));

%// Stores our list of clusters
clusterList = {};

%// Keeps track of how many clusters we have
counter = 1;

%// Stack - initialize to empty
stackNodes = [];

%// While there is at least one node we need to visit
while (~all(nodeIDList))    
    % Find any node
    stackNodes = find(nodeIDList == false, 1);
    % Initialize our stack to contain this node
    nodesCluster = stackNodes;

    %// While our stack is not empty
    while (~isempty(stackNodes))
        % Grab the node off the stack and pop off
        node = stackNodes(end);
        stackNodes(end) = [];        

        %// If we have marked this node as visited, skip
        if (nodeIDList(node))
            continue;
        end

        %// Mark as visited 
        nodeIDList(node) = true;

        %// Retrieve all nodes connected to this node
        connectedNodes = ConnectivityMatrix(ConnectivityMatrix(:,1) == node, :);
        nodesToVisit = unique(connectedNodes(:,2).');

        %// Remove those already visited
        visitedNodes = ~nodeIDList(nodesToVisit);
        finalNodesToVisit = nodesToVisit(visitedNodes);

        %// Add to cluster
        nodesCluster = unique([nodesCluster finalNodesToVisit]);

        %// Add to stack
        stackNodes = unique([stackNodes finalNodesToVisit]);                
    end

    %// Add connected components to its own cluster
    clusterList{counter} = nodesCluster;
    counter = counter + 1;
end

运行此代码后,我们可以像这样显示集群:

celldisp(clusterList)

clusterList{1} =

 1     2     3     4


clusterList{2} =

 5     6     7     8

因此,集群 #1 包含节点 1、2、3、4,而集群 #2 包含节点 5、6、7、8。

请记住,只有像在图表中那样按顺序标记节点时,此代码才会起作用。您不能跳过任何标签编号(即您不能执行 1,2,4,6,9 等。这应该是 1,2,3,4,5)。

祝你好运!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在 MATLAB 中对连接的点进行聚类? 的相关文章

  • 这是 Matlab 的错误吗?你有同样的问题吗? [复制]

    这个问题在这里已经有答案了 我的Matlab版本是R2012a为什么在Matlab中1 1 0 2不等于0 9 这太糟糕了 gt gt 1 1 0 2 0 9 ans 0 这不是Matlab问题 这是一个浮点问题 在 C 或任何符合以下标准
  • 分析 mex 函数

    我刚刚用 c 将 Matlab 程序重写为 mex 函数以加快速度 并取得了出色的结果 这个优化决策是一个非常非常好的主意 无需线程即可将速度提高 20 倍 它仍然让我很好奇 mex 函数将时间花在什么上 并希望找出可能的瓶颈 我正在寻找一
  • 投影 - 将 3d 转换为 2d

    我有问题或者很好 我不知道如何将具有 x y z 值的 3d 点转换为 2d 点 我必须绘制投影 其中我确实有点的 x y z 值 但我不知道如何将它们转换为 2d 以便我可以将它们移动到我的轴上 我一直在浏览维基和谷歌 但是我不太确定应该
  • 检测 MATLAB 帮助浏览器

    我想为大型 MATLAB 应用程序创建一些 HTML 文档 主要在 MATLAB 帮助浏览器 从 11b 开始的任何版本的 MATLAB 中 查看 这将有一些自定义 CSS 但没有什么非常复杂的 但是 我还希望在其他浏览器中可以查看相同的文
  • 使用 D3.js SVG 进行 2D 多边形布尔运算

    我有 2 个使用 D3 js 创建的简单面积图 数据和代码如下 让我们称它们为Graph A Graph B 我想用它们根据它们的相交方式创建 3 个新路径 多边形 Path 1 Graph A Graph B Path 2 Graph B
  • 在 GUI MATLAB 中为静态文本赋值

    如何在 MATLAB GUI 中为静态文本赋值 双击指南中的文本打开属性编辑器 然后编辑 String 财产 您还可以设置 Tag 属性 以便您可以在 GUI 运行时对其进行编辑 如果您将标签设置为mytext 您可以将静态文本更改为 My
  • Floyd Warshall 算法的时间复杂度

    Skiena 的算法书包含以下解释弗洛伊德 沃歇尔算法 http en wikipedia org wiki Floyd E2 80 93Warshall algorithm floyd adjacency matrix g int i j
  • 具有表面梯度的颜色 matplotlibplot_surface 命令

    我想将 surf 命令从MATLAB到plot surface命令中绘图库 我面临的挑战是使用时cmapplot surface 命令中的函数用渐变为表面着色 这里是matlab script Matlab Commands x 5 25
  • 隐藏图中某些图形对象的 MATLAB 图例条目

    MATLAB 图例列出了绘图中的所有内容 包括您在绘图上放置的指南 绕过这个问题的软糖就是要做的 Plot Add legend Add guidelines 然而 MATLAB 将最新的行放在前面 这意味着指南将位于显示的数据之上 丑陋且
  • MATLAB:让audioplayer()在函数结束后继续播放

    我正在使用使用以下子函数的代码 function playTone duration toneFreq Generate a tone samplesPerSecond 44100 the bit rate of the tone y si
  • iOS 将 URL 中的音频分成帧

    我正在 iOS 上开发一个简单的网络广播应用程序 具有非常简单的语音 音乐识别功能 主要思想是一个收音机 它播放来自 url 的信号 同时检查正在广播的信号类型 当它检测到语音时 它会改变频道等等 我使用 Storyboards 和 AVF
  • 使用 sprintf 打印元素数量可变的向量

    在下面的代码中 我可以打印向量中的所有元素item用空格分隔为 item 123 456 789 sprintf d d d item ans 123 456 789 我怎样才能做到这一点而不必输入那么多 d作为元素的数量item 最简单的
  • 为什么使用 Dijkstra 算法而不是最佳(最便宜)优先搜索?

    从我到目前为止所读到的来看 这最佳优先搜索 https en wikipedia org wiki Best first search在找到到达目标的最短路径方面似乎更快 因为 Dijkstra 算法在遍历图时必须放松所有节点 是什么让 D
  • 同时使用两个数组中的元素的过滤器

    假设我们有两个大小相同的数组 A and B 现在 我们需要一个过滤器 对于给定的掩码大小 从以下位置选择元素A 但删除掩码的中心元素 并在其中插入相应的元素B 所以 3x3 伪掩码 看起来类似于 A A A A B A A A A 对平均
  • 计算向量中连续 1 和 0 的数量

    在 Matlab 中我有一个如下所示的向量 0 0 1 1 0 0 0 1 1 0 0 0 0 1 1 1 0 0 0 0 1 0 1 我现在要做的是统计这个向量中1的个数 连续的 1 算作 1 此外 我还想计算 1 之间 0 的平均值和中
  • 梯度下降Matlab实现

    我已经浏览了堆栈溢出中的许多代码 并在同一行上编写了自己的代码 这段代码有一些问题我无法理解 我正在存储值 theta1 和 theta 2 以及用于分析目的的成本函数 x 和 Y 的数据可以从此下载页 它具有 dat 文件形式的 x 和
  • 如何将 Simulink 编码器编译器版本设置为支持 C++11 的版本?

    我正在尝试将代码合并到 Simulink 及其嵌入式编码器中 该代码使用 C 11 扩展 跑步mex setup c 给出这个输出 mex setup c MEX configured to use Xcode Clang for C la
  • Matlab,如何获取imagesc生成的结果?

    我读过一些类似的文章 但它们不是我想要的 得到imagesc之后的矩阵 https stackoverflow com questions 14364239 get the matrix after imagesc 14364434 143
  • 用均匀的彩色表面替换颜色点

    这是我的数据和当前的绘图 require ggplot2 a rep c 2 5 10 15 20 30 40 50 75 100 each 7 b rep c 0 001 0 005 0 01 0 05 0 5 5 50 10 c c T
  • 通过 DFS 查找图中的强连通分量

    我正在阅读有关 BFS 和 DFS 的图算法 当我分析通过DFS在图中查找强连通分量的算法时 我想到了一个疑问 为了找到强连通分量 书 Coremen 做了什么 首先它在图上运行 DFS 以获得顶点的完成时间 然后再次以完成时间的降序在图的

随机推荐