{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Tutorial 2: ready-to-use benchmarks and visualization" ] }, { "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 the previous tutorial, you have learnt how to define your own custom benchmark function using the BenchmarkFunction class. In this tutorial, you will learn how to use the ready-to-use benchmark functions provided by the `beeoptimal.benchmarks` module. These pre-defined functions are designed to help you quickly test optimization algorithms without having to implement the functions yourself. Additionally, you will get introduced to some visualization tools that allow a better understanding of the optimization landscapes.\n", "\n", "At the moment, the available ready-to-use benchmark functions are the following:\n", "\n", "- Sphere\n", "- Rosenbrock\n", "- Ackley\n", "- Rastrigin\n", "- Weierstrass\n", "- Griewank\n", "- Schwefel\n", "- Sumsquares\n", "- Eggholder\n", "\n", "Except from the Eggholder, which is inherently a 2D function, all the other functions are available in 2,10 and 30 dimensions." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For this tutorial, we will focus on the 2D Griewank function, as its landscape offers interesting features that become more apparent depending on the zoom level we apply." ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "from beeoptimal.benchmarks import Griewank2d\n", "from beeoptimal.plotting import contourplot,surfaceplot" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can easily evaluate the function in the same way as we did in the previous tutorial." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "Benchmark:\n", " Griewank-2d\n", "\n", "Default Bounds:\n", " [[-600 600]\n", " [-600 600]]\n", "\n", "Optimal Solution:\n", " [0. 0.]\n", "\n", "Optimal Value:\n", " 0.0\n" ] } ], "source": [ "print(f\"\\nBenchmark:\\n {Griewank2d.name}\")\n", "print(f\"\\nDefault Bounds:\\n {Griewank2d.bounds}\")\n", "print(f\"\\nOptimal Solution:\\n {Griewank2d.optimal_solution}\")\n", "print(f\"\\nOptimal Value:\\n {Griewank2d.optimal_value}\")" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Griewank-2d function evaluated at x=[-572.05440973 -548.83516035] --> f(x)=158.02230710936988\n" ] } ], "source": [ "x = np.random.uniform(low=Griewank2d.bounds[:,0], high=Griewank2d.bounds[:,1], size=len(Griewank2d.bounds))\n", "f_x = Griewank2d.evaluate(x)\n", "print(f\"{Griewank2d.name} function evaluated at x={x} --> f(x)={f_x}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As mentioned above, `BeeOptimal` provides two visualization tools that facilitate the exploration of the benchmark functions:\n", "\n", "- `contourplot`\n", "- `surfaceplot`\n", "\n", ".. warning::\n", " These visualization tools are designed specifically for 2D functions, as we cannot visualize more than three dimensions (unless you have exceeded the glasses of brandy...😵‍💫🥃)\n", " " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The most simple way to use them is the following:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "text/html": [ " \n", " " ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "griewank2d_contourplot = contourplot(\n", " function=Griewank2d,\n", " title=f'Contourplot for {Griewank2d.name} function',\n", " figsize=(600,600)\n", " )\n", "\n", "griewank2d_surfaceplot = surfaceplot(\n", " function=Griewank2d,\n", " title=f'Surfaceplot for {Griewank2d.name} function',\n", " figsize=(600,600)\n", " )\n", "\n", "griewank2d_contourplot.show()\n", "griewank2d_surfaceplot.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By default, the plotting functions use the bounds defined in the benchmark function. However, for visualization purposes, you might want to adjust these bounds. The functions allow you to either pass custom bounds as arguments or specify a zoom factor. These two options can also be combined for greater flexibility in your visualizations." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "text/html": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "p1 = surfaceplot(\n", " function = Griewank2d,\n", " title = f'{Griewank2d.name} Surface [DEFAULT BOUNDS]',\n", " figsize = (500,500)\n", " )\n", "\n", "p2 = surfaceplot(\n", " function = Griewank2d,\n", " title = f'{Griewank2d.name} Surface [CUSTOM BOUNDS]',\n", " figsize = (500,500),\n", " bounds = np.array([[-60,60],[-60,60]]),\n", " )\n", "\n", "p3 = surfaceplot(\n", " function = Griewank2d,\n", " title = f'{Griewank2d.name} Surface [ZOOM]',\n", " figsize = (500,500),\n", " zoom = 0.02\n", " )\n", "\n", "p4 = surfaceplot(\n", " function = Griewank2d,\n", " title = f'{Griewank2d.name} Surface [CUSTOM BOUNDS & ZOOM]',\n", " figsize = (500,500),\n", " bounds = np.array([[-0.5,0.5],[-0.5,0.5]]),\n", " zoom = 10.0\n", " )\n", "\n", "p1.show()\n", "p2.show()\n", "p3.show()\n", "p4.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ ".. note::\n", " Both `bounds` and `zoom` arguments can be passed to the function `contourplot` in the same way as to the function `surfaceplot`." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "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.12.1" } }, "nbformat": 4, "nbformat_minor": 2 }