问题描述
我正在尝试解决一个问题,以确定受各种约束的政府拨款。最好将问题描述为:
政府已决定提供总计1,800,000欧元的财政援助。他们邀请了同样的申请。他们已经决定了如何分配资金的一些限制。约束是:
-
可根据申请人的财务状况分配的最大金额上限。
丰富= 300,000
中产阶级= 500,000
差= 1,000,000
-
可以根据申请人的性别分配的最大金额。
男性= 800,000
女性= 1,000
他们收到了不同组合的申请。政府无法分配该申请收到的更多款项。
+--------------------+------------------+-----------------------------+------------------------+
| Applicant Category | Applicant Gender | Total Applications Received | Amount to be allocated |
+--------------------+------------------+-----------------------------+------------------------+
| Rich | Male | 200,000 | |
| Middle class | Female | 400,000 | |
| Middle class | Male | 350,000 | |
| Poor | Female | 650,000 | |
| Poor | Male | 750,000 | |
+--------------------+------------------+-----------------------------+------------------------+
在上面的示例中,Rich Male的申请总数为200,000。因此,政府不能为该类别分配超过200,000的资金。如果这有助于增加所有这些行的总支出金额,则政府可以分配的预算少于此。
中产阶级男性总共要求40万,中产阶级女性要求35万。但是,可以在中产阶级类别中支出的总金额为500,000。这意味着它无法完全分配给这些存储桶,而需要减少支付。
中产阶级女性要求40万,贫穷女性要求65万。但是,所有女性可以支付的总金额为1,000,这意味着这两个桶也无法完全分配。
上表中的“要分配的金额”列是必须确定的算法。诸如此类-可以分配给表中每个条目的最大金额是多少,该金额将允许我们总共支付最大金额,而没有违反任何约束,因此“要分配的金额”不应超过“收到的申请总数”?
例如,如果我们将700,000美元分配给贫困男性,则需要同时从男性和贫困类别中扣除。在将700,000分配给贫困男性后,男性的剩余金额变为100,000(800,00-700,000),而贫困人口变为300,000(1,000-700,000)。现在,对其他条目的后续分配必须考虑到修改后的约束,并确保不违反限制。
目的是确定政府可以分配给类别和性别的每种组合的数量,以使总支出最大化。
我对线性编程还是有点陌生,但是通过阅读在线帮助,我可以确定我可以分别限制在每个类别上的约束条件。
x (rich) <= 300,000
y (middle class) <= 500,000
z (poor) <= 1,000
p (male) <= 800,000
q (female) <= 1,000
但是,我无法对政府收到的申请制定限制。例如,有钱男性收到的200,000个申请不会转换为(x + p)
解决方法
我们可以用以下线性方程式来表达上述问题:
Let Rm = Rich Male
Rm = Rich Female
Mm = Middleclass Male
Mf = Middleclass Female
Pm = Poor Male
Pf = Poor Female
目标:Maximize: Rm + Rf + Mm + Mf + Pm + Pf
主题:
1) Rm + Rf <= 300,000
2) Mm + Mf <= 500,000
3) Pm + Pf <= 1,000,000
4) Rm + Mm + Pm <= 800,000
5) Rf + Mf + Pf <= 1,000
6) Rm <= 200,000
7) Mm <= 350,000
8) Pm <= 750,000
9) Rf <= 0
10) Mf <= 400,000
11) Pf <= 650,000
可以根据输入数据更改约束6-11。
解决这个问题,我们得到:
Rm = 200,000
Mm = 250,000
Pm = 350,000
Rf = 0
Mf = 250,000
Pf = 650,000
因此,根据给定的数据,总共1,70,000
会分配给申请者
代码:
from pulp import *
import pandas as pd
# Problem Data
df = pd.DataFrame({'economic': ['rich','middle','poor','poor'],'gender': ['male','female','male','male'],'received': [200000,400000,350000,650000,750000]})
max_by_economic = {'rich': 300000,'middle':500000,'poor':1000000}
max_by_gender = {'male': 800000,'female':500000,'poor':1000000}
max_total = 1800000
# Implementation
prob = LpProblem("allocation",LpMaximize)
alloc_vars = LpVariable.dicts('alloc_vars',df.index)
# Objective
prob += lpSum([alloc_vars[i] for i in df.index])
# Bounds
for i in df.index:
prob += alloc_vars[i] <= df.received[i]
# Constraints
for status in max_by_economic:
prob += lpSum([alloc_vars[i] for i in df.index if df['economic'][i] == status]) <= max_by_economic[status]
for gender in max_by_gender:
prob += lpSum([alloc_vars[i] for i in df.index if df['gender'][i] == gender]) <= max_by_gender
prob += lpSum([alloc_vars[i] for i in df.index]) <= max_total
prob.solve()
# Load results into dataframe
df['allocation'] = [alloc_vars[i].varValue for i in df.index]
print(df)
返回:
economic gender received allocation
0 rich male 200000 200000.0
1 middle female 400000 150000.0
2 middle male 350000 350000.0
3 poor female 650000 250000.0
4 poor male 750000 750000.0