anchor.diff:  [[partitionedSearchAlgorithm]]
   == Algorithm Description
   
  -For big datasets, usually above 5000 planning entities,
  -it is usually worthwhile to partition the datasets into smaller pieces and solve those separately.
  -Partition Search is multi-threaded, leading to a performance boost due to more CPU utilization.
  -Additionally, it finds an initial solution faster, even if it only uses only 1 CPU,
  +It is often more efficient to partition large data sets (usually above 5000 planning entities)
  +into smaller pieces and solve them separately.
  +Partition Search is multi-threaded, so it provides a performance boost on multi-core machines
  +due to higher CPU utilization.
  +Additionally, even when only using one CPU, it finds an initial solution faster,
   because the search space sum of a partitioned Construction Heuristic is far less than its non-partitioned variant.
   
   However, **partitioning does lead to suboptimal results**, even if the pieces are solved optimally, as shown below:
   
   image::Chapter-Partitioned_search/mapReduceIsTerribleForTsp.png[align="center"]
   
  -One way to deal with this is to run a non-partitioned Local Search after the Partitioned Search phase.
  +It effectively trades a short term gain in solution quality for long term loss.
  +One way to compensate for this loss,
  +is to run a non-partitioned Local Search after the Partitioned Search phase.
   
   [NOTE]
   ====
   Not all use cases can be partitioned.
   It only works on use cases for which the planning entities and value ranges can be split into n partition,
   such that none of the constraints cross the boundaries between partitions.
  +Partitioning only works for use cases where the planning entities and value ranges can be split into n partitions,
  +without any of the constraints crossing boundaries between partitions.
   ====
   
   
  
positive.code: }
  ----
  
  The `size()` of the returned `List` is the `partCount`, so the number of partitions.
  This can be decided dynamically, for example based on the size of the non-partitioned solution.
  The `partCount` is unrelated to the `runnablePartThreadLimit`.
  
  For example:
  
negative.code: ----
  
  The `threadFactoryClass` allows to plug in a custom `ThreadFactory` for environments
  where arbitrary thread creation should be avoided, such as most application servers, Android, or Google App Engine.
  
  The `runnablePartThreadLimit` allows limiting CPU usage, see below.
  
  Just like a `<solver>` element, the `<partitionedSearch>` element can contain one or more <<solverPhase,phases>>.
  Each of those phases will be run on each partition.
  
  A common configuration is to first run a Partitioned Search phase
  (which includes a Construction Heuristic and a Local Search)
  followed by a non-partitioned Local Search phase:
  
  [source,xml,options="nowrap"]
  ----
  