title: Is there any way to improve speed of or-tools?
body: <p>I'm trying to use or-tools to solve an MIP problem. It could run quite fast with small Number and Range, you may treat them as number of variables and number of constraints. But for larger values, it runs slower and sometimes even can't get the feasible results. If there any other way to improve the speed with Number= 1,000,000 and Range = 10,000?</p>
  <p>Problem description</p>
  <p>variables: x,r, #x=#r=Number</p>
  <p>Object: Minimize (sum(r))</p>
  <p>Subject to:
  (1) r are either 0 or 1.</p>
  <p>(2) x are integers.</p>
  <p>(3) x&lt;=M*r, where M is infinity.</p>
  <p>(4) for any unique item in buckets, sum(x[buckets==item]) falls in [count(item)*0.9,count(item)*1.1]</p>
  <p>(5) x could have a lower bound if x &gt;0</p>
  <pre><code>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(&quot;number of buckets:&quot;,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&lt;=upper)&amp;(buckets&gt;=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(&quot;add attributes constraints&quot;)
      for i in unique_buckets:
          xs = x[buckets==i]
          model.Add(sum(xs) &lt;= int(1.1*len(xs)))
          model.Add(sum(xs) &gt;= int(0.9 * len(xs)))
  
      print(&quot;add x&amp;r constraints&quot;)    
      for i in range(Number):
          model.Add(x[i] &lt;= M*r[i])
          model.Add(x_lower_bound - x[i] &lt;= 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)
  </code></pre>