【发布时间】:2020-11-18 22:02:46
【问题描述】:
我正在尝试使用 or-tools 来解决 MIP 问题。它可以在较小的 Number 和 Range 下运行得非常快,您可以将它们视为变量的数量和约束的数量。但对于较大的值,它运行速度较慢,有时甚至无法得到可行的结果。如果 Number= 1,000,000 和 Range = 10,000,还有其他方法可以提高速度吗?
问题描述
变量:x,r, #x=#r=Number
对象:最小化 (sum(r))
受制于: (1) r 为 0 或 1。
(2) x 是整数。
(3) x
(4) 对于桶中的任何唯一项,sum(x[buckets==item]) 落在 [count(item)*0.9,count(item)*1.1]
(5) 如果 x >0
,x 可能有一个下界from __future__ import print_function
from ortools.sat.python import cp_model
import numpy as np
import pandas as pd
np.random.seed(1)
def set_up_buckets(Number,Range,mu=0,sigma=1):
buckets = (np.random.normal(0, 1, Number)*Range).astype(int)
print("number of buckets:",len(np.unique(buckets)))
return buckets
model = cp_model.CpModel()
Number = 1000000
Range = 10000
Infinity = int(Number/10)
buckets = set_up_buckets(Number,Range)
def reduce_intervals(buckets,Range,sigma_cnt,mu=0,sigma=1):
upper = (mu+sigma*sigma_cnt)*Range
lower = (mu-sigma*sigma_cnt)*Range
buckets_reduced = buckets[(buckets<=upper)&(buckets>=lower)]
return buckets_reduced
buckets_reduced = reduce_intervals(buckets,Range,2)
def set_up_variables(Number):
x,r = [],[]
for i in range(Number):
x.append(model.NewIntVar(0, Infinity, 'x{}'.format(i+1)))
r.append(model.NewBoolVar('r{}'.format(i+1)))
return np.array(x),np.array(r)
x,r = set_up_variables(Number)
%%time
def set_up_constraints(Number,unique_buckets):
M = Number
x_lower_bound = int(Number/10000)
# x_upper_bound = int(Number/10)
print("add attributes constraints")
for i in unique_buckets:
xs = x[buckets==i]
model.Add(sum(xs) <= int(1.1*len(xs)))
model.Add(sum(xs) >= int(0.9 * len(xs)))
print("add x&r constraints")
for i in range(Number):
model.Add(x[i] <= M*r[i])
model.Add(x_lower_bound - x[i] <= M*(1-r[i]))
model.Minimize(sum(r))
return model
model = set_up_constraints(Number,np.unique(buckets_reduced))
def solve_model(model,max_seconds = 60*60):
solver = cp_model.CpSolver()
solver.parameters.log_search_progress = True
solver.parameters.num_search_workers = 8
solver.parameters.max_time_in_seconds = max_seconds
status = solver.Solve(model)
return solver,status
solver,status = solve_model(model)
【问题讨论】:
-
你可以试试
num_search_workers = 8。根据 OR-Tools 的开发人员 (Laurent Perron) 的说法,最佳多样性,因此 CP-SAT 的稳健性和性能受到 8 个线程的影响。根据我有限的经验,这是真的。请参阅此答案的 cmets:or.stackexchange.com/a/4126/2477。如果减少大 M 的值有帮助,也可以尝试 - 这将取决于特定的实例(数据)。 -
1 小时后,您还没有建立模型 :-) 因此,此时搜索参数无关紧要。
标签: optimization mathematical-optimization or-tools mixed-integer-programming integer-programming