微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

最佳运输代码Scipy线性编程优化需要更长的时间

如何解决最佳运输代码Scipy线性编程优化需要更长的时间

我一直在尝试计算平均值为0.0和4.0且方差分别为9.0和16.0的两个一维高斯分布之间的Wasserstein距离。我使用了scipy.linprog.optimize模块,并使用了以下链接中所述的“ interior-point”方法 https://yetanothermathprogrammingconsultant.blogspot.com/2019/10/scipy-linear-programming-large-but-easy.html。 但是,它花费了超过17个小时的时间,并且仍在运行(我的代码正在运行)以解决300 x 300 LP矩阵问题(即300个源节点和300个目标节点)。但是,该文件说有可能用1000个源节点和1000个目的节点来解决问题。(即,一个人可以用1,000,000(一百万)个决定性变量来解决LP问题。我的代码有什么问题?为什么要花这么长时间?我们是否需要大容量内存(或群集)来解决此类问题? 我的代码

from datetime import datetime
start_time = datetime.Now()
from scipy.optimize import linprog
import scipy

#Initializing the LP matrix
Piprob=np.zeros(500*500).reshape(500,500)

def Piprobmin(Krv,rhoi,rhoj):
  r1=np.shape(Krv)[0]
  r2=np.shape(Krv)[1]
  print("r1,r2",r1,r2)
  #Computing the LP Matrix which has just two ones in each column
  pmat=np.zeros((r1+r2)*(r1*r2)).reshape((r1+r2),(r1*r2))
  for i in range(r1+r2):
      for j in range(r1*r2):
          if((i<r1) and (j<((i+1)*r2)) and (j>=(i*r2))):
              pmat[i][j]=1
          if(i>=r1):
              for k in range(r1*r2):
                  if j==(i-r1)+(k*r2):
                      pmat[i][j]=1
  #flattening the cost matrix into one dimensional array
  krvf=Krv.flatten()
  tempr=np.append(rhoi,rhoj)
  Xv=[] #Creating list for joint probability matrix elements
                          
  res = scipy.optimize.linprog(c=krvf,method='interior-point',A_eq=pmat,b_eq=tempr,options= 
  {'sparse':True,'disp':True})

  print("res=\n",res)
  wv=res.fun
  for  l1 in range(r1*r2):
      Xv.append(res.x[l1])
  Yv=np.array(Xv)
  Yv=Yv.reshape(r1,r2)
  #returning Yv-joint probability and,Wv-minimized wasserstein distance
  return Yv,wv

  Piprob,W=Piprobmin(K,result1,result2) #K-cost function matrix,result1 is the first 
                                        #marginal,result2 is the second marginal
  end_time = datetime.Now()
  print('Duration: {}'.format(end_time - start_time))

成本函数的大小为300 X 300,大小,每个边际都有300点(总共600个约束)。我确认我的成本函数是对称且非负的。并且每个边际之和都等于一个概率。

解决方法

blog post中,单词 sparse 经常使用。不是没有原因的。将A矩阵存储为稀疏矩阵非常重要。否则,您将无法处理大问题。该博客文章详细讨论了运输LP矩阵在内存要求方面的差异,因此这一点应该不容错过。

这是一些示例代码,说明如何使用 scipy.optimize.linprog 建立具有1000个源节点和1000个目标节点的运输模型。同样,LP矩阵具有2,000行和1,000,000列,并且存储稀疏

import numpy as np
import scipy as sp
import scipy.sparse as sparse
import scipy.optimize as opt
from memory_profiler import profile


def GenerateData(M,N):
   np.random.seed(123)

   # form objective function
   c = np.random.uniform(0,10,(M,N))

   # demand,supply
   s = np.random.uniform(0,15,M)
   d = np.random.uniform(0,N)
   assert np.sum(d) <= np.sum(s),"supply too small"

   #print('c',c)
   #print('s',s)
   #print('d',d)
   return {'c':c,'s':s,'d':d,'n':N,'m':M}

def FormLPData(data):

   rhs = np.append(data['s'],-data['d'])

   # form A
   # column (i,j)=n*i+j has two nonzeroes:
   #    1 at row i with rhs supply(i)
   #    1 at row N+j with rhs demand(j)
   N = data['n']
   M = data['m']
   NZ = 2*N*M
   irow = np.zeros(NZ,dtype=int)
   jcol = np.zeros(NZ,dtype=int)
   value = np.zeros(NZ)
   for i in range(N):
      for j in range(M):
         k = M*i+j
         k1 = 2*k
         k2 = k1+1
         irow[k1] = i
         jcol[k1] = k
         value[k1] = 1.0
         irow[k2] = N+j
         jcol[k2] = k
         value[k2] = -1.0

   A = sparse.coo_matrix((value,(irow,jcol)))

   #print('A',A)
   #print('rhs',rhs)

   return {'A':A,'rhs':rhs}



@profile
def run():
   # dimensions
   M = 1000  # sources
   N = 1000 # destinations
   data = GenerateData(M,N)
   lpdata = FormLPData(data)
   res = opt.linprog(c=np.reshape(data['c'],M*N),A_ub=lpdata['A'],b_ub=lpdata['rhs'],options={'sparse':True,'disp':True})


if __name__ == '__main__':
   run()

因此,您似乎完全错过了有关博客文章的全部内容。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。