数模笔记之“Q值分配法、比例加惯例(D‘Hondt)” matlab代码

例:某学校有3个系,共200名学生,甲系103人,乙系63人,丙系34人,使用Q值法分配法、“Q值分配法+D’Hondt” 分配21个席位。

%Q值分配法
clc
clear
all=200;
all_des=21;
peo=[103 53 43];
p=floor(peo./all*all_des);
rest=all_des-sum(p);
for i=1:rest
    Q=peo.^2./(p.*(p+1));
    
    [M,I]=max(Q);
    p(I)=p(I)+1;
end
p

​ 但是Q值分配法在名额较少或者参与分配部门比较多的时候,可能存在较大不公平,故提出来用"D‘Hondt +Q值分配法“,代码如下。具体讲解见参考资料。

%D'Hondt +Q值分配法
clc
clear
all=200;
all_des=21;
peo=[103 53 43];

[m,n]=size(peo);
p1=zeros(m,n); %每部门分配的名额
[M1,I1]=max(peo);
p1(I1)=p1(I1)+1; %先把名额分配给人数最多的一组
while sum(p1)<all_des %先用D'Hondt法,逐一分配名额,直至每个系都有至少一个分配名额或分配名额数达到要求值
    if ismember(0,p1)
        [M2,I2]=max(peo./(p1+1));
        p1(I2)=p1(I2)+1;
    else
        break
    end
end
if sum(p1)==all_des
    disp(['使用D\''Hondt方法,且分配名额为',num2str(p1)]);
    return
else  %使用Q值分配方法
        p=floor(peo./all*all_des);
    rest=all_des-sum(p);
    for i=1:rest
        Q=peo.^2./(p.*(p+1));
        [M,I]=max(Q);
        p(I)=p(I)+1;
    end
    disp(['使用q值方法,且分配名额为',num2str(p)]);
end

参考资料:
https://wenku.baidu.com/view/efe0e5b702d276a201292e0c.html

MATLAB中,我们可以使用不同的选举算,如D'Hondt(也称为圣歌)、比例代表制或Quota方(Q),来按照学生的宿舍人数公平地分配10位委员会成员。这里我们分别演示如何使用这三种方: 1. **D'Hondt**: ```matlab % 学生数据 num_students = 1000; num_A = 235; num_B = 333; num_C = 432; % 总席位 total_seats = 10; % 计算每个宿舍的剩余票数 remaining_votes_A = num_A; remaining_votes_B = num_B; remaining_votes_C = num_C; % 初始化结果数组 committee_A = zeros(1); committee_B = zeros(1); committee_C = zeros(1); while sum(committee_A + committee_B + committee_C) < total_seats % 找出当前剩余票数最多的宿舍 [max_votes, max_index] = max([remaining_votes_A, remaining_votes_B, remaining_votes_C]); % 分配席位 switch max_index case 1 committee_A = committee_A + 1; remaining_votes_A = remaining_votes_A - (total_seats - sum(committee_A + committee_B + committee_C)); case 2 committee_B = committee_B + 1; remaining_votes_B = remaining_votes_B - (total_seats - sum(committee_A + committee_B + committee_C)); case 3 committee_C = committee_C + 1; remaining_votes_C = remaining_votes_C - (total_seats - sum(committee_A + committee_B + committee_C)); end end % 结果显示 disp(['A宿舍得到 ' num2str(committee_A) ' 名委员']); disp(['B宿舍得到 ' num2str(committee_B) ' 名委员']); disp(['C宿舍得到 ' num2str(committee_C) ' 名委员']); ``` 2. **Q(Quota Method)**: ```matlab % 计算每个宿舍的初始基数 base_A = floor(num_A / total_seats); base_B = floor(num_B / total_seats); base_C = floor(num_C / total_seats); % 剩余基数 remaining_bases = [num_A - base_A * total_seats, num_B - base_B * total_seats, num_C - base_C * total_seats]; % 初始化结果数组 committee_A = zeros(1, total_seats); committee_B = zeros(1, total_seats); committee_C = zeros(1, total_seats); for i = 1:total_seats % 看哪栋宿舍有更多的剩余票 [max_remaining, max_index] = max(remaining_bases); % 分配委员 if max_remaining > 0 committee(max_index, i) = 1; remaining_bases(max_index) = remaining_bases(max_index) - 1; else break; % 当所有宿舍都达到分配名额时停止 end end % 结果显示 disp(['A宿舍得到 ' mat2str(committee_A) ' 名委员']); disp(['B宿舍得到 ' mat2str(committee_B) ' 名委员']); disp(['C宿舍得到 ' mat2str(committee_C) ' 名委员']); ``` **相关问题--:** 1. 这些方在选择过程中是如何保证公平性的? 2. D'Hondt和 Q 的主要区别是什么? 3. 如果想要改变总席位,如何调整上述代码
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值