数学建模 1 线性规划

可以解决 线性规划 中的

 

一. 线性规划

参考《数学建模算法与应用-司守奎》第一章线性规划 

求解最普通的线性规划问题:

PULP调用包

import pulp
#目标函数的系数
z = [2, 3, 1]
#约束
a = [[1, 4, 2], [3, 2, 0]]
b = [8, 6]
#确定最大化最小化问题,最大化只要把Min改成Max即可
m = pulp.LpProblem(sense=pulp.LpMinimize)
#定义三个变量放到列表中
x = [pulp.LpVariable(f'x{i}', lowBound=0) for i in [1,2,3]]
#定义目标函数,lpDot可以将两个列表的对应位相乘再加和
#相当于z[0]*x[0]+z[1]*x[0]+z[2]*x[2]
m += pulp.lpDot(z, x)

#设置约束条件
for i in range(len(a)):
    m += (pulp.lpDot(a[i], x) >= b[i])
#求解
m.solve()
#输出结果
print(f'优化结果:{pulp.value(m.objective)}')
print(f'参数取值:{[pulp.value(var) for var in x]}')

#output:
#优化结果:7.0
#参数取值:[2.0, 0.0, 3.0]

如果存在类似x_1+2x_2+4x_3=101这种情况,可以

A_eq = [1,2,4]
b_eq = 101
m += (pulp.lpDot(A_eq, x) == b_eq)

二、运输问题

pulp调包代码

import pulp
import numpy as np
from pprint import pprint

def transportation_problem(costs, x_max, y_max):

    row = len(costs)
    col = len(costs[0])

    prob = pulp.LpProblem('Transportation Problem', sense=pulp.LpMaximize)

    var = [[pulp.LpVariable(f'x{i}{j}', lowBound=0, cat=pulp.LpInteger) for j in range(col)] for i in range(row)]

    flatten = lambda x: [y for l in x for y in flatten(l)] if type(x) is list else [x]

    prob += pulp.lpDot(flatten(var), costs.flatten())

    for i in range(row):
        prob += (pulp.lpSum(var[i]) <= x_max[i])

    for j in range(col):
        prob += (pulp.lpSum([var[i][j] for i in range(row)]) <= y_max[j])

    prob.solve()

    return {'objective':pulp.value(prob.objective), 'var': [[pulp.value(var[i][j]) for j in range(col)] for i in range(row)]}


if __name__ == '__main__':
    costs = np.array([[500, 550, 630, 1000, 800, 700],
                       [800, 700, 600, 950, 900, 930],
                       [1000, 960, 840, 650, 600, 700],
                       [1200, 1040, 980, 860, 880, 780]])

    max_plant = [76, 88, 96, 40]
    max_cultivation = [42, 56, 44, 39, 60, 59]
    res = transportation_problem(costs, max_plant, max_cultivation)

    print(f'最大值为{res["objective"]}')
    print('各变量的取值为:')
    pprint(res['var'])

#output:
#最大值为284230.0
#各变量的取值为:
#[[0.0, 0.0, 6.0, 39.0, 31.0, 0.0],
# [0.0, 0.0, 0.0, 0.0, 29.0, 59.0],
# [2.0, 56.0, 38.0, 0.0, 0.0, 0.0],
# [40.0, 0.0, 0.0, 0.0, 0.0, 0.0]]

三、指派问题

https://www.jianshu.com/p/9be417cbfebb

https://blog.csdn.net/your_answer/article/details/79160045

指派问题概述:

实际中,会遇到这样的问题,有n项不同的任务,需要n个人分别完成其中的1项,每个人完成任务的时间不一样。于是就有一个问题,如何分配任务使得花费时间最少。

通俗来讲,就是n*n矩阵中,选取n个元素,每行每列各有1个元素,使得和最小。

如下图:

指派问题性质:

指派问题的最优解有这样一个性质,若从矩阵的一行(列)各元素中分别减去该行(列)的最小元素,得到归约矩阵,其最优解和原矩阵的最优解相同.

匈牙利法:

(3)暂时不看被线覆盖的元素,重复(1)(2)直到没有线可以画。

(4)根据(2)找到的0元素个数判断,找到n个独立0元素则Success,小于n个则Fail.(本例子中,n=5,可以看到,第一次试指派之后,独立0元素有4个,不符合)

4.画盖0线:

目标:做最少的直线数覆盖所有0元素,直线数就是独立0元素的个数。

注意:这跟3的线不同;不能用贪心法去画线,比如

1 0 0

1 1 0

1 0 1

若先画横的,则得画3条线,实际只需2条;若先画竖的,将矩阵转置后同理。

步骤3得出的独立0元素的位置

发布了23 篇原创文章 · 获赞 20 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/GAIYA2050/article/details/99829450
今日推荐