Python解运筹学问题
Python解運籌學問題
- PuLP
- 一般線性規劃問題
- 構造并求解混合0-1整數規劃問題
- numpy和scipy
- 標準問題(最小值,約束為<=)
- 非標準形式
- 運輸問題
- 指派問題(*scipy的linear_sum_assignment*)
- networkx 解圖論問題
- 最小支撐樹問題
- 最短路問題
- 最大流問題
PuLP
一般線性規劃問題
例題:
from pulp import *#構建問題 my_LpProblem = pulp.LpProblem("myProblem", LpMaximize) # 設置變量 x1 = pulp.LpVariable("x1", 0, None) x2 = pulp.LpVariable("x2", 0, None) x3 = pulp.LpVariable("x3", 0, None) # 最有函數 my_LpProblem += -x1+x2+x3 # 約束條件 my_LpProblem += x1 - x2 +2*x3 <= 10 my_LpProblem +=-x1 + x2 + x3 >= 4 my_LpProblem +=-x1 + x3 == 2 # 求解 status = my_LpProblem.solve() print("Status:", LpStatus[my_LpProblem.status]) # 打印出最優解 for v in my_LpProblem.variables():print(v.name, "=", v.varValue) # 打印最優目標函數值 print("objective=", value(my_LpProblem.objective))構造并求解混合0-1整數規劃問題
例題:
from pulp import *my_MipProblem = LpProblem("myproblem", LpMinimize)solution = []x1 = LpVariable("x1", lowBound=0, cat=LpInteger)# LpInteger:整數型 x2 = LpVariable("x2", cat=LpBinary)# LpBinary:0—1型x3 = LpVariable("x3", lowBound=0)my_MipProblem += 2 * x1 + 3 * x2 + x3, "obj" my_MipProblem += 2 * x1 - x2 + 3 * x3 >= 6, "c1" my_MipProblem += 4 * x1 + x2 + 5 * x3 == 24, "c2"my_MipProblem.solve() # 打印出已經求解問題的狀態print("Status:", LpStatus[my_MipProblem.status])# 打印出最優解for v in my_MipProblem.variables():print(v.name, "=", v.varValue)solution.append(v.varValue)# 打印最優目標函數值 print("objective=", value(my_MipProblem.objective))numpy和scipy
用scipy的linprog求解以下線性規劃問題
標準問題(最小值,約束為<=)
例題:
import numpy as np from scipy.optimize import linprogc = np.array([-6, -1, -2]) A_ub = np.array([[1, 3, 1], [2, 0, 1], [1, 1, 0]]) b_ub = np.array([12, 6, 2]) x1_bounds = [0, None] x2_bounds = [0, None] x3_bounds = [0, None]my_linprog_result = linprog(c, A_ub, b_ub, A_eq=None, b_eq=None, bounds=(x1_bounds, x2_bounds, x3_bounds), callback=None) my_solution = my_linprog_result.x my_optimum_value = my_linprog_result.fun print(my_solution) print(my_optimum_value)非標準形式
用linprog求解時,只能求解最小值且為小于約束的問題,如果要求解其他問題,則需先變換成規定的標準形式。
例題:
import numpy as np from scipy.optimize import linprogc = np.array([-1,-1,2]) # 最大值變為最小值,取相反數 A_ub = np.array([[1,2,3],[-2,-1,2]]) # >=約束轉換為<=約束,取相反數 b_ub = np.array([12,-8]) x1_bounds = [0,None] x2_bounds = [0,None] x3_bounds = [0,None]my_linprog_result = linprog(c,A_ub,b_ub,A_eq=None,b_eq=None,bounds=(x1_bounds,x2_bounds,x3_bounds),method='simplex',callback=None) my_solution = my_linprog_result.x my_optimum_value = -my_linprog_result.fun # 將最優值轉換為最大值 print(my_solution) print(my_optimum_value)運輸問題
例題:
from pulp import * import numpy as np from itertools import productproduction = 3 #3個產地 sale = 4 #3個銷地+1個虛擬銷地demand = [20, 40, 60, 10] # 銷量 capacity = [45, 30, 55] # 產量 cost = np.array([[7, 2, 2, 0], [1, 6, 5, 0], [5, 4, 7, 0]]) # 建立模型 prob = LpProblem("Transportation", LpMinimize) x = LpVariable.dicts("x", product(range(production), range(sale)), lowBound=0, upBound=None, cat=LpInteger) # product 作用未知 prob += pulp.lpSum(cost[l, c] * x[l, c] for l in range(production) for c in range(sale))# 約束條件 for l in range(production):prob += lpSum(x[l, c] for c in range(sale)) == capacity[l] for c in range(sale):prob += lpSum(x[l, c] for l in range(production)) == demand[c] # 求解 prob.solve()min_cost = value(prob.objective) solution = []for v in prob.variables():solution.append(v.varValue) solution = np.array(solution).reshape(3, 4)print(solution) print(min_cost)指派問題(scipy的linear_sum_assignment)
學習閱讀scipy.optimize.linear_sum_assignment
注意
例題1:
例題2:
networkx 解圖論問題
Python的Networkx包
NetworkX is a Python language software package for the creation, manipulation, and study of the structure, dynamics, and function of complex networks.
With NetworkX you can load and store networks in standard and nonstandard data formats, generate many types of random and classic networks, analyze network structure, build network models, design new network algorithms, draw networks, and much more.
官方文檔
入門教程
算法
networkx整理內容
預習內容:
用
最小支撐樹問題
用Networkx的minimum_spanning_tree和minimum_spanning_edges方法求解以下最小支撐樹問題,要求:
提示:使用Graph.size會有幫助.
例題:
import networkx as nx G = nx.Graph() # 設置節點 v = {} for i in range(10):v[i] = f'v{i}' G.add_nodes_from(v) # 設置無向邊 weight = [(0,1,17), (0,2,21), (0,6,14), (0,8,24), (0,9,10),(1,4,10), (1,5,17), (1,6,11), (1,8,22),(2,3,18), (2,8,22),(3,5,11), (3,6,10), (3,7,14), (3,9,23),(4,7,7), (4,8,18),(5,9,18),(6,7,20),(7,8,11)] # 生成無向圖 for (start,end,flow) in weight:G.add_edge(start,end,weight=flow) # 求最小樹和最小樹的邊 T = nx.minimum_spanning_tree(G) T_edges = list(nx.minimum_spanning_edges(G)) # 計算T_weight(從tuple中取出dict,再從dict中取出值) T_weight = 0 # 初始化 for (start, end, weight) in T_edges:T_weight = T_weight + weight.get('weight') # dict沒有value方法(T_weight = T_weight + weight.value())print(sorted(T.edges(data=True))) print(T_weight)最短路問題
用Networkx的最短路求解方法求解以下最短路問題,要求:
例題1:求解下圖中從v1至v8的最短路徑及最短距離.
例題2:
import networkx as nx # 生成有向圖 G = nx.DiGraph() edge = [(0, 1, 3), (0, 2, 2), (0, 4, 3),(1, 3, -2), (1, 4, 7),(2, 4, 4), (2, 5, 1),(3, 4, 5), (3, 6, 4),(4, 5, 1), (4, 6, 4),(5, 6, 2), (5, 7, 5),(6, 7, 6), (6, 8, 4),(7, 8, 6)] #可以是list,也可以是tuple for (start, end, flow) in edge:G.add_edge(start, end, weight=flow)# 設置屬性 # 求解最短路徑 all_shortest_paths = list(nx.all_shortest_paths(G, source=0, target=8, weight='weight')) #默認算法是dijkstra,調出屬性 shortest_path_length = nx.shortest_path_length(G,source=0,target=8, weight='weight') print(all_shortest_paths) print(shortest_path_length)最大流問題
用Networkx的Maximum Flow算法方法求解以下網絡最大流問題。
例題要求:
節點的編號從0開始
返回G,其為下圖所對應的DiGraph,其中弧上的權重用capacity表示.
返回max_flow_value,為最大流的流量(數值).
返回cut_set,為最小割集,可以是一個list或set.
求解下圖中從v1至v11的最大流及最小割,并思考最小割集是什么。圖中弧上的數字表示其容量.
總結
以上是生活随笔為你收集整理的Python解运筹学问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JS高级程序设计精简版(第十章:函数)附
- 下一篇: websocket python爬虫_p