基于python的Topsis(优劣解距离)算法的实现(附代码及举例说明)

TOPSIS 法是一种用于组内综合评价十分常见的算法能充分利用原始数据的信息,其结果能精确地反映各评价方案之间的差距。例如当我们在面对离散性、随机性较高的原始数据时,为了通过对这些数据进行分析从而得到最优解,不妨可以试试这种算法。下面我将以2021数学建模比赛中c题数据及问题为例进行演示说明。

题目如下---------------------------------------------------------------------------------------------------------------------

某建筑和装饰板材的生产企业所用原材料主要是木质纤维和其他植物素纤维材料, 总体可分为 A,B,C 三种类型。该企业每年按 48 周安排生产,需要提前制定 24 周的原 材料订购和转运计划,即根据产能要求确定需要订购的原材料供应商(称为“供应商”)和相应每周的原材料订购数量(称为“订货量”),确定第三方物流公司(称为“转运 商”)并委托其将供应商每周的原材料供货数量(称为“供货量”)转运到企业仓库。
该企业每周的产能为 2.82 万立方米,每立方米产品需消耗 A 类原材料 0.6 立方米, 或 B 类原材料 0.66 立方米,或 C 类原材料 0.72 立方米。由于原材料的特殊性,供应商 不能保证严格按订货量供货,实际供货量可能多于或少于订货量。为了保证正常生产的 需要,该企业要尽可能保持不少于满足两周生产需求的原材料库存量,为此该企业对供 应商实际提供的原材料总是全部收购。 在实际转运过程中,原材料会有一定的损耗(损耗量占供货量的百分比称为“损耗率”),转运商实际运送到企业仓库的原材料数量称为“接收量”。每家转运商的运输 能力为 6000 立方米/周。通常情况下,一家供应商每周供应的原材料尽量由一家转运商 运输。 原材料的采购成本直接影响到企业的生产效益,实际中 A 类和 B 类原材料的采购单 价分别比 C 类原材料高 20%和 10%。三类原材料运输和储存的单位费用相同。 附件 1 给出了该企业近 5 年 402 家原材料供应商的订货量和供货量数据。附件 2 给 出了 8 家转运商的运输损耗率数据。请你们团队结合实际情况,对相关数据进行深入分 析,研究下列问题:
1.根据附件 1,对 402 家供应商的供货特征进行量化分析,建立反映保障企业生产 重要性的数学模型,在此基础上确定 50 家最重要的供应商,并在论文中列表给出结果。
2.参考问题 1,该企业应至少选择多少家供应商供应原材料才可能满足生产的需求? 针对这些供应商,为该企业制定未来 24 周每周最经济的原材料订购方案,并据此制定 损耗最少的转运方案。试对订购方案和转运方案的实施效果进行分析。
3.该企业为了压缩生产成本,现计划尽量多地采购 A 类和尽量少地采购 C 类原材 料,以减少转运及仓储的成本,同时希望转运商的转运损耗率尽量少。请制定新的订购 方案及转运方案,并分析方案的实施效果。
4.该企业通过技术改造已具备了提高产能的潜力。根据现有原材料的供应商和转运 商的实际情况,确定该企业每周的产能可以提高多少,并给出未来 24 周的订购和转运方案。

附件一:企业对402家供应商过去240周的订单量和供应商的供应量
附件二:8家转运商过去240周的转运损耗率
附件A:填写未来24周的订购方案(分三张表对应三道题)
附件B:未来24周的的转运方案(分三张表对应三道题)
————————————————
版权声明:本文为CSDN博主「闪现插秧」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/m0_59024303/article/details/120318032

我将借助该算法的是解决问题1----确定 50 家最重要的供应商,根据算法对420家供应商进行评分筛选出评分靠前50家作为问题1的解决成果。代码如下

import numpy as np
import xlrd
import pandas as pd


# 从excel文件中读取数据
def read(file):
    wb = xlrd.open_workbook(filename=file)  # 打开文件
    sheet = wb.sheet_by_index(0)  # 通过索引获取表格
    rows = sheet.nrows  # 获取行数
    all_content = []  # 存放读取的数据
    for j in range(1, 4):  # 取第1~第3列对的数据
        temp = []
        for i in range(1, rows):
            cell = sheet.cell_value(i, j)  # 获取数据
            temp.append(cell)
        all_content.append(temp)  # 按列添加到结果集中
        temp = []
    return np.array(all_content)


# 极小型指标 -> 极大型指标
def dataDirection_1(datas):
    return np.max(datas) - datas  # 套公式


# 中间型指标 -> 极大型指标
def dataDirection_2(datas, x_best):
    temp_datas = datas - x_best
    M = np.max(abs(temp_datas))
    answer_datas = 1 - abs(datas - x_best) / M  # 套公式
    return answer_datas

# 正向化矩阵标准化
def temp2(datas):
    K = np.power(np.sum(pow(datas, 2), axis=1), 0.5)
    for i in range(0, K.size):
        for j in range(0, datas[i].size):
            datas[i, j] = datas[i, j] / K[i]  # 套用矩阵标准化的公式
    return datas


# 计算得分并归一化
def temp3(answer2):
    list_max = np.array(
        [np.max(answer2[0, :]), np.max(answer2[1, :]), np.max(answer2[2, :])])  # 获取每一列的最大值
    list_min = np.array(
        [np.min(answer2[0, :]), np.min(answer2[1, :]), np.min(answer2[2, :])])  # 获取每一列的最小值
    max_list = []  # 存放第i个评价对象与最大值的距离
    min_list = []  # 存放第i个评价对象与最小值的距离
    answer_list = []  # 存放评价对象的未归一化得分
    for k in range(0, np.size(answer2, axis=1)):  # 遍历每一列数据
        max_sum = 0
        min_sum = 0
        for q in range(0, 3):  # 有三个指标
            max_sum += np.power(answer2[q, k] - list_max[q], 2)  # 按每一列计算Di+
            min_sum += np.power(answer2[q, k] - list_min[q], 2)  # 按每一列计算Di-
        max_list.append(pow(max_sum, 0.5))
        min_list.append(pow(min_sum, 0.5))
        answer_list.append(min_list[k] / (min_list[k] + max_list[k]))  # 套用计算得分的公式 Si = (Di-) / ((Di+) +(Di-))
        max_sum = 0
        min_sum = 0
    answer = np.array(answer_list)  # 得分归一化
    return (answer / np.sum(answer))


def main():
    file = 'C:/Users/JayDen/Desktop/topsis算法各属性数值及得分.xls'
    answer1 = read(file)  # 读取文件
    answer2 = []
    for i in range(0, 3):  # 按照不同的列,根据不同的指标转换为极大型指标,因为只有四列
        answer = None
        if (i == 0):  # 本来就是极大型指标,不用转换
            answer = answer1[0]
        elif (i == 1):  # 中间型指标
            answer = dataDirection_2(answer1[1], 1)
        elif (i == 2):  # 极小型指标
            answer = dataDirection_1(answer1[2])
        answer2.append(answer)
    answer2 = np.array(answer2)  # 将list转换为numpy数组
    answer3 = temp2(answer2)  # 数组正向化
    answer4 = temp3(answer3)  # 标准化处理去钢
    data = pd.DataFrame(answer4)  # 计算得分
    # 将得分输出到excel表格中
    writer = pd.ExcelWriter(
        'C:/Users/JayDen/Desktop/得分.xls')  # 写入Excel文件
    data.to_excel(writer, 'Sheet1', float_format='%.5f')  # ‘page_1’是写入excel的sheet名
    writer.save()
    writer.close()
main()


得分部分供应商数据如下

基于python的Topsis(优劣解距离)算法的实现(附代码及举例说明)_第1张图片

 

 

你可能感兴趣的:(python,算法,数学建模)