本篇博客请结合《数学模型(第四版)》,姜启源版教材第八章第四节内容阅读。
在处理席位分析问题时,常使用Huntington除数法来进行处理。在书中279~281的学习中,我们了解到了怎样去比较一个分配结果的不公平度,以及一个较惯例分配法更加公平的“Q值法”。那么,下面我将介绍一种处理这类问题的通用方法,Huntington除数法。
Edward Vermilye Huntington(1874~1952),1922年获得哈佛大学博士学位。20世纪20年代,他对这个问题做了具体的研究,提出了一系列的席位分配方法。之前介绍过的“Q值法”,也作为其中的一种情况,包含在内。
假设共有<code>m</code>方分配<code>N</code>个席位,第<code>i</code>方的人数记为<code>pi</code>,<code>ni</code>表示第<code>i</code>方分配的席位数,且均为非负整数。
| Huntington除数法 |
除数 d(n) |
不公平度的度量指标(假定pi/ni>pj/nj) |
| 最大除数法(GD) |
n+1 |
(nj-pi)/pj-ni |
| 主要分数法(MF) |
n+1/2 |
(nj/pj)-(ni-pi) |
| 相等比例法(EP) |
sqrt(n(n+1)) |
(njpi)/(nipj)-1 |
| 调和平均法(HM) |
2n(n+1)/(2n+1) |
pi/ni-pj/nj |
| 最小除数法(SD) |
n |
nj-nipj/pi |
下面是这个方法的思路:首先,我们对每一方都分配一个席位,然后利用选定的衡量指标,计算出每一方的不公平度。给最大的那一组,分配一个席位,然后继续计算,直到将所有席位分配完毕。一般情况下,在使用Huntington除数法时,通常在各方自动分得1席的基础上在做分配,除非在各方人数悬殊且席位数较少的时候。
由于在计算的过程中,采用了每增加1席计算一次的方式,因此不会出现席位悖论和人口悖论。
下面是C语言写的Huntington算法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| #include <cstdio> #include <iostream> #include <cstring> #include <cmath> #include <algorithm> using namespace std;
int w; FILE *fin=fopen("in.txt","r");
double dn(int n) { switch(w) { case 1:return n+1.0; case 2:return n+0.5; case 3:return sqrt(n*(n+1.0)); case 4:return 2*n*(n+1.0)/(2*n+1); case 5:return n; default:return 0; } }
void Huntington() { int s,flag=0,bh=1; double p[6],pd[6]; int n[6]; double max_pd; fscanf(fin,"%d",&s); for(int i=1;i<=5;i++) { fscanf(fin,"%lf",&p[i]); } for(int i=1;i<=5;i++) { n[i]=1; }
while(n[1]+n[2]+n[3]+n[4]+n[5]!=s) { flag=1;
for(int i=1;i<=5;i++) { pd[i] = p[i]/dn(n[i]); } max_pd = p[1]/dn(n[1]);
for(int i=2;i<=5;i++) { if(pd[i]>max_pd) { flag = i,max_pd = pd[i]; } } n[flag]++;
cout<<"第"<<bh++<<"次:"<<endl; for(int i=1;i<=5;i++) cout<<"p/di="<<pd[i]<<" n="<<n[i]<<endl; cout<<"--------------------"<<endl;
} cout<<endl; }
void printList() { cout<<"#请选择需要模拟的权重函数#"<<endl; cout<<"1.最大除数法(GD)"<<endl; cout<<"2.主要分数法(MF)"<<endl; cout<<"3.相等比例法(EP)"<<endl; cout<<"4.调和平均法(HM)"<<endl; cout<<"5.最小除数法(SD)"<<endl; cout<<"--------------------"<<endl; cout<<"退出请输入0"<<endl; }
void select() { printList(); while(cin>>w) { switch (w) { case 1:case 2:case 3:case 4:case 5: Huntington(); select(); break; case 0:fclose(fin);exit(0); default: cout<<"输入错误,请重新输入"<<endl; cout<<"--------------------"<<endl; select(); } } }
int main() { select(); fclose(fin); return 0; }
|
GD法偏向于人数多的组,SD法偏向于人数少的组。Huntington推荐偏向适中的EP法,也就是“Q值法”,该方法在1930年后一直在被美国国会众议员席位分配中采用。
最后更新时间:
梦想依在 人生正当年