用python处理DEA模型--CCR


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