python解决DEA模型–CCR

最近本人潜心学习python来解决DEA模型。DEA模型说难其实并不难,就是各种线性规划,但是它作为一个方向必然有其难点,我认为就是模型太多了,不断被创新,不断有新模型。

近来,了解到有gurobi这个库的存在,对于各种各样的模型都方便处理,太好用了!

gurobi的下载请自行去官网下载https://www.gurobi.com/。

那么本篇文章就直接附上代码。

import gurobipy
import pandas as pd
# 分页显示数据, 设置为 False 不允许分页
pd.set_option('display.expand_frame_repr', False)
# 最多显示的列数, 设置为 None 显示全部列
pd.set_option('display.max_columns', None)
# 最多显示的行数, 设置为 None 显示全部行
pd.set_option('display.max_rows', None)
class DEA(object):
def __init__(self, DMUs_Name, X, Y, AP=False):
self.m1, self.m1_name, self.m2, self.m2_name, self.AP = X.shape[1], X.columns.tolist(), Y.shape[1], Y.columns.tolist(), AP
self.DMUs, self.X, self.Y = gurobipy.multidict({ DMU: [X.loc[DMU].tolist(), Y.loc[DMU].tolist()] for DMU in DMUs_Name})
print(f'DEA(AP={AP}) MODEL RUNING...')
#multidict扩展字典,便于处理同一个对象的不同属性约束
def __CCR(self):
for k in self.DMUs:
MODEL = gurobipy.Model()
OE, lambdas, s_negitive, s_positive = MODEL.addVar(), MODEL.addVars(self.DMUs),  MODEL.addVars(self.m1),\
MODEL.addVars(self.m2)
#决策变量 Model.addVar() 和 Model.addVars(),比如说是x = MODEL.addVar(lb=0.0, ub=gurobipy.GRB.INFINITY,
# vtype=gurobipy.GRB.CONTINUOUS, name="")
MODEL.update()
## 更新变量环境
MODEL.setObjectiveN(OE, index=0, priority=1)
#添加目标函数 Model.setObjective() 和 Model.setObjectiveN(),并且index: 目标函数对应的序号 (默认 0,1,2,…),
# 以 index=0 作为目标函数的值, 其余值需要另外设置参数
MODEL.setObjectiveN(-(sum(s_negitive) + sum(s_positive)), index=1, priority=0)
#priority大就先算
MODEL.addConstrs(gurobipy.quicksum(lambdas[i] * self.X[i][j] for i in self.DMUs if i != k or not self.AP)
+ s_negitive[j] == OE * self.X[k][j] for j in range(self.m1))
MODEL.addConstrs(gurobipy.quicksum(lambdas[i] * self.Y[i][j] for i in self.DMUs if i != k or not self.AP)
- s_positive[j] == self.Y[k][j] for j in range(self.m2))
MODEL.setParam('OutputFlag', 0)
MODEL.optimize()
self.Result.at[k, ('效益分析', '综合技术效益(CCR)')] = MODEL.objVal
self.Result.at[k, ('规模报酬分析', '有效性')] = '非 DEA 有效' if MODEL.objVal < 1 else 'DEA 弱有效' \
if s_negitive.sum().getValue() + s_positive.sum().getValue() else 'DEA 强有效'
self.Result.at[k, ('规模报酬分析', '类型')] = '规模报酬固定' if lambdas.sum().getValue() == 1 \
else '规模报酬递增' if lambdas.sum().getValue() < 1 else '规模报酬递减'
for m in range(self.m1):
self.Result.at[k, ('差额变数分析', f'{self.m1_name[m]}')] = s_negitive[m].X
self.Result.at[k, ('投入冗余率',  f'{self.m1_name[m]}')] = 'N/A' if self.X[k][m] == 0 \
else s_negitive[m].X / self.X[k][m]
for m in range(self.m2):
self.Result.at[k, ('差额变数分析', f'{self.m2_name[m]}')] = s_positive[m].X
self.Result.at[k, ('产出不足率', f'{self.m2_name[m]}')] = 'N/A' if self.Y[k][m] == 0 \
else s_positive[m].X / self.Y[k][m]
return self.Result
def dea(self):
columns_Page = ['效益分析'] + ['规模报酬分析'] *2 + ['差额变数分析'] * (self.m1 + self.m2) + \
['投入冗余率'] * self.m1 + ['产出不足率'] * self.m2
columns_Group = ['综合技术效益(CCR)','有效性', '类型'] + (self.m1_name + self.m2_name) * 2
self.Result = pd.DataFrame(index=self.DMUs, columns=[columns_Page, columns_Group])
self.__CCR()
return self.Result
def analysis(self, file_name=None):
Result = self.dea()
file_name = 'DEA 数据包络分析报告.xlsx' if file_name is None else f'\\{file_name}.xlsx'
Result.to_excel(file_name, 'DEA 数据包络分析报告')
if __name__=='__main__':
innum, outnum = 2, 1
file = "C://Users//admin//Desktop//数据.xlsx"
data = pd.read_excel(file, header=0, index_col=0)
print(data)
X = data[data.columns[:innum]]
Y = data[data.columns[innum:innum+outnum]]
print(X)
print(Y)
dea = DEA(DMUs_Name=data.index, X=X, Y=Y)
#dea.analysis() # dea 分析并输出表格
print(dea.dea())  # dea 分析,不输出结果

本文地址:https://blog.csdn.net/weixin_43217288/article/details/111090649