日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

Python解运筹学问题

發布時間:2023/12/31 python 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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

注意

  • linear_sum_assignment只能求解目標函數為最小值的線性指派問題
  • 可以直接求解任務數與人數不對等的指派問題
  • 輸入參數必須為一個2D的numpy.array實例
  • 返回的結果為最優指派對應在此2D array上的index
  • 例題1:

    import numpy as np from scipy.optimize import linear_sum_assignments1 = [11, 10, 11, 3, 11] s2 = [8, 11, 10, 12, 14] s3 = [15, 5, 16, 2, 3] s4 = [15, 3, 5, 17, 14]time_array_standardized = np.vstack((s1, s2, s3, s4,s4))row_ind, col_ind = linear_sum_assignment(time_array_standardized) print(row_ind)#開銷矩陣對應的行索引 print(col_ind)#對應行索引的最優指派的列索引 print(time_array_standardized[row_ind,col_ind])#提取每個行索引的最優指派列索引所在的元素,形成數組 minimum_time = time_array_standardized[row_ind,col_ind].sum()#數組求和 print(minimum_time)

    例題2:

    import numpy as np from scipy.optimize import linear_sum_assignments1 = [-320, -300, -440, -470, -450] s2 = [-370, -490, -420, -550, -310] s3 = [-360, -510, -440, -490, -300] s4 = [-310, -420, -420, -450, -450] s5 = [-340, -330, -400, -450, -510]time_array_standardized = np.vstack((s1, s2, s3, s4, s5))row_ind, col_ind = linear_sum_assignment(time_array_standardized) print(row_ind)#開銷矩陣對應的行索引 print(col_ind)#對應行索引的最優指派的列索引 print(time_array_standardized[row_ind,col_ind])#提取每個行索引的最優指派列索引所在的元素,形成數組 maximum_sales = -time_array_standardized[row_ind,col_ind].sum()#數組求和 print(maximum_sales)

    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整理內容

    預習內容:

  • nx.Graph(無向圖)和nx.DiGraph(有向圖)的生成
  • 用Networkx的minimum_spanning_tree和minimum_spanning_edges方法求解最小支撐樹問題
  • Networkx的最短路求解方法求解最短路問題
  • 最小支撐樹問題

    用Networkx的minimum_spanning_tree和minimum_spanning_edges方法求解以下最小支撐樹問題,要求:

  • 節點的編號從0開始
  • 邊的權重用weight表示
  • 返回G,其為下圖所對應的Graph.
  • 返回T,為G對應的最小支撐樹
  • 返回T_edges,為T中的所有邊,T_edges可以是一個list,或tuple,或generator.
  • 返回T_weight,T的權重之和.
    提示:使用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的最短路求解方法求解以下最短路問題,要求:

  • 節點的編號從0開始
  • 返回G,其為下圖所對應的DiGraph.
  • 返回all_shortest_paths,為G中source和target之間的所有最短路徑,例如如果v1到v8的最短路徑有兩條:v1→v2→v8和v1→v3→v4→v8,則返回一個list或generator,其格式為[[0,1,7], [0,2,3,7]].
  • 返回shortest_path_length,為最短路的長度.
  • 例題1:求解下圖中從v1至v8的最短路徑及最短距離.

    import networkx as nx # 生成有向圖 G = nx.DiGraph() edge = [(0, 1, 1), (0, 2, 4), (0, 3, 3),(1, 2, 3), (1, 4, 8),(2, 4, 5), (2, 5, 3), (2, 6, 6),(3, 2, 4), (3, 6, 5),(4, 5, 4), (4, 7, 3),(5, 7, 4),(6, 5, 2), (6, 7, 5)] #可以是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=7, weight='weight')) #默認算法是dijkstra,調出屬性 shortest_path_length = nx.shortest_path_length(G,source=0,target=7,weight='weight') print(all_shortest_paths) print(shortest_path_length)

    例題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的最大流及最小割,并思考最小割集是什么。圖中弧上的數字表示其容量.

  • import networkx as nx G = nx.DiGraph() edge = [(0, 1, 155), (0, 2, 180), (0, 3, 30),(1, 4, 155), (1, 5, 185),(2, 4, 105), (2, 5, 65), (2, 6, 60),(3, 5, 120), (3, 6, 160),(4, 7, 110), (4, 8, 60),(5, 7, 180), (5, 8, 155), (5, 9, 60),(6, 8, 135), (6, 9, 135),(7, 10, 85),(8, 10, 85),(9, 10, 155)] for (start, end, flow) in edge:G.add_edge(start, end, capacity=flow)# 設置屬性 # 計算最大流的值 max_flow_value = nx.maximum_flow_value(G, 0, 10, capacity="capacity") # 計算最小割 cut_value, partition = nx.minimum_cut(G, 0, 10,capacity="capacity")# partition (u,v) reachable, non_reachable = partition # 設置弧 cut_set = set() for u, nbrs in ((n, G[n]) for n in reachable):cut_set.update((u, v) for v in nbrs if v in non_reachable)

    總結

    以上是生活随笔為你收集整理的Python解运筹学问题的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。