本篇博客请结合《数学模型(第四版)》,姜启源版教材第八章第四节内容阅读。

  在处理席位分析问题时,常使用Huntington除数法来进行处理。在书中279~281的学习中,我们了解到了怎样去比较一个分配结果的不公平度,以及一个较惯例分配法更加公平的“Q值法”。那么,下面我将介绍一种处理这类问题的通用方法,Huntington除数法。

  Edward Vermilye Huntington(1874~1952),1922年获得哈佛大学博士学位。20世纪20年代,他对这个问题做了具体的研究,提出了一系列的席位分配方法。之前介绍过的“Q值法”,也作为其中的一种情况,包含在内。

  假设共有m方分配N个席位,第i方的人数记为pi,ni表示第i方分配的席位数,且均为非负整数。

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年后一直在被美国国会众议员席位分配中采用。