{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Tutorial 3: solving your first optimization problem with ABC" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "nbsphinx": "hidden" }, "outputs": [], "source": [ "# Set Plotly to render plots as interactive in notebooks (this cell will be hidden: I set \"nbsphinx\": \"hidden\" in the cell metadata)\n", "import plotly.io as pio\n", "pio.renderers.default = \"notebook\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this tutorial, you will learn how to use the *Artificial Bee Colony (ABC)* algorithm to optimize a complex objective function. You will get through the process of setting up the `ArtificialBeeColony` class and the configuration of its `optimize` method. As an example, we will consider the *Eggholder* function, a 2D function defined as follows:\n", "\n", "$$f((x_1,x_2)) = -(x_2 + 47) \\sin\\left(\\sqrt{\\left|x_2 + \\frac{x_1}{2} + 47\\right|}\\right) - x_1 \\sin\\left(\\sqrt{|x_1 - (x_2 + 47)|}\\right)$$" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The first step is to define a `BenchmarkFunction` object that represents the *Eggholder* function. We can either define it from scratch or we can import it directly from the `beeoptimal.benchmarks` module." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Benchmark:\n", " Eggholder\n", "\n", "Default Bounds:\n", " [[-512 512]\n", " [-512 512]]\n", "\n", "Optimal Solution:\n", " [512. 404.2319]\n", "\n", "Optimal Value:\n", " -959.6406627106155\n" ] } ], "source": [ "from beeoptimal.benchmarks import Eggholder\n", "\n", "print(f\"\\nBenchmark:\\n {Eggholder.name}\")\n", "print(f\"\\nDefault Bounds:\\n {Eggholder.bounds}\")\n", "print(f\"\\nOptimal Solution:\\n {Eggholder.optimal_solution}\")\n", "print(f\"\\nOptimal Value:\\n {Eggholder.optimal_value}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The next step is to import and instanciate an `ArtificialBeeColony` object. Its attributes are the following:\n", "\n", "- `colony_size`: the number of bees in the colony (at least 10 in order to ensure compatibility with all the implemented mutation strategies)\n", "- `function`: the function to optimize\n", "- `bounds`: the search space bounds\n", "- `n_employed_bees`: the number of employed bees\n", "- `max_scouts`: the maximum number of scout bees per iteration\n", "\n", "The most simple way to initialize it is the following:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "from beeoptimal import ArtificialBeeColony\n", "\n", "ABC = ArtificialBeeColony(\n", " colony_size = 100,\n", " function = Eggholder.fun,\n", " bounds = Eggholder.bounds,\n", " )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ".. note::\n", " If the attributes `n_employed_bees` and `max_scouts` are not provided, they will be both set to `colony_size//2`.\n", " In case you want to use a different number of employed bees or max scouts, just set them manually.\n", "\n", "\n", "When specifying `n_employed_bees` and `max_scouts`, make sure to respect the following constraints:\n", " \n", "- 5 $<$ `n_employed_bees` $\\leq$ `colony_size`\n", "- 0 $<$ `max_scouts` $\\leq$ `n_employed_bees`\n", " \n", "where the condition `n_employed_bees` > 5 is needed to ensure compatibility with all the implemented mutation strategies." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We are finally ready to call the `optimize` method. In this example, we will set up a standard configuration for the ABC algorithm" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Running Optimization: 100%|██████████|[00:05<00:00]\n" ] } ], "source": [ "ABC.optimize(\n", " max_iters = 1000,\n", " limit = 'default',\n", " selection = 'RouletteWheel',\n", " mutation = 'StandardABC',\n", " initialization = 'random',\n", " stagnation_tol = 1e-6,\n", " random_seed = 1234,\n", " verbose = True \n", " )" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "**************************************************\n", "Optimal Solution:\n", "\tExpected : [512. 404.2319]\n", "\tFound : [512. 404.23180504]\n", "Optimal Value:\n", "\tExpected : -959.6406627106155\n", "\tFound : -959.640662720851\n", "**************************************************\n" ] } ], "source": [ "print('*'*50)\n", "print(f\"Optimal Solution:\")\n", "print(f\"\\tExpected : {Eggholder.optimal_solution}\")\n", "print(f\"\\tFound : {ABC.optimal_bee.position}\")\n", "print(f\"Optimal Value:\")\n", "print(f\"\\tExpected : {Eggholder.optimal_value}\")\n", "print(f\"\\tFound : {ABC.optimal_bee.value}\")\n", "print('*'*50)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "If you want to experiment with another configuration, you can just reset the `ArtificialBeeColony` object and call the `optimize` method again, without the need of instantiating a new object." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "ABC.reset()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Another possible configuration:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "Running Optimization: 86%|████████▌ |[00:05<00:00]" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Early termination: Optimization stagnated at iteration 861 / 1000\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "ABC.optimize(\n", " max_iters = 1000,\n", " limit = 'default',\n", " selection = 'Tournament',\n", " tournament_size = 20,\n", " mutation = 'ABC/best/1',\n", " initialization = 'cahotic',\n", " sf = 1.0,\n", " self_adaptive_sf = False,\n", " stagnation_tol = 1e-6,\n", " random_seed = 1234,\n", " verbose = True \n", " )" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "**************************************************\n", "Optimal Solution:\n", "\tExpected : [512. 404.2319]\n", "\tFound : [512. 404.23180513]\n", "Optimal Value:\n", "\tExpected : -959.6406627106155\n", "\tFound : -959.640662720851\n", "**************************************************\n" ] } ], "source": [ "print('*'*50)\n", "print(f\"Optimal Solution:\")\n", "print(f\"\\tExpected : {Eggholder.optimal_solution}\")\n", "print(f\"\\tFound : {ABC.optimal_bee.position}\")\n", "print(f\"Optimal Value:\")\n", "print(f\"\\tExpected : {Eggholder.optimal_value}\")\n", "print(f\"\\tFound : {ABC.optimal_bee.value}\")\n", "print('*'*50)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "name": "python", "version": "3.12.1" } }, "nbformat": 4, "nbformat_minor": 2 }