【问题标题】:Optimizing python script to produce output faster (Variable Assignment)优化python脚本以更快地产生输出(变量分配)
【发布时间】:2021-07-29 14:19:27
【问题描述】:

我使用 python 进行优化。我使用带有 1100 节点的 Networkx 库制作了一个图表。 python 脚本包括以下几行。

# Compute key parameters of MIP model formulation
from itertools import product
num_facilities = len(facilities)
print("The num_facility = ", num_facilities)
num_customers = len(customers)
print("The num_customers = ", num_customers)
cartesian_prod = list(product(range(num_customers), range(num_facilities))) 

#Output
The num_facility =  1100
The num_customers =  1100

下一步,生成一些随机数如下:

import random
random.seed(7) 
number_of_vpns = random.sample(range(0, 1200), num_facilities)

我使用以下函数计算图中节点之间的距离。

def compute_distance(source_number,dest_number):
    path = (nx.shortest_path(g,source=source_number,target= dest_number, weight='weight'))
    path_length = path_weight(g, path, weight="weight")
    return path_length

最后,我将变量“shipping_cost”定义为:

%%time
shipping_cost = {(c,f): number_of_vpns[c]*compute_distance(c,f) for c, f in cartesian_prod}

上述代码的每一行都以较短的方式(毫秒)执行。但是,即使在 7 小时后,对变量“shipping_cost”的赋值也没有完成。该变量在逻辑上包含 1210000 个值。

  1. 从运行时间上看是否正常?
  2. 有什么办法可以减少 shipping_cost 分配的执行时间?

【问题讨论】:

  • cartesian_prod 包含什么? product 是做什么的?
  • 亲爱的@Ram,在数学方面,两个集合的笛卡尔积定义为所有有序对 (a, b) 的集合,其中 a 属于 A,b 属于 B。考虑以下示例以便更好地理解。产品来自from itertools import product 输入:arr1 = [1, 2, 3] arr2 = [5, 6, 7] 输出:[(1, 5), (1, 6), (1, 7), (2 , 5), (2, 6), (2, 7), (3, 5), (3, 6), (3, 7)]
  • 您的 cartesian_prod 包含 1210000 个值。您正在调用 compute_distance(),而后者又调用 shortest_path()path_length() 获取所有 1210000 值。这就是计算shipping_cost 需要花费大量时间来计算的原因。你真的需要为所有值计算 compute_distance() 吗?
  • 我想shortest_path() 使用时间复杂度为 O(ElogV) 的 Dijkstra 算法,并且您有 1100 个节点(V = 1100),我不知道#edges。甚至还有path_length() - 我不知道它的时间复杂度是多少。我认为您可以进行所有数学运算并计算 1210000 个值所花费的时间。
  • 算一下吧。假设 50 毫秒:1210000 * 50 ms = 16.8 h

标签: python performance time


【解决方案1】:

基于@Ram 的 cmets:

cartesian_prod 包含 1210000 值。代码调用compute_distance(),后者又调用shortest_path()path_length(),获取来自networkx 库的所有1210000 个值。这就是计算shipping_cost 需要花费大量时间来计算的原因。

我将代码更改如下(添加path_lengths而不是compute_distance并修改shipping_cost):

import networkx as nx
path_lengths = dict(nx.all_pairs_dijkstra_path_length(g, weight='weight'))

shipping_cost = {(c,f): number_of_vpns[c]*path_lengths[c][f] for c, f in cartesian_prod}

这样一来,path_lengths 对所有节点计算一次,时间复杂度集中在访问 path_lengths 的元素上。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-10-04
    • 1970-01-01
    • 2013-04-10
    • 2011-12-14
    • 2019-10-29
    • 2023-03-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多