Skip to content

Commit

Permalink
Merge pull request #65 from thomaswmorris/pareto
Browse files Browse the repository at this point in the history
Add functionality for Pareto optimization
  • Loading branch information
thomaswmorris authored Apr 18, 2024
2 parents 5e0fc07 + dfa413f commit 654410b
Show file tree
Hide file tree
Showing 18 changed files with 545 additions and 220 deletions.
3 changes: 2 additions & 1 deletion docs/source/tutorials.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Tutorials
.. toctree::
:maxdepth: 2

tutorials/himmelblau.ipynb
tutorials/introduction.ipynb
tutorials/hyperparameters.ipynb
tutorials/pareto-fronts.ipynb
tutorials/passive-dofs.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@
"metadata": {},
"outputs": [],
"source": [
"RE(agent.learn(\"quasi-random\", n=32))\n",
"RE(agent.learn(\"quasi-random\", n=36))\n",
"agent.plot_objectives()"
]
},
Expand Down Expand Up @@ -294,7 +294,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 3.11.5 64-bit",
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
Expand All @@ -308,7 +308,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.5"
"version": "3.10.0"
},
"vscode": {
"interpreter": {
Expand Down
159 changes: 159 additions & 0 deletions docs/source/tutorials/pareto-fronts.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
{
"cells": [
{
"attachments": {},
"cell_type": "markdown",
"id": "e7b5e13a-c059-441d-8d4f-fff080d52054",
"metadata": {},
"source": [
"# Multiobjective optimization with Pareto front mapping\n",
"\n",
"One way to do multiobjective optimization is with Pareto optimization, which explores the set of Pareto-efficient points. A point is Pareto-efficient if there are no other valid points that are better at every objective: it shows the \"trade-off\" between several objectives. "
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "cac0177b-576c-4f01-b306-2e9e8544a05c",
"metadata": {},
"outputs": [],
"source": [
"from blop.utils import prepare_re_env\n",
"\n",
"%run -i $prepare_re_env.__file__ --db-type=temp"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "120812d8-5de2-4efa-8fc6-2d8e4cd0693e",
"metadata": {},
"outputs": [],
"source": [
"from blop import DOF, Objective, Agent\n",
"from blop.utils import functions\n",
"from blop.dofs import BrownianMotion\n",
"\n",
"import numpy as np\n",
"\n",
"\n",
"def digestion(db, uid):\n",
" products = db[uid].table()\n",
"\n",
" for index, entry in products.iterrows():\n",
" x1, x2 = entry.x1, entry.x2\n",
"\n",
" products.loc[index, \"f1\"] = (x1 - 2) ** 2 + (x2 - 1) + 2\n",
" products.loc[index, \"f2\"] = 9 * x1 - (x2 - 1) + 2\n",
" products.loc[index, \"c1\"] = x1**2 + x2**2\n",
" products.loc[index, \"c2\"] = x1 - 3 * x2 + 10\n",
"\n",
" return products\n",
"\n",
"\n",
"dofs = [\n",
" DOF(name=\"x1\", search_domain=(-20, 20)),\n",
" DOF(name=\"x2\", search_domain=(-20, 20)),\n",
"]\n",
"\n",
"\n",
"objectives = [\n",
" Objective(name=\"f1\", target=\"min\"),\n",
" Objective(name=\"f2\", target=\"min\"),\n",
" Objective(name=\"c1\", target=(-np.inf, 225)),\n",
" Objective(name=\"c2\", target=(-np.inf, 0)),\n",
"]\n",
"\n",
"agent = Agent(\n",
" dofs=dofs,\n",
" objectives=objectives,\n",
" digestion=digestion,\n",
" db=db,\n",
")\n",
"\n",
"(uid,) = RE(agent.learn(\"qr\", n=64))"
]
},
{
"cell_type": "markdown",
"id": "d81c6af2-0a4c-4d31-9b7c-cc3065550b98",
"metadata": {},
"source": [
"We can plot our fitness and constraint objectives to see their models:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "c6c08f53-e96b-4987-ba3d-a93c84468b0b",
"metadata": {},
"outputs": [],
"source": [
"agent.plot_objectives()"
]
},
{
"cell_type": "markdown",
"id": "48b976e6-048a-4e16-9a1c-500203a2e195",
"metadata": {},
"source": [
"We can plot the Pareto front (the set of all Pareto-efficient points), which shows the trade-off between the two fitnesses. The points in blue comprise the Pareto front, while the points in red are either not Pareto efficient or are invalidated by one of the constraints."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "990a877e-f533-419c-bf5d-569ad7e72c6b",
"metadata": {},
"outputs": [],
"source": [
"agent.plot_pareto_front()"
]
},
{
"cell_type": "markdown",
"id": "29d7f4fb-8f25-4b57-982f-28737fad2a7c",
"metadata": {},
"source": [
"We can explore the Pareto front by choosing a random point on the Pareto front and computing the expected improvement in the hypervolume of all fitness objectives with respect to that point (called the \"reference point\"). All this is done automatically with the `qnehvi` acquisition function:"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "b49e6233-b228-43a3-9d8a-722a82e93443",
"metadata": {},
"outputs": [],
"source": [
"# this is broken now but is fixed in the next PR\n",
"# RE(agent.learn(\"qnehvi\", n=4))"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.0"
},
"vscode": {
"interpreter": {
"hash": "b0fa6594d8f4cbf19f97940f81e996739fb7646882a419484c72d19e05852a7e"
}
}
},
"nbformat": 4,
"nbformat_minor": 5
}
2 changes: 1 addition & 1 deletion docs/source/tutorials/passive-dofs.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.5"
"version": "3.10.0"
},
"vscode": {
"interpreter": {
Expand Down
Loading

0 comments on commit 654410b

Please sign in to comment.