最近本人潜心学习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