KM算法matlab仿真并画图显示匹配过程

KM算法matlab仿真并画图显示匹配过程

[原理讲解及实例讲解参见我上传的资源PPT](https://download.csdn.net/download/jane0819/87232208)

  1. KM.m文件可直接运行;
  2. plotMatch.m画图显示每一步匹配结果;
    仿真代码参考博文

在基础上增加了三种边权值的仿真:

  1. 自然数稠密矩阵
  2. 创造稀疏矩阵
  3. 模拟0~1概率矩阵
  4. 增加时间复杂度的计数
  5. 增加关键步骤的注释
  6. 画图视频保存
function match = KM(r)
    global g_map;
    global g_m;
    global g_n;
    global g_label_value_x;
    global g_label_value_y;
    global g_match_x;
    global g_match_y;
    global g_min_weight_diff;
    global g_visible_x;
    global g_visible_y;
    global times;
    
%% 模拟边权值
    rng('default');
%     r = round(rand(10,15)*50)     % 初始化边权值
%     r(r>15) = 0                   % 创造稀疏矩阵
    r = (rand(10,15)*1)           % 模拟0~1概率矩阵
    r = round(r*30);              % 放大截断0~1概率矩阵
%% 保存图像到视频    
    bSaveAVI = 0;                
    if bSaveAVI
        aviname = input('input the file name for avi: ','s');
        AVIOBJ = VideoWriter(aviname);   
        AVIOBJ.Quality = 60;
        AVIOBJ.FrameRate = 16;
        open(AVIOBJ);
    end
    
%% 是否画图    
    bPlotMatch = 0;
    
%% 初始化左侧顶标值 = g_map每行最大值
    [g_m,g_n] = size(r);
    g_map = r; % 二分图的权值
    g_label_value_x = zeros(g_m,1);
    g_label_value_y = zeros(g_n,1);
    g_match_x = ones(g_m,1)*-1;
    g_match_y = ones(g_n,1)*-1;

    for i = 1:g_m
        for j = 1:g_n
            if g_label_value_x(i) < g_map(i,j)
                g_label_value_x(i) = g_map(i,j);
            end
        end
    end
    
%% KM-algorithm
    times = 0; % 记录时间复杂度
    for i = 1:g_m
        times = times + 1;
        while(1)
            g_min_weight_diff = 10^10;
            g_visible_x = zeros(g_m,1);
            g_visible_y = zeros(g_n,1);
            
            if dfs(i) || g_min_weight_diff == 10^10 || g_label_value_x(i) == 0  
                % 要么找到匹配项dfs(i)==true;
                % 要么无任何可匹配项,g_min_weight_diff == 10^10无相等子图;
                % 要么初始匹配即==0
                break;
            end
            
            % 被访问过的顶标值进行修改
            for j = 1:g_m
                if g_visible_x(j)
                    g_label_value_x(j) = g_label_value_x(j) - g_min_weight_diff;
                end
            end
            for j = 1:g_n
                if g_visible_y(j)
                    g_label_value_y(j) = g_label_value_y(j) + g_min_weight_diff;
                end
            end           
        end   
        if bPlotMatch
            plotMatch(r,g_match_x);
            if bSaveAVI 
                frame = getframe(gca);   %把图像存入视频文件中
                im = frame2im(frame);
                writeVideo(AVIOBJ,im);
                pause(3);
            end
        end
    end
    match = g_match_x;
    if bPlotMatch
        plotMatch(r,match);
        if bSaveAVI
            close(AVIOBJ); %%关闭视频文件句柄
        end
    end
    disp(['n^3 = ',num2str((min([g_m;g_n]))^3),', 时间复杂度 = ',num2str(times)]);
 
 
function res = dfs(i)
%% 深度优先搜索
    global g_map;
    global g_m;
    global g_n;
    global g_label_value_x;
    global g_label_value_y;
    global g_match_x;
    global g_match_y;
    global g_min_weight_diff;
    global g_visible_x;
    global g_visible_y;
    global times;
 
    g_visible_x(i) = 1;
    for j = 1:g_n
        times = times + 1;
        if(~g_visible_y(j) && g_map(i,j) > 0)
            tmp = g_label_value_x(i) + g_label_value_y(j) - g_map(i,j); 
            if tmp < 10^-5              
                % 顶标和=边权值,即tmp==0
                g_visible_y(j) = 1;
                if(g_match_y(j) == -1 || dfs(g_match_y(j)))
                    g_match_x(i) = j;
                    g_match_y(j) = i;
                    res = true;
                    return
                end
            elseif tmp > 0
                % 顶标和<边权值
                if tmp < g_min_weight_diff
                    g_min_weight_diff = tmp; % 边权和顶标最小的差值
                end
            end
        end
    end
    res = false;
 
 

function plotMatch(r,match)
    global g_label_value_x;
    global g_label_value_y;
    figure(1)
    clf
    [g_m,g_n] = size(r);
    for i = 1:g_m
        A(i,1) = 5;
        A(i,2) = 5*i;
        hold on
        plot(A(i,1),A(i,2),'k.', 'MarkerFaceColor','k', 'MarkerSize',30)
        text(A(i,1)-5,A(i,2),['A' num2str(i) '=' num2str(g_label_value_x(i))]);
    end
    for i = 1:g_n
        B(i,1) = 25;
        B(i,2) = 5*i;
        hold on
        plot(B(i,1),B(i,2),'k.', 'MarkerFaceColor','k', 'MarkerSize',30)
        text(B(i,1)+3,B(i,2),['B' num2str(i) '=' num2str(g_label_value_y(i))]);
    end
    xlim([-10,40]);ylim([0,5*g_n+5]);
    for i = 1:g_m
        for j = 1:g_n
            hold on;
            plot([A(i,1),B(j,1)],[A(i,2),B(j,2)],'y-','LineWidth',2);
            text(A(i,1)+0.7*(-A(i,1)+B(j,1)),A(i,2)+0.7*(-A(i,2)+B(j,2)),num2str(r(i,j)));
        end
        hold on
        if match(i) > 0
            plot([A(i,1),B(match(i),1)],[A(i,2),B(match(i),2)],'b-','LineWidth',4);
        end
    end
    pause(0.6);
    
end

你可能感兴趣的:(matlab,算法,开发语言,机器学习,动态规划)