{"action":"created","comment":{"url":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/comments/90797943","pull_request_review_id":11313216,"id":90797943,"diff_hunk":"@@ -8,27 +8,214 @@\n :sourcedir: .\n \n \n-[[partitionedSearchOverview]]\n-== Overview\n+[[partitionedSearchAlgorithm]]\n+== Algorithm Description\n \n-For very big datasets, it is sometimes worthwhile to partition the datasets into smaller pieces.\n+For big datasets, usually above 5000 planning entities,\n+it is usually worthwhile to partition the datasets into smaller pieces and solve those separately.\n+Partition Search is multi-threaded, leading to a performance boost due to more CPU utilization.\n+Additionally, it finds an initial solution faster, even if it only uses only 1 CPU,\n+because the search space sum of a partitioned Construction Heuristic is far less than its non-partitioned variant.\n \n-However, **partitioning leads to suboptimal results**, even if the pieces are solved optimally:\n+However, **partitioning does lead to suboptimal results**, even if the pieces are solved optimally, as shown below:\n \n image::Chapter-Partitioned_search/mapReduceIsTerribleForTsp.png[align=\"center\"]\n \n-A future version of Planner will have native support for several forms of partitioning.\n-Meanwhile, you can implement it yourself as shown in the image above.\n-Use an `Solver` to solve each piece.\n+One way to deal with this is to run a non-partitioned Local Search after the Partitioned Search phase.\n \n [NOTE]\n ====\n Not all use cases can be partitioned.\n-It only works on use cases for which the planning entities and value ranges can be divided into n pieces, such that none of the constraints cross piece boundaries.\n+It only works on use cases for which the planning entities and value ranges can be split into n partition,\n+such that none of the constraints cross the boundaries between partitions.\n ====\n \n \n+[[partitionedSearchConfiguration]]\n+== Configuration\n+\n+Simplest configuration:\n+\n+[source,xml,options=\"nowrap\"]\n+----\n+  <partitionedSearch>\n+    <solutionPartitionerClass>org.optaplanner.examples.cloudbalancing.variants.solver.partitioner.CloudBalancePartitioner</solutionPartitionerClass>\n+  </partitionedSearch>\n+----\n+\n+There are several ways to <<partitioningASolution,partition a solution>>.\n+\n+Advanced configuration:\n+\n+[source,xml,options=\"nowrap\"]\n+----\n+  <partitionedSearch>\n+    ...\n+    <solutionPartitionerClass>org.optaplanner.examples.cloudbalancing.variants.solver.partitioner.CloudBalancePartitioner</solutionPartitionerClass>\n+    <threadFactoryClass>...MyAppServerThreadFactory</threadFactoryClass>\n+    <runnablePartThreadLimit>4</runnablePartThreadLimit>\n+\n+    <constructionHeuristic>...</constructionHeuristic>\n+    <localSearch>...</localSearch>\n+  </partitionedSearch>\n+----\n+\n+The `threadFactoryClass` allows to plug in a custom `ThreadFactory` for environments\n+that don't like arbitrary thread creation,\n+such as most application servers, Android or Google App Engine.\n+\n+The `runnablePartThreadLimit` allows limiting CPU usage, see below.\n+\n+Just like a `<solver>` element, the `<partitionedSearch>` element can one or more <<solverPhase,phases>>.\n+Each of those phases will be run on each partition.","path":"optaplanner-docs/src/main/asciidoc/Chapter-Partitioned_search/Chapter-Partitioned_search.adoc","position":71,"original_position":71,"commit_id":"6c1a55b706299817f253a72d13839f53a249baf7","original_commit_id":"6c1a55b706299817f253a72d13839f53a249baf7","user":{"login":"gsheldon","id":9453232,"avatar_url":"https://avatars.githubusercontent.com/u/9453232?v=3","gravatar_id":"","url":"https://api.github.com/users/gsheldon","html_url":"https://github.com/gsheldon","followers_url":"https://api.github.com/users/gsheldon/followers","following_url":"https://api.github.com/users/gsheldon/following{/other_user}","gists_url":"https://api.github.com/users/gsheldon/gists{/gist_id}","starred_url":"https://api.github.com/users/gsheldon/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/gsheldon/subscriptions","organizations_url":"https://api.github.com/users/gsheldon/orgs","repos_url":"https://api.github.com/users/gsheldon/repos","events_url":"https://api.github.com/users/gsheldon/events{/privacy}","received_events_url":"https://api.github.com/users/gsheldon/received_events","type":"User","site_admin":false},"body":"\"Like the <solver> element, the <partitionedSearch> element can...\" run? There is a word missing here. ","created_at":"2016-12-05T03:07:11Z","updated_at":"2016-12-05T03:07:11Z","html_url":"https://github.com/droolsjbpm/optaplanner/pull/238#discussion_r90797943","pull_request_url":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/238","_links":{"self":{"href":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/comments/90797943"},"html":{"href":"https://github.com/droolsjbpm/optaplanner/pull/238#discussion_r90797943"},"pull_request":{"href":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/238"}}},"pull_request":{"url":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/238","id":96344773,"html_url":"https://github.com/droolsjbpm/optaplanner/pull/238","diff_url":"https://github.com/droolsjbpm/optaplanner/pull/238.diff","patch_url":"https://github.com/droolsjbpm/optaplanner/pull/238.patch","issue_url":"https://api.github.com/repos/droolsjbpm/optaplanner/issues/238","number":238,"state":"open","locked":false,"title":"Partitioned Search docs","user":{"login":"ge0ffrey","id":176880,"avatar_url":"https://avatars.githubusercontent.com/u/176880?v=3","gravatar_id":"","url":"https://api.github.com/users/ge0ffrey","html_url":"https://github.com/ge0ffrey","followers_url":"https://api.github.com/users/ge0ffrey/followers","following_url":"https://api.github.com/users/ge0ffrey/following{/other_user}","gists_url":"https://api.github.com/users/ge0ffrey/gists{/gist_id}","starred_url":"https://api.github.com/users/ge0ffrey/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ge0ffrey/subscriptions","organizations_url":"https://api.github.com/users/ge0ffrey/orgs","repos_url":"https://api.github.com/users/ge0ffrey/repos","events_url":"https://api.github.com/users/ge0ffrey/events{/privacy}","received_events_url":"https://api.github.com/users/ge0ffrey/received_events","type":"User","site_admin":false},"body":"","created_at":"2016-12-02T20:10:20Z","updated_at":"2016-12-05T03:07:11Z","closed_at":null,"merged_at":null,"merge_commit_sha":"5d8076b0c52aa6cd9d8799214216ec4403463b26","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/238/commits","review_comments_url":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/238/comments","review_comment_url":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/comments{/number}","comments_url":"https://api.github.com/repos/droolsjbpm/optaplanner/issues/238/comments","statuses_url":"https://api.github.com/repos/droolsjbpm/optaplanner/statuses/6c1a55b706299817f253a72d13839f53a249baf7","head":{"label":"ge0ffrey:PartitionedSearchDocs","ref":"PartitionedSearchDocs","sha":"6c1a55b706299817f253a72d13839f53a249baf7","user":{"login":"ge0ffrey","id":176880,"avatar_url":"https://avatars.githubusercontent.com/u/176880?v=3","gravatar_id":"","url":"https://api.github.com/users/ge0ffrey","html_url":"https://github.com/ge0ffrey","followers_url":"https://api.github.com/users/ge0ffrey/followers","following_url":"https://api.github.com/users/ge0ffrey/following{/other_user}","gists_url":"https://api.github.com/users/ge0ffrey/gists{/gist_id}","starred_url":"https://api.github.com/users/ge0ffrey/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ge0ffrey/subscriptions","organizations_url":"https://api.github.com/users/ge0ffrey/orgs","repos_url":"https://api.github.com/users/ge0ffrey/repos","events_url":"https://api.github.com/users/ge0ffrey/events{/privacy}","received_events_url":"https://api.github.com/users/ge0ffrey/received_events","type":"User","site_admin":false},"repo":{"id":1792278,"name":"optaplanner","full_name":"ge0ffrey/optaplanner","owner":{"login":"ge0ffrey","id":176880,"avatar_url":"https://avatars.githubusercontent.com/u/176880?v=3","gravatar_id":"","url":"https://api.github.com/users/ge0ffrey","html_url":"https://github.com/ge0ffrey","followers_url":"https://api.github.com/users/ge0ffrey/followers","following_url":"https://api.github.com/users/ge0ffrey/following{/other_user}","gists_url":"https://api.github.com/users/ge0ffrey/gists{/gist_id}","starred_url":"https://api.github.com/users/ge0ffrey/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ge0ffrey/subscriptions","organizations_url":"https://api.github.com/users/ge0ffrey/orgs","repos_url":"https://api.github.com/users/ge0ffrey/repos","events_url":"https://api.github.com/users/ge0ffrey/events{/privacy}","received_events_url":"https://api.github.com/users/ge0ffrey/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/ge0ffrey/optaplanner","description":"Drools Planner optimizes automated planning.","fork":true,"url":"https://api.github.com/repos/ge0ffrey/optaplanner","forks_url":"https://api.github.com/repos/ge0ffrey/optaplanner/forks","keys_url":"https://api.github.com/repos/ge0ffrey/optaplanner/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ge0ffrey/optaplanner/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ge0ffrey/optaplanner/teams","hooks_url":"https://api.github.com/repos/ge0ffrey/optaplanner/hooks","issue_events_url":"https://api.github.com/repos/ge0ffrey/optaplanner/issues/events{/number}","events_url":"https://api.github.com/repos/ge0ffrey/optaplanner/events","assignees_url":"https://api.github.com/repos/ge0ffrey/optaplanner/assignees{/user}","branches_url":"https://api.github.com/repos/ge0ffrey/optaplanner/branches{/branch}","tags_url":"https://api.github.com/repos/ge0ffrey/optaplanner/tags","blobs_url":"https://api.github.com/repos/ge0ffrey/optaplanner/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ge0ffrey/optaplanner/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ge0ffrey/optaplanner/git/refs{/sha}","trees_url":"https://api.github.com/repos/ge0ffrey/optaplanner/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ge0ffrey/optaplanner/statuses/{sha}","languages_url":"https://api.github.com/repos/ge0ffrey/optaplanner/languages","stargazers_url":"https://api.github.com/repos/ge0ffrey/optaplanner/stargazers","contributors_url":"https://api.github.com/repos/ge0ffrey/optaplanner/contributors","subscribers_url":"https://api.github.com/repos/ge0ffrey/optaplanner/subscribers","subscription_url":"https://api.github.com/repos/ge0ffrey/optaplanner/subscription","commits_url":"https://api.github.com/repos/ge0ffrey/optaplanner/commits{/sha}","git_commits_url":"https://api.github.com/repos/ge0ffrey/optaplanner/git/commits{/sha}","comments_url":"https://api.github.com/repos/ge0ffrey/optaplanner/comments{/number}","issue_comment_url":"https://api.github.com/repos/ge0ffrey/optaplanner/issues/comments{/number}","contents_url":"https://api.github.com/repos/ge0ffrey/optaplanner/contents/{+path}","compare_url":"https://api.github.com/repos/ge0ffrey/optaplanner/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ge0ffrey/optaplanner/merges","archive_url":"https://api.github.com/repos/ge0ffrey/optaplanner/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ge0ffrey/optaplanner/downloads","issues_url":"https://api.github.com/repos/ge0ffrey/optaplanner/issues{/number}","pulls_url":"https://api.github.com/repos/ge0ffrey/optaplanner/pulls{/number}","milestones_url":"https://api.github.com/repos/ge0ffrey/optaplanner/milestones{/number}","notifications_url":"https://api.github.com/repos/ge0ffrey/optaplanner/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ge0ffrey/optaplanner/labels{/name}","releases_url":"https://api.github.com/repos/ge0ffrey/optaplanner/releases{/id}","deployments_url":"https://api.github.com/repos/ge0ffrey/optaplanner/deployments","created_at":"2011-05-24T07:49:08Z","updated_at":"2016-04-27T17:59:56Z","pushed_at":"2016-12-02T20:10:02Z","git_url":"git://github.com/ge0ffrey/optaplanner.git","ssh_url":"git@github.com:ge0ffrey/optaplanner.git","clone_url":"https://github.com/ge0ffrey/optaplanner.git","svn_url":"https://github.com/ge0ffrey/optaplanner","homepage":"http://www.jboss.org/drools/drools-planner","size":156589,"stargazers_count":5,"watchers_count":5,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":5,"default_branch":"master"}},"base":{"label":"droolsjbpm:master","ref":"master","sha":"fc14d3397840eeace3d64b9dd826e7d573659b10","user":{"login":"droolsjbpm","id":517980,"avatar_url":"https://avatars.githubusercontent.com/u/517980?v=3","gravatar_id":"","url":"https://api.github.com/users/droolsjbpm","html_url":"https://github.com/droolsjbpm","followers_url":"https://api.github.com/users/droolsjbpm/followers","following_url":"https://api.github.com/users/droolsjbpm/following{/other_user}","gists_url":"https://api.github.com/users/droolsjbpm/gists{/gist_id}","starred_url":"https://api.github.com/users/droolsjbpm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/droolsjbpm/subscriptions","organizations_url":"https://api.github.com/users/droolsjbpm/orgs","repos_url":"https://api.github.com/users/droolsjbpm/repos","events_url":"https://api.github.com/users/droolsjbpm/events{/privacy}","received_events_url":"https://api.github.com/users/droolsjbpm/received_events","type":"Organization","site_admin":false},"repo":{"id":1370858,"name":"optaplanner","full_name":"droolsjbpm/optaplanner","owner":{"login":"droolsjbpm","id":517980,"avatar_url":"https://avatars.githubusercontent.com/u/517980?v=3","gravatar_id":"","url":"https://api.github.com/users/droolsjbpm","html_url":"https://github.com/droolsjbpm","followers_url":"https://api.github.com/users/droolsjbpm/followers","following_url":"https://api.github.com/users/droolsjbpm/following{/other_user}","gists_url":"https://api.github.com/users/droolsjbpm/gists{/gist_id}","starred_url":"https://api.github.com/users/droolsjbpm/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/droolsjbpm/subscriptions","organizations_url":"https://api.github.com/users/droolsjbpm/orgs","repos_url":"https://api.github.com/users/droolsjbpm/repos","events_url":"https://api.github.com/users/droolsjbpm/events{/privacy}","received_events_url":"https://api.github.com/users/droolsjbpm/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/droolsjbpm/optaplanner","description":"Java planning engine: OptaPlanner optimizes business resource scheduling and planning.","fork":false,"url":"https://api.github.com/repos/droolsjbpm/optaplanner","forks_url":"https://api.github.com/repos/droolsjbpm/optaplanner/forks","keys_url":"https://api.github.com/repos/droolsjbpm/optaplanner/keys{/key_id}","collaborators_url":"https://api.github.com/repos/droolsjbpm/optaplanner/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/droolsjbpm/optaplanner/teams","hooks_url":"https://api.github.com/repos/droolsjbpm/optaplanner/hooks","issue_events_url":"https://api.github.com/repos/droolsjbpm/optaplanner/issues/events{/number}","events_url":"https://api.github.com/repos/droolsjbpm/optaplanner/events","assignees_url":"https://api.github.com/repos/droolsjbpm/optaplanner/assignees{/user}","branches_url":"https://api.github.com/repos/droolsjbpm/optaplanner/branches{/branch}","tags_url":"https://api.github.com/repos/droolsjbpm/optaplanner/tags","blobs_url":"https://api.github.com/repos/droolsjbpm/optaplanner/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/droolsjbpm/optaplanner/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/droolsjbpm/optaplanner/git/refs{/sha}","trees_url":"https://api.github.com/repos/droolsjbpm/optaplanner/git/trees{/sha}","statuses_url":"https://api.github.com/repos/droolsjbpm/optaplanner/statuses/{sha}","languages_url":"https://api.github.com/repos/droolsjbpm/optaplanner/languages","stargazers_url":"https://api.github.com/repos/droolsjbpm/optaplanner/stargazers","contributors_url":"https://api.github.com/repos/droolsjbpm/optaplanner/contributors","subscribers_url":"https://api.github.com/repos/droolsjbpm/optaplanner/subscribers","subscription_url":"https://api.github.com/repos/droolsjbpm/optaplanner/subscription","commits_url":"https://api.github.com/repos/droolsjbpm/optaplanner/commits{/sha}","git_commits_url":"https://api.github.com/repos/droolsjbpm/optaplanner/git/commits{/sha}","comments_url":"https://api.github.com/repos/droolsjbpm/optaplanner/comments{/number}","issue_comment_url":"https://api.github.com/repos/droolsjbpm/optaplanner/issues/comments{/number}","contents_url":"https://api.github.com/repos/droolsjbpm/optaplanner/contents/{+path}","compare_url":"https://api.github.com/repos/droolsjbpm/optaplanner/compare/{base}...{head}","merges_url":"https://api.github.com/repos/droolsjbpm/optaplanner/merges","archive_url":"https://api.github.com/repos/droolsjbpm/optaplanner/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/droolsjbpm/optaplanner/downloads","issues_url":"https://api.github.com/repos/droolsjbpm/optaplanner/issues{/number}","pulls_url":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls{/number}","milestones_url":"https://api.github.com/repos/droolsjbpm/optaplanner/milestones{/number}","notifications_url":"https://api.github.com/repos/droolsjbpm/optaplanner/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/droolsjbpm/optaplanner/labels{/name}","releases_url":"https://api.github.com/repos/droolsjbpm/optaplanner/releases{/id}","deployments_url":"https://api.github.com/repos/droolsjbpm/optaplanner/deployments","created_at":"2011-02-15T19:38:23Z","updated_at":"2016-12-04T22:37:24Z","pushed_at":"2016-12-04T22:51:22Z","git_url":"git://github.com/droolsjbpm/optaplanner.git","ssh_url":"git@github.com:droolsjbpm/optaplanner.git","clone_url":"https://github.com/droolsjbpm/optaplanner.git","svn_url":"https://github.com/droolsjbpm/optaplanner","homepage":"http://www.optaplanner.org","size":161251,"stargazers_count":577,"watchers_count":577,"language":"Java","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":321,"mirror_url":null,"open_issues_count":9,"forks":321,"open_issues":9,"watchers":577,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/238"},"html":{"href":"https://github.com/droolsjbpm/optaplanner/pull/238"},"issue":{"href":"https://api.github.com/repos/droolsjbpm/optaplanner/issues/238"},"comments":{"href":"https://api.github.com/repos/droolsjbpm/optaplanner/issues/238/comments"},"review_comments":{"href":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/238/comments"},"review_comment":{"href":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/droolsjbpm/optaplanner/pulls/238/commits"},"statuses":{"href":"https://api.github.com/repos/droolsjbpm/optaplanner/statuses/6c1a55b706299817f253a72d13839f53a249baf7"}}}}
{"actor":{"display_login":"gsheldon"}}