首页 > 解决方案 > docplex.cp.model 比穷举搜索慢

问题描述

我正在解决一个combinatorial optimisation问题,并意识到这CPLEX需要很长时间才能运行。这是一个玩具示例:

在此处输入图像描述

我正在使用pythonAPIdocplex

import numpy as np
from docplex.cp.model import CpoModel
N = 5000
S = 10
k = 2

u_i = np.random.rand(N)[:,np.newaxis]
u_ij = np.random.rand(N*S).reshape(N, S)
beta = np.random.rand(N)[:,np.newaxis]

m = CpoModel(name = 'model')
R = range(0, S)

idx = [(j) for j in R]
I = m.binary_var_dict(idx)
m.add_constraint(m.sum(I[j] for j in R)<= k)

total_rev = m.sum(beta[i,0] / ( 1 + u_i[i,0]/sum(I[j] * u_ij[i,j]  for j in R) ) for i in range(N) )

m.maximize(total_rev)

sol=m.solve(agent='local')

sol.print_solution()

for i in R:
    if sol[I[i]]==1:
        print('i : '+str(i))

部分输出如下:

Model constraints: 1, variables: integer: 10, interval: 0, sequence: 0
Solve status: Optimal
Search status: SearchCompleted, stop cause: SearchHasNotBeenStopped
Solve time: 76.14 sec
-------------------------------------------------------------------------------
Objective values: (1665.58,), bounds: (1665.74,), gaps: (9.27007e-05,)
Variables:
   + 10 anonymous variables

我尝试了详尽的搜索:

import numpy as np
import pandas as pd
from itertools import combinations,permutations,product
import time

start = time.time()

results = []

for K_i in range(1,k+1):  #K
    comb = list(combinations(range(S), K_i))

    A = len(comb)
    for a in range(A):# A
        comb_i = comb[a]

        I = np.repeat(0,S).reshape(-1,1)

        I[comb_i,0] = 1
        u_j = np.matmul(u_ij,I)

        total_rev = np.sum(beta/ (1 + u_i/u_j))
        results.append({'comb_i':comb_i, 'total_rev':total_rev })

end = time.time()
time_elapsed = end - start
print('time_elapsed : ', str(time_elapsed))

results = pd.DataFrame(results)
opt_results = results[results['total_rev'] == max(results['total_rev'].values)]
print(opt_results)

输出:

time_elapsed :  0.012971639633178711
    comb_i    total_rev
23  (1, 6)  1665.581329

如您所见,CPLEX它比穷举搜索慢 1000 倍。有没有办法改进CPLEX算法?

标签: python-3.xoptimizationconstraint-programmingdocplex

解决方案


对于这个特殊问题:

sol=m.solve(agent='local', SearchType='DepthFirst', Workers=1)

应该有很大帮助。


推荐阅读