延迟接受算法与Matlab实现(二)

博主此前因考研和毕业未对DA算法进行一对一或一对多拓展,现有空余时间着手进行。指出两个偏好矩阵为mxm正方形矩阵时做一对一匹配最稳定,对象集个数不等时需一对多或多对一匹配。介绍代码思路是在原有基础上加外循环,还给出总算法代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

由于之前忙着考研和毕业的事情,一直没有对DA算法进行一对一或者一对多的拓展,现在稍微有了一点富余的时间,打算把这一部分内容给做出来。
我自己的理解是,如果两个偏好矩阵都是mxm的正方形矩阵,即需要匹配的两个对象集的对象个数都相等,在这种情况下只需进行一对一的匹配,因为这种匹配关系这时是最稳定的。只有当两个对象集的对象个数不等的时候需要进行一对多或者多对一的匹配。关于这一部分,如果有不同想法的同好,欢迎与我交流。
整个代码的思路就是在(一)的基础上加了一个外循环,即内部依然是一对一的匹配,再一次匹配后,将已经获得匹配的对象剔除,再进行下一次循环匹配,直到所有匹配完成。这一步在代码中的处理就是令已经匹配对象的偏好度为零。
下面总的算法的代码

function [pairing_vec,conv_vec,time,sta]=DAalgs(PL_matr1,PL_matr2)
%完成延迟接受算法的一对多或者多对一匹配
%此种情况更适合于男女数不对等的情况下,为多余的男(女)进行匹配
%time--叠代次数;sta--稳定性

[m1,n1] = size(PL_matr1);%woman
[m2,n2] = size(PL_matr2);%man
pairing_vec = zeros(m1,m2);%初始化配对结果

number_min = min(m1,m2);%求两个列表中的较小值,求人数少的一方
number_max = max(m1,m2);%求两个列表中的较大值

man_reject = ones(1,m2);%标记man被拒绝
man_rejection_list = zeros(m2,n2);%清空man的拒绝列表
woman_proposal_list = zeros(m1,n1);%清空woman的可选列表
con_vec = zeros(m1,m2);
num = 1;
while( number_max > nozero(pairing_vec) )%人数多的一方的数目不等于配对矩阵中的非零数目时进行循环配对
    for i = 1:m1
        for j = 1:m2
            if(pairing_vec(i,j))
                if m1>m2
                    %man_rejection_list(i,j) = 1;
                    PL_matr1(i,:) = 0;
                    PL_matr2(:,i) = 0;
                else
                    %man_rejection_list(i,j) = 1;
                    PL_matr1(:,j) = 0;
                    PL_matr2(j,:) = 0;
                end
            end
        end
    end
    pairing_vec = zeros(m1,m2);%初始化配对结果
    man_reject = ones(1,m2);%标记man被拒绝
    man_rejection_list = zeros(m2,n2);%清空man的拒绝列表
    woman_proposal_list = zeros(m1,n1);%清空woman的可选列表
    
    
    while( number_min > nozero(pairing_vec) )%人数少的一方的数目不等于配对矩阵中的非零数目时进行循环配对

    %index1 = 0;index2 = 0;
    for i = 1:m2   
        mark_reject = man_reject(1,i);
        index1 = 0;%index2 = 0;
        if (mark_reject == 1) %&&(man_flag(1,i) == 0)) %如果mani被拒绝       
            for j = 1:m1
                if (man_rejection_list(i,j) == 0) %&& (PL_matr2(i,j) > 0)%如果womanj未拒绝mani
                    index = PL_matr2(i,j); % 统计mani对womanj的喜欢程度                
                    if index > index1
                        index1 = index;
                        %index2 = j;                    
                    end 
                    man_reject(1,i) = 0; %标记mani为未拒绝
                    %break;
                end          
            end
            for j = 1:m1
                %if woman_flag(1,j) == 0
                    if (PL_matr2(i,j) == index1) %&& (PL_matr2(i,j) > 0)
                        woman_proposal_list(j,i) = 1;%找到对mani喜欢程度最大的womanj,并将mani加入womanj的可选列        
                        %man_reject(1,i) = 0; %标记mani为未拒绝
                        %break;
                    else
                        continue;
                    end
                %end
            end
        else
          continue;  
        end    
    end %生成woman_proposal_list

    %index1 = 0;index2 = 0;
    for j = 1:m1
        woman_proposal = sum(woman_proposal_list(j,:));
        index1 = 0 ;%index2 = 0 ;
        if (woman_proposal ~= 0) %&& (PL_matr1(j,i) > 0)%&&(woman_flag(1,j) == 0)) %如果woman的可选列表大于0,即有可选对象        
            for i = 1:m2
                %if man_flag(1,i) == 0
                    if (woman_proposal_list(j,i) == 1)  
                        index = PL_matr1(j,i); % 统计mani对womanj的喜欢程度            
                        if (index > index1) %&& (man_flag(1,i) == 0))
                        index1 = index;
                        %index2 = i;
                        end  %找到对womanj喜欢程度最大的mani
                    end
                %end
            end
            for i = 1:m2
                %if man_flag(1,i) == 0
                    if (woman_proposal_list(j,i) == 1) %&& (PL_matr1(j,i) > 0)
                        if (PL_matr1(j,i) ~= index1)%将对womanj除了喜欢程度最大的man之外的所有man进行移除
                            woman_proposal_list(j,i) = 0; %从选择列表中移除
                            man_reject(1,i) = 1;%标记为被拒绝
                            man_rejection_list(i,j) = 1;%加入被拒绝列表                       
                        else
                             continue;
                        end                   
                    else
                        continue;
                    end
    %             else
    %                 continue;
    %             end
            end
        else
            continue;
        end

        woman_proposal = sum(woman_proposal_list(j,:));
        index3 = 0;
        index4 = 0;
        if(woman_proposal > 1)%女生的可选列表不止有一个,但是此时只能保留一个
            for i = 1:m2
                if (woman_proposal_list(j,i) == 1)
                    index2 = PL_matr1(j,i);
                    if index2 > index3
                        index3 = index2 ;
                        index4 = i;                       
                    end                   
                else
                    continue;
                end
            end
            for i = 1:m2
                if(i ~= index4)
                    woman_proposal_list(j,i) = 0; %从选择列表中移除
                    man_reject(1,i) = 1;%标记为被拒绝
                    man_rejection_list(i,j) = 1;%加入被拒绝列表
                end
            end
        end
    end   %保证woman_proposal_list每一行只有一个1


    pairing_vec = woman_proposal_list;%%进行配对
    
    conv_vec = pairing_vec;
    
    num = num+1;
     
    

    

    end
    
    con_vec =  con_vec+pairing_vec;
    number_min = min(number_min,number_max - nozero(con_vec));
    pairing_vec = con_vec;
    
end
    time = num;
    sta1 = 0;
    sta2 = 0;
    for i = 1:m1
        for j = 1:m2
            if (woman_proposal_list(i,j) == 1) 
                sta1 = sta1+woman_proposal_list(i,j)*PL_matr1(i,j);
            end
        end
    end
    for i = 1:m1
        for j = 1:m2
            if (woman_proposal_list(i,j) == 1) 
                sta2 = sta2+woman_proposal_list(i,j)*PL_matr2(j,i);
            end
        end
    end

    sta = sta1 + sta2;

    function result=nozero(A) %求矩阵中非零个数的函数

    B = (A~=0);

    result=sum(B(:));

    end

end

欢迎各位与我私信交流,如有错误,请指正。

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值