算法

本文深入探讨了排序算法的时间复杂度和实现方法,包括冒泡排序、选择排序、插入排序、堆排序、快速排序、希尔排序和归并排序。同时,介绍了查找技术,如二分查找和二叉查找树,以及哈希表的概念。文章强调了递归和循环在算法中的作用和区别,并提供了相关资源链接以供进一步学习。
摘要由CSDN通过智能技术生成
时间复杂度

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

排序

学习方法:看一遍动画演示,自己拿笔画图跟着程序手动排序一遍,代码写一遍(最难)
排序算法通常就两步
1.引入一套机制(具有标记含义的变量,独特的比较方式) --将此机制写成一个函数
2.递归的使用这套机制
排序的核心: 如何构建有序序列与无序序列,每一轮比较如何将无序序列元素变成有序序列元素(如何比较)

递归

递归与循环的区别:
1.递归是树状的,层层向自己的子集递推,达到临界条件后回归父集。 表达上可以直接用数学函数表示
2.循环是线性的,就是把已知的这一段数据给遍历完

在排序算法中通常两个结合使用, 循环遍历当前列,然后递进到其子列,子列循环完回归
递归树:递归树往往被用于求解递归方程,简介明了的显示出递归逻辑过程
用于可视化递归算法的流程。当你知道递归的时间复杂度的公式后,就可以画出递归树,有利于你计算递归算法的时间复杂度
在这里插入图片描述
递归与循环的深层理解:
https://www.zhihu.com/question/20418254

二分查找法是递归定义的,因为相同代码片段间,是有父子的层次结构的
所以二分查找法最好用递归写,才是最符合逻辑的
用循环也可以写,但深层次的思维模型中是不契合的

以递归形式定义,但二分查找是尾递归,可改写为循环

如果一个函数中所有递归形式的调用都出现在函数的末尾,我们称这个递归函数是尾递归的。尾递归函数的特点是在回归过程中不用做任何操作。 尾递归都可以改写为循环。

递归和循环的共同点:都是 EIP 在同一段代码段内反复。
两者在模型,重复代码段之间的层次结构,和流程控制方面的差异:
递归是自相似的,两次重复代码段之间,是有结构,层次上的“父子”关系的。
循环,是在同一个层次之内的
递归可以回到数据中点,再向反方向推进

两者在流程控制上有差别: 放到汇编层次,两者的不同就显示出来了
递归通过 ret 可以回到重复代码段的中间位置(由 stack 负责记忆),这个跳转,就是递归相对于循环比较特殊的地方,也导致,递归改成循环的困难点。

冒泡排序:

1.从第一个无序序列元素开始,比较相邻的元素。如果第一个比第二个大,就交换它们两个的位置,得到无序序列最大值
2.重复第一步

选择排序:

1.初始min=无序序列第一位,min与无序序列所有元素进行比较(循环),得到无序序列中的min元素
2.min元素与无序序列第一位元素交换位置,成为有序序列
3.重复第一,二步(最外面的大循环)

逻辑思维过程是从内到外的(循环),所以写的时候循环也是从内到外写的
在这里插入图片描述
冒泡排序:比较与交换位置同时进行,得到最大值的同时,极大值已经在有序序列中。
选择排序:先比较得出最大值,然后再交换位置

比较的对象不同:
冒泡排序是无序序列中相邻之间两个元素比较
选择排序是min元素与无序序列中的所有元素比较

插入排序

在这里插入图片描述
将无序序列的一个元素插入到有序序列的正确位置

1.有序序列最后一位元素, 与无序序列元素依次比较:,每轮比较必定会将无序序列的第一个元素插入到有序序列中(两种插入方法),每轮比较有序序列必定加1,所有元素向后移动为要插入的元素腾出位置

若无序元素小于最右有序元素:这个无序元素从有序最后一个元素开始依次与有序元素比较,找到自己要插入的位置

若无序元素大于最右有序元素,则该无序元素插入有序元素最后(即上面插入的特殊情况,i直接加1,不再与其他有序元素进行比较)

排序的核心: 如何构建有序序列与无序序列,每一轮比较如何将无序序列元素变成有序序列元素(如何比较)

堆排序

1.建立二叉树(最初的无序区)
2.调整(调整为堆)
3.取出(取出堆顶元素)
循环2,3

1.AdjustHeap (L,i): 输入序号i,递归的将以序号i为根节点的子树调整为堆
在这里插入图片描述
2.CreateHeap (L):将整个完全二叉树调整为堆(即for循环调用AdjustHeap
在这里插入图片描述
3.HeapSort(L): 利用堆顶元素排序,即for循环CreateHeap
在这里插入图片描述
在这里插入图片描述

快速排序:

两种方法
1.
https://www.bilibili.com/video/BV1Ab411s7To/?spm_id_from=333.788.videocard.0
课堂上是将最后一个数作为pivot, 引入快慢指针来排
在这里插入图片描述
在这里插入图片描述
2.
在这里插入图片描述
-具体编程机制
1.引入三个变量:pivot中心轴,left左下标,right右下标
2.left从左向右获取值,并与pivot比较:若left大于pivot,则该值放到整个序列右边,开始移动right下标
若left小于pivot,该值不动,继续移动left下标
3.当left下标=right下标时,将pivot放到该位置
4.递进下一子序列
(2.3写为函数QuickSort)

-动画演示:
https://www.bilibili.com/video/BV1at411T75o?from=search&seid=3460101319024924872

-具体代码:
在这里插入图片描述
上一步交换后增加left下标的需求 与 这一步left 是否不用交换直接增加的判断 用一个while循环结合起来了, 一个while循环实现两重需求 NB
在这里插入图片描述

希尔排序:

每次遍历,还是整个数组从头到尾依次遍历(循环括号内的条件) 但每一步比较的对象是根据希尔增量划分出的同一序列的元素
https://www.bilibili.com/video/BV1g441147uP

temp即每组的无序元素, 初始序列为increment(第一组的第一个无序元素), 然后依次加1, 是后面每一组的第一个无序元素。 然后与有序数列的最后一个元素(i - gap)比较

归并排序

在这里插入图片描述
从头开始就是 将每个元素都视为一个数组,

就是不断拆分,合并 然后递归
mergeSort-- 拆分, merge—合并

查找

二分查找

基本思想(结合动画):
在 有序数组

  1. 若带寻找值小于中间值,则在中间值的左半区继续查找
  2. 若带寻找值小于中间值,则在中间值的右半区继续查找
  3. 若带寻找值等于中间值,结束寻找
    不断重复上述过程
    https://www.cnblogs.com/morethink/p/8379475.html

具体实现
1.引入机制:low, high, mid 三个变量作为数组索引,构建“不断缩小的数组” 逻辑
2. 用待寻找值value 与 array[mid]比较,
value>array[mid] : low = mid+1 : 即用索引实现了 “将下一次搜索范围限制在左半区” 的逻辑
value<array[mid] : high =mid-1: 同理

二叉查找树

在这里插入图片描述
把数据直接放在树上, 不要线性的来查找
动态查找: 要查找的集合会动态的发生变化(新增,删除)
静态查找: 要查找的集合 自己本身的元素不会变, --二分查找

二叉查找树: 采用了递归的定义方法
逻辑结构:每个节点为小中大结构的二叉树(每个节点的key值大于左子树节点,小于右子树节点)
注意它不一定是完全二叉树。
基本思想(结合动画):
https://www.cxyxiaowu.com/2008.html
1.创建一个二叉查找树(将一个无序数组的值一个个放到二叉查找树上,一个个创造节点)
2.利用二叉查找树进行搜索(递归的比较,类似于二分查找,父节点就是mid)

具体实现
引入机制: 引入四个指针
创建:s用于创建二叉查找树的节点,p用于决定s插到哪里
查找:T, f用于查找过程,p用于表示查找结果(最终的查找结果就是指针—指向某个节点)

指针s:要插入节点的指针
指针T:路径(标识)指针,指向正在搜索的元素。 表明现在搜寻到哪里了 (最开始是根节点)
指针f: 指向正在搜索元素的父节点 (留退路,如果正在搜索的节点为null,则父节点就是叶子结点了)
指针p: 搜索结果指针:查找成功,则指针p指向该数据元素结点,否则指针p指向查找路径上访问的最后一个结点 即查找成功,p=T, 查找元素不存在,p=f

插入操作:
在这里插入图片描述
二叉查找树不支持重复元素的查找
在这里插入图片描述
平衡二叉查找树(AVL):二叉查找树的形状不固定,如果变成线性排列的话,查找速度变为遍历,效率极低。

过程: 两步构造平衡二叉搜索树
按照平衡二叉树的插入方式插入一个元素,使得整个树不平衡了
1.找到要调整的三个点:判断每棵子树的平衡因子,找到最小不平衡树
从最小不平衡树的根节点走向插入的元素(导致不平衡的元素),最先经过的三个点就是要调整的三个点
2.如何调整(中序遍历+搜索树性质):对整棵树进行一次中序遍历,三个点的前中后位置就是旋转后应该在的位置

哈希表

在这里插入图片描述
哈希表最小应用模型: 引入的一套机制
1.采用含有12个元素的数组作为哈希表的元素内容
2.采用大小为12的动态数组作为哈希表的基本存储结构
3.采取取余法(mod 12)作为哈希算法: 元素值 – 元素地址索引(即哈希值)
4.采用开放定址法的线性探测(满了就向后插)作为 解决哈希冲突的方法

哈希表查询步骤(前三步为创建哈希表):
1.创建哈希表基本存储结构(动态数组),并初始化每个元素的值(null)
动态数组= 头指针+当前元素个数, 申请空间时申请当前元素个数的空间, 当前元素个数即动态数组总长度
在这里插入图片描述
在这里插入图片描述
2.将待存元素值用哈希函数计算,得到元素地址的索引
在这里插入图片描述
在这里插入图片描述
3. 创造哈希表逻辑结构:解决哈希冲突后,将元素值插入到 对应的 索引位置
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
4.使用创建好的哈希表进行搜索:
将值通过哈希算法变为哈希值(索引)后,找不到对应的值, 因为采取了开放地址法来处理哈希冲突,所以要向后继续检验, 直到碰到内容为null(说明真的没这个值)或 等于原哈希值(循环了一轮回到了原来的索引)
则说明没有这个值
否则,返回元素值对应的哈希值(即元素地址的索引)

Reference

https://blog.csdn.net/kexuanxiu1163/article/details/103051357
https://blog.csdn.net/weixin_41190227/article/details/86600821
小甲鱼视频:https://www.bilibili.com/video/BV1Ws411T7Qk?p=91

function [idx, C, sumD, D] = kmeans(X, k, varargin) % varargin:实际输入参量 if nargin 1 % 大于1刚至少有一种距离 error(sprintf('Ambiguous ''distance'' parameter value: %s.', distance)); elseif isempty(i) % 如果是空的,则表明没有合适的距离 error(sprintf('Unknown ''distance'' parameter value: %s.', distance)); end % 针对不同的距离,处理不同 distance = distNames{i}; switch distance case 'cityblock' % sort 列元素按升序排列,Xord中存的是元素在原始矩阵中的列中对应的大小位置 [Xsort,Xord] = sort(X,1); case 'cosine' % 余弦 % 计算每一行的和的平方根 Xnorm = sqrt(sum(X.^2, 2)); if any(min(Xnorm) <= eps * max(Xnorm)) error(['Some points have small relative magnitudes, making them ', ... 'effectively zero.\nEither remove those points, or choose a ', ... 'distance other than ''cosine''.'], []); end % 标量化 Xnorm(:,ones(1,p))得到n*p的矩阵 X = X ./ Xnorm(:,ones(1,p)); case 'correlation' % 线性化 X = X - repmat(mean(X,2),1,p); % 计算每一行的和的平方根 Xnorm = sqrt(sum(X.^2, 2)); if any(min(Xnorm) 1 error(sprintf('Ambiguous ''start'' parameter value: %s.', start)); elseif isempty(i) error(sprintf('Unknown ''start'' parameter value: %s.', start)); elseif isempty(k) error('You must specify the number of clusters, K.'); end start = startNames{i}; % strcmp比较两个字符串 uniform是在X中随机选择K个点 if strcmp(start, 'uniform') if strcmp(distance, 'hamming') error('Hamming distance cannot be initialized with uniform random values.'); end % 标量化后的X Xmins = min(X,1); Xmaxs = max(X,1); end elseif isnumeric(start) % 判断输入是否是一个数 这里的start是一个K*P的矩阵,表示初始聚类中心 CC = start; % CC表示初始聚类中心 start = 'numeric'; if isempty(k) k = size(CC,1); elseif k ~= size(CC,1); error('The ''start'' matrix must have K rows.'); elseif size(CC,2) ~= p error('The ''start'' matrix must have the same number of columns as X.'); end if isempty(reps) reps = size(CC,3); elseif reps ~= size(CC,3); error('The third dimension of the ''start'' array must match the ''replicates'' parameter value.'); end % Need to center explicit starting points for 'correlation'. % 线性距离需要指定具体的开始点 % (Re)normalization for 'cosine'/'correlation' is done at each % iteration.每一次迭代进行“余弦和线性”距离正规化 % 判断是否相等 if isequal(distance, 'correlation') % repmat复制矩阵1*P*1 线性化 CC = CC - repmat(mean(CC,2),[1,p,1]); end else error('The ''start'' parameter value must be a string or a numeric matrix or array.'); end % ------------------------------------------------------------------ % 如果一个聚类丢失了所有成员,这个进程将被调用 if ischar(emptyact) emptyactNames = {'error','drop','singleton'}; i = strmatch(lower(emptyact), emptyactNames); if length(i) > 1 error(sprintf('Ambiguous ''emptyaction'' parameter value: %s.', emptyact)); elseif isempty(i) error(sprintf('Unknown ''emptyaction'' parameter value: %s.', emptyact)); end emptyact = emptyactNames{i}; else error('The ''emptyaction'' parameter value must be a string.'); end % ------------------------------------------------------------------ % 控制输出的显示示信息 if ischar(display) % strvcat 垂直连接字符串 i = strmatch(lower(display), strvcat('off','notify','final','iter')); if length(i) > 1 error(sprintf('Ambiguous ''display'' parameter value: %s.', display)); elseif isempty(i) error(sprintf('Unknown ''display'' parameter value: %s.', display)); end display = i-1; else error('The ''display'' parameter value must be a string.'); end % ------------------------------------------------------------------ % 输入参数K的控制 if k == 1 error('The number of clusters must be greater than 1.'); elseif n 2 % 'iter',\t 表示向后空出8个字符 disp(sprintf(' iter\t phase\t num\t sum')); end % ------------------------------------------------------------------ % Begin phase one: batch reassignments 第一队段:分批赋值 converged = false; iter = 0; while true % Compute the distance from every point to each cluster centroid % 计算每一个点到每一个聚类中心的距离,D中存放的是N*K个数值 D(:,changed) = distfun(X, C(changed,:), distance, iter); % Compute the total sum of distances for the current configuration. % Can't do it first time through, there's no configuration yet. % 计算当前配置的总距离,但第一次不能执行,因为还没有配置 if iter > 0 totsumD = sum(D((idx-1)*n + (1:n)')); % Test for a cycle: if objective is not decreased, back out % the last step and move on to the single update phase % 循环测试:如果目标没有减少,退出到最后一步,移动到第二阶段 % prevtotsumD表示前一次的总距离,如果前一次的距离比当前的小,则聚类为上一次的,即不发生变化 if prevtotsumD 2 % 'iter' disp(sprintf(dispfmt,iter,1,length(moved),totsumD)); end if iter >= maxit, % break(2) break; % 跳出while end end % Determine closest cluster for each point and reassign points to clusters % 决定每一个点的最近分簇,重新分配点到各个簇 previdx = idx; % 大小为n*1 % totsumD 被初始化为无穷大,这里表示总距离 prevtotsumD = totsumD; % 返回每一行中最小的元素,d的大小为n*1,nidx为最小元素在行中的位置,其大小为n*1,D为n*p [d, nidx] = min(D, [], 2); if iter == 0 % iter==0,表示第一次迭代 % Every point moved, every cluster will need an update % 每一个点需要移动,每一个簇更新 moved = 1:n; idx = nidx; changed = 1:k; else % Determine which points moved 决定哪一个点移动 % 找到上一次和当前最小元素不同的位置 moved = find(nidx ~= previdx); if length(moved) > 0 % Resolve ties in favor of not moving % 重新分配而不是移动 括号中是一个逻辑运算 确定需要移动点的位置 moved = moved(D((previdx(moved)-1)*n + moved) > d(moved)); end % 如果没有不同的,即当前的是最小元素,跳出循环,得到的元素已经是各行的最小值 if length(moved) == 0 % break(3) break; end idx(moved) = nidx(moved); % Find clusters that gained or lost members 找到获得的或者丢失的成员的分簇 % 得到idx(moved)和previdx(moved)中不重复出现的所有元素,并按升序排列 changed = unique([idx(moved); previdx(moved)])'; end % Calculate the new cluster centroids and counts. 计算新的分簇中心和计数 % C(changed,:)表示新的聚类中心,m(changed)表示聚类标号在idx中出现的次数 % sort 列元素按升序排列,Xsort存放对的元素,Xord中存的是元素在原始矩阵中的列中对应的大小位置 [C(changed,:), m(changed)] = gcentroids(X, idx, changed, distance, Xsort, Xord); iter = iter + 1; % Deal with clusters that have just lost all their members % 处理丢失所有成员的分簇,empties表示丢失元素的聚类标号 不用考虑 empties = changed(m(changed) == 0); if ~isempty(empties) switch emptyact case 'error' % 默认值,一般情况下不会出现 error(sprintf('Empty cluster created at iteration %d.',iter)); case 'drop' % Remove the empty cluster from any further processing % 移走空的聚类 D(:,empties) = NaN; changed = changed(m(changed) > 0); if display > 0 warning(sprintf('Empty cluster created at iteration %d.',iter)); end case 'singleton' if display > 0 warning(sprintf('Empty cluster created at iteration %d.',iter)); end for i = empties % Find the point furthest away from its current cluster. % Take that point out of its cluster and use it to create % a new singleton cluster to replace the empty one. % 找到离聚类中心最远距离的点,把该点从它的聚类中移走,用它来创建一个新的聚类,来代替空的聚类 % 得到列的最大元素(dlarge),以及该元素在列中的标号(lonely) [dlarge, lonely] = max(d); from = idx(lonely); % taking from this cluster 从当前聚类移走 C(i,:) = X(lonely,:); m(i) = 1; idx(lonely) = i; d(lonely) = 0; % Update clusters from which points are taken % 更新那些点被移走的聚类 [C(from,:), m(from)] = gcentroids(X, idx, from, distance, Xsort, Xord); changed = unique([changed from]); end end end end % phase one % ------------------------------------------------------------------ % Initialize some cluster information prior to phase two % 为第二阶段初始化一些先验聚类信息 针对特定的距离,默认的是欧氏距离 switch distance case 'cityblock' Xmid = zeros([k,p,2]); for i = 1:k if m(i) > 0 % Separate out sorted coords for points in i'th cluster, % and save values above and below median, component-wise % 分解出第i个聚类中挑选的点的坐标,保存它的上,下中位数 % reshape把矩阵分解为要求的行列数m*p % sort 列元素按升序排列,Xord中存的是元素在原始矩阵中的列中对应的大小位置 Xsorted = reshape(Xsort(idx(Xord)==i), m(i), p); % floor取比值小或者等于的最近的值 nn = floor(.5*m(i)); if mod(m(i),2) == 0 Xmid(i,:,1:2) = Xsorted([nn, nn+1],:)'; elseif m(i) > 1 Xmid(i,:,1:2) = Xsorted([nn, nn+2],:)'; else Xmid(i,:,1:2) = Xsorted([1, 1],:)'; end end end case 'hamming' Xsum = zeros(k,p); for i = 1:k if m(i) > 0 % Sum coords for points in i'th cluster, component-wise % 对基于分量对第i个聚类的坐标点求和 Xsum(i,:) = sum(X(idx==i,:), 1); end end end % ------------------------------------------------------------------ % Begin phase two: single reassignments 第二阶段:单独赋值 % m中保存的是每一个聚类的个数,元素和为n % find(m' > 0)得到m'中大于0的元素的位置(索引) % 实际情况(默认情况下)changed=1:k changed = find(m' > 0); lastmoved = 0; nummoved = 0; iter1 = iter; while iter < maxit % Calculate distances to each cluster from each point, and the % potential change in total sum of errors for adding or removing % each point from each cluster. Clusters that have not changed % membership need not be updated. % 计算从每一个点到每一个聚类的距离,潜在由于总距离发生变化移除或添加引起的错误。 % 那些成员没有改变的聚类不需要更新。 % % Singleton clusters are a special case for the sum of dists % calculation. Removing their only point is never best, so the % reassignment criterion had better guarantee that a singleton % point will stay in its own cluster. Happily, we get % Del(i,idx(i)) == 0 automatically for them. % 单独聚类在计算距离时是一个特殊情况,仅仅移除点不是最好的方法,因此重新赋值准则能够保证一个 % 单独的点能够留在它的聚类中,可喜的是,自动有Del(i,idx(i)) == 0。 switch distance case 'sqeuclidean' for i = changed % idx存放的距离矩阵D中每一行的最小元素所处的列,也即位置 mbrs = (idx == i); sgn = 1 - 2*mbrs; % -1 for members, 1 for nonmembers % 表示只有一个聚类 if m(i) == 1 % prevent divide-by-zero for singleton mbrs 防止单个成员做0处理 sgn(mbrs) = 0; end Del(:,i) = (m(i) ./ (m(i) + sgn)) .* sum((X - C(repmat(i,n,1),:)).^2, 2); end case 'cityblock' for i = changed if mod(m(i),2) == 0 % this will never catch singleton clusters ldist = Xmid(repmat(i,n,1),:,1) - X; rdist = X - Xmid(repmat(i,n,1),:,2); mbrs = (idx == i); sgn = repmat(1-2*mbrs, 1, p); % -1 for members, 1 for nonmembers Del(:,i) = sum(max(0, max(sgn.*rdist, sgn.*ldist)), 2); else Del(:,i) = sum(abs(X - C(repmat(i,n,1),:)), 2); end end case {'cosine','correlation'} % The points are normalized, centroids are not, so normalize them normC(changed) = sqrt(sum(C(changed,:).^2, 2)); if any(normC 0 % Resolve ties in favor of not moving % 重新分配而不是移动 确定移动的位置 moved = moved(Del((previdx(moved)-1)*n + moved) > minDel(moved)); end if length(moved) == 0 % Count an iteration if phase 2 did nothing at all, or if we're % in the middle of a pass through all the points if (iter - iter1) == 0 | nummoved > 0 iter = iter + 1; if display > 2 % 'iter' disp(sprintf(dispfmt,iter,2,nummoved,totsumD)); end end converged = true; break; end % Pick the next move in cyclic order moved = mod(min(mod(moved - lastmoved - 1, n) + lastmoved), n) + 1; % If we've gone once through all the points, that's an iteration if moved 2 % 'iter' disp(sprintf(dispfmt,iter,2,nummoved,totsumD)); end if iter >= maxit, break; end nummoved = 0; end nummoved = nummoved + 1; lastmoved = moved; oidx = idx(moved); nidx = nidx(moved); totsumD = totsumD + Del(moved,nidx) - Del(moved,oidx); % Update the cluster index vector, and rhe old and new cluster % counts and centroids idx(moved) = nidx; m(nidx) = m(nidx) + 1; m(oidx) = m(oidx) - 1; switch distance case 'sqeuclidean' C(nidx,:) = C(nidx,:) + (X(moved,:) - C(nidx,:)) / m(nidx); C(oidx,:) = C(oidx,:) - (X(moved,:) - C(oidx,:)) / m(oidx); case 'cityblock' for i = [oidx nidx] % Separate out sorted coords for points in each cluster. % New centroid is the coord median, save values above and % below median. All done component-wise. Xsorted = reshape(Xsort(idx(Xord)==i), m(i), p); nn = floor(.5*m(i)); if mod(m(i),2) == 0 C(i,:) = .5 * (Xsorted(nn,:) + Xsorted(nn+1,:)); Xmid(i,:,1:2) = Xsorted([nn, nn+1],:)'; else C(i,:) = Xsorted(nn+1,:); if m(i) > 1 Xmid(i,:,1:2) = Xsorted([nn, nn+2],:)'; else Xmid(i,:,1:2) = Xsorted([1, 1],:)'; end end end case {'cosine','correlation'} C(nidx,:) = C(nidx,:) + (X(moved,:) - C(nidx,:)) / m(nidx); C(oidx,:) = C(oidx,:) - (X(moved,:) - C(oidx,:)) / m(oidx); case 'hamming' % Update summed coords for points in each cluster. New % centroid is the coord median. All done component-wise. Xsum(nidx,:) = Xsum(nidx,:) + X(moved,:); Xsum(oidx,:) = Xsum(oidx,:) - X(moved,:); C(nidx,:) = .5*sign(2*Xsum(nidx,:) - m(nidx)) + .5; C(oidx,:) = .5*sign(2*Xsum(oidx,:) - m(oidx)) + .5; end changed = sort([oidx nidx]); end % phase two % ------------------------------------------------------------------ if (~converged) & (display > 0) warning(sprintf('Failed to converge in %d iterations.', maxit)); end % Calculate cluster-wise sums of distances nonempties = find(m(:)'>0); D(:,nonempties) = distfun(X, C(nonempties,:), distance, iter); d = D((idx-1)*n + (1:n)'); sumD = zeros(k,1); for i = 1:k sumD(i) = sum(d(idx == i)); end if display > 1 % 'final' or 'iter' disp(sprintf('%d iterations, total sum of distances = %g',iter,totsumD)); end % Save the best solution so far if totsumD 3 Dbest = D; end end end % Return the best solution
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值