对偶单纯形法的Python实现

对偶单纯形法的Python实现

      • 编写背景
      • 程序
      • 输出
      • 说明
      • 缺点

编写背景

对偶单纯形法的算法原理在各个版本的《运筹学》教材中已经被阐述得很详细了,但是手工计算不仅繁琐,而且容易出错。编写程序时笔者尚未接触Lingo,故使用Python对算法进行实现。

程序

import re
import pandas as pd
from fractions import Fraction

data = pd.read_csv("data2.csv", header=0, index_col=0)
print("=======The Original Table=======")
print(data)


def do_it(data):
    in_base_index = data.loc["sigma", :][data.loc['sigma', :] < 0].index
    rec = {}
    res_val = []
    for i in in_base_index:
        out_base_index = data.loc[:, i][data.loc[:, i] < 0].index.drop("sigma")
        for j in out_base_index:
            res = Fraction(data.loc["sigma", i], data.loc[j, i])
            res_val.append(res)
            rec[str(j) + "," + str(i)] = res

    def get_key(dic, value):
        return [k for k, v in dic.items() if v == value]

    s = get_key(rec, min(res_val))
    s = re.split(r"\,", s[0])

    # 这里是将本身变成1
    param1 = Fraction(1, data.loc[s[0], s[1]])
    data.loc[s[0], :] = data.loc[s[0], :] * param1
    # 将其他变为0
    for row in data.index.drop(s[0]):
        target = data.loc[row, s[1]]
        param2 = Fraction(-target, 1)
        data.loc[row, :] = data.loc[s[0], :] * param2 + data.loc[row, :]

    data = data.rename(index={s[0]: s[1]})
    print("================================")
    print(data)
    if (data["b"].drop("sigma") < 0).any():
        print("Need More Action!")
        do_it(data)
    else:
        print("Can't Do Any More.")
    return data


# 如何b中的任何一个数小于零,都需要进一步操作
if (data["b"].drop("sigma") < 0).any():
    print("Need More Action!")
    do_it(data)
else:
    print("Can't Do Any More.")

输出

对偶单纯形法的Python实现_第1张图片
对偶单纯形法的Python实现_第2张图片
程序会输出计算过程中每一次迭代的单纯形表,并给出是否需要再一次迭代的提示,最后一张表就是输入题目的结果。

说明

该程序需要用户自行将题目调整成标准形式,并将初始单纯形表以csv文件的格式读入程序。如下图所示:
对偶单纯形法的Python实现_第3张图片
csv文件的存放位置及读入可以参考其他博主的文章,或者自行查阅Pandas的参考文档,在此不进行赘述。

缺点

该程序的缺点也很明显——只能拿来做题,而且是明知道有最优解的题目,否则会陷入死循环。因此此程序仅作为练手参考使用,请不要轻易将其用于解题!!!

你可能感兴趣的:(随笔,python,算法)