K-RNN详细算法请参考Manifold-ranking based retrieval using k-regular nearest neighbor graph论文中的算法1,算法2有待更新。
算法1介绍:
Matlab代码:
function G = kRNN(W,m,k)
% W 表示图像之间的相似度权值矩阵
% m 表示图所有顶点中顶点的最大度
% k 表示所有顶点的平均度
% G 表示k-RNN图的权值矩阵
num_vertices = size(W, 1);% 节点数目
% 排序
sorted_W = zeros(num_vertices, num_vertices);% 保存排序后相似度权值矩阵
sorted_Position = zeros(num_vertices, num_vertices);% 保存排序后原始节点位置
for i = 1: num_vertices
[sorted, position] = sort(W(i, :), 2);% 按照行排序
sorted_W(i, :) = sorted;
sorted_Position(i, :) = position;
end
T = ones(num_vertices, num_vertices);
% 初始化
G = zeros(num_vertices,num_vertices);
maxDegree = k;
averageDegree = 0;
%搜索图
while (averageDegree < k) && (maxDegree < m)
for vertices_i = 1 : num_vertices
% 获取排序后的W第vertices_i行中的前maxDegree个元素
maxDegree_vertices = sorted_Position(vertices_i, 1 : maxDegree);
for maxDegree_i = 1 : maxDegree
% 读取maxDegree_vertices中的每一个元素
maxDegree_element = maxDegree_vertices(maxDegree_i);
% 判断vertices_i与maxDegree_element节点之间是否存在边
if T(vertices_i, maxDegree_element) == 1
% 存在边,则查找maxDegree_element行的前maxDegree个元素中是否存在vertices_i元素
pos = find(sorted_Position(maxDegree_element, 1 : maxDegree) == vertices_i);
if isempty(pos) == 0
% 存在,则在G中添加边
G(vertices_i, maxDegree_element) = W(vertices_i, maxDegree_element);
% 在T中剔除边
T(vertices_i, maxDegree_element) = 0;
else
continue;
end
else
% 不存在边
continue;
end
end
end
% 更新maxDegree
maxDegree = maxDegree + 1;
% 更新averageDegree,统计G中不为0元素的个数,然后再除以节点的总个数
averageDegree = sum(sum(G( : ) ~= 0)) / num_vertices;
end
return;
end
测试:
clear;
clc;
load('D')
W = D;
k = 10;
m = 2 * k;
G = kRNN(W,m,k);
D为.mat格式的二维对称矩阵,主对角线上的所有元素为0,其他元素表示两个个体之间的距离值。里面的数据例如如下: