numpy docplex不支持平方根np.sqrt(x),请建议一个替代的解决方案

h43kikqp  于 2022-12-26  发布在  其他
关注(0)|答案(1)|浏览(139)

我已经用python实现了docplex模型,一切都很顺利:问题公式,变量,约束条件和目标函数。当我试图计算两个圆心之间的欧几里得距离时提出的问题,简单地numpy可以做np.sqrt((x2-x1)**2 +(y2-y1)**2)。请告诉我如何解决这个问题,我无法找到欧几里得距离的二次方程,而不使用平方根。
附上工作代码,您可以在其中看到约束1的问题。

from docplex.mp.model import Model
import numpy as np

def packing_cplex(CDA, R, H, items):

  # continuous variables x,y range from -R to +R
  x = [ CDA.continuous_var(name="x{}:".format(i), lb=-R, ub=R)
        for i in range(len(items))]

  y = [ CDA.continuous_var(name="y{}:".format(i), lb=-R, ub=R)
        for i in range(len(items))]
  
  # integer variable z range from 0 to H 
  z = [ CDA.integer_var(name="z{}:".format(i), lb=0, ub=H)
        for i in range(len(items))]
  
  # indicator denotes whether an item is packed into the container
  # i=1, .., n, values 1/0
  d = [ CDA.binary_var(name="d{}:".format(i))
         for i in range(len(items))]

  # sqrt root issue--> np.sqrt((x[i]**2 + y[i]**2))
  # 1.constraint packed items and container radius
  CDA.add_quadratic_constraints(R >= (items[i][0] + (x[i]**2 + y[i]**2)**1 )
                                      for i in range(len(items)))
    
  # 2.constraint packed items and container height
  for i in range(len(items)):                  
    CDA.add( CDA.if_then( d[i]==1, H >= ( items[i][1] + z[i] ) ) )
    
  # objective maximise max∑_(i=0 .. n-1 (π * ri^2 * hi * di)
  CDA.set_objective("max", np.sum([d[i] * np.pi * items[i][0]**2 * items[i][1]
                                                for i in range(len(items))]))

# radius and height of cylinder container  
R, H = 3, 2
volume = np.pi * R**2 * H

# pack, [(ri,hi), ... ([rn,hn]) where ri/hi is radius/height of item
items = [(1,2),(1,2),(1,2),(1,2),(1,2),(1,2),(1,2)]
CDA = Model(name='CDA')
packing_cplex(CDA, R, H, items)
CDA.print_information()
solution = CDA.solve()
utilization = solution._objective / volume
print('Utilization (%) ', utilization)

我期待平方根的替代解

uz75evzq

uz75evzq1#

如果你有非线性函数,你可以在cplex中使用CPOptimizer。
例如,https://github.com/AlexFleischerParis/zoodocplex/blob/master/zoononlinear.py
或平方根:

from docplex.cp.model import CpoModel

mdl = CpoModel(name='buses')
nbbus40 = mdl.integer_var(0,1000,name='nbBus40')
nbbus30 = mdl.integer_var(0,1000,name='nbBus30')
mdl.add(nbbus40*40 + nbbus30*30 >= 300)

#non linear objective
mdl.minimize(mdl.power(nbbus40,0.5)*500 + mdl.power(nbbus30,0.5)*400)

msol=mdl.solve()

print(msol[nbbus40]," buses 40 seats")

print(msol[nbbus30]," buses 30 seats")

要处理十进制变量,请参见
https://github.com/AlexFleischerParis/zoodocplex/blob/master/zoodecimalcpo.py

from docplex.cp.model import CpoModel

mdl = CpoModel(name='buses')

#now suppose we can book a % of buses not only complete buses

scale=100
scalenbbus40 = mdl.integer_var(0,1000,name='scalenbBus40')
scalenbbus30 = mdl.integer_var(0,1000,name='scalenbBus30')

nbbus40= scalenbbus40 / scale
nbbus30= scalenbbus30 / scale

 

mdl.add(nbbus40*40 + nbbus30*30 >= 310)
mdl.minimize(nbbus40*500 + nbbus30*400)

msol=mdl.solve()

print(msol[scalenbbus40]/scale," buses 40 seats")
print(msol[scalenbbus30]/scale," buses 30 seats")

相关问题