{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# The River Pollution Problem"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from desdeo_emo.EAs.RVEA import RVEA\n",
    "from desdeo_problem import variable_builder, ScalarObjective, VectorObjective, MOProblem\n",
    "\n",
    "import numpy as np\n",
    "import pandas as pd\n",
    "from desdeo_emo.utilities.plotlyanimate import animate_init_, animate_next_"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# create the problem\n",
    "def f_1(x):\n",
    "    return 4.07 + 2.27 * x[:, 0]\n",
    "\n",
    "def f_2(x):\n",
    "    return 2.60 + 0.03*x[:, 0] + 0.02*x[:, 1] + 0.01 / (1.39 - x[:, 0]**2) + 0.30 / (1.39 - x[:, 1]**2)\n",
    "\n",
    "def f_3(x):\n",
    "    return 8.21 - 0.71 / (1.09 - x[:, 0]**2)\n",
    "\n",
    "def f_4(x):\n",
    "    return 0.96 - 0.96 / (1.09 - x[:, 1]**2)\n",
    "\n",
    "# def f_5(x):\n",
    "    # return -0.96 + 0.96 / (1.09 - x[:, 1]**2)\n",
    "\n",
    "def f_5(x):\n",
    "    return np.max([np.abs(x[:, 0] - 0.65), np.abs(x[:, 1] - 0.65)], axis=0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "f1 = ScalarObjective(name=\"f1\", evaluator=f_1, maximize=True)\n",
    "f2 = ScalarObjective(name=\"f2\", evaluator=f_2, maximize=True)\n",
    "f3 = ScalarObjective(name=\"f3\", evaluator=f_3, maximize=True)\n",
    "f4 = ScalarObjective(name=\"f4\", evaluator=f_4, maximize=True)\n",
    "f5 = ScalarObjective(name=\"f5\", evaluator=f_5, maximize=False)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "varsl = variable_builder([\"x_1\", \"x_2\"],\n",
    "        initial_values=[0.5, 0.5],\n",
    "        lower_bounds=[0.3, 0.3],\n",
    "        upper_bounds=[1.0, 1.0]\n",
    "        )"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "problem = MOProblem(variables=varsl, objectives=[f1, f2, f3, f4, f5])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Plot saved as:  river.html\n",
      "View the plot by opening the file in browser.\n",
      "To view the plot in Jupyter Notebook, use the IFrame command.\n"
     ]
    }
   ],
   "source": [
    "evolver = RVEA(problem, interact=True, n_iterations=5, n_gen_per_iter=100)\n",
    "figure = animate_init_(evolver.population.objectives, filename=\"river.html\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "pref, plot = evolver.start()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "               f1       f2       f3          f4        f5\n",
      "minimize       -1       -1       -1          -1         1\n",
      "ideal     6.33643  3.40833  7.49815 -0.00301699  0.013136\n",
      "nadir        -inf     -inf     -inf        -inf       inf\n"
     ]
    }
   ],
   "source": [
    "print(plot.content[\"dimensions_data\"])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Please provide preferences. There is four ways to do this. You can either:\n",
      "\n",
      "\t1: Select preferred solution(s)\n",
      "\t2: Select non-preferred solution(s)\n",
      "\t3: Specify a reference point worse than or equal to the ideal point\n",
      "\t4: Specify desired ranges for objectives.\n",
      "\n",
      "In case you choose \n",
      "\n",
      "1, please specify index/indices of preferred solutions in a numpy array (indexing starts from 0).\n",
      "For example: \n",
      "\tnumpy.array([1]), for choosing the solutions with index 1.\n",
      "\tnumpy.array([2, 4, 5, 16]), for choosing the solutions with indices 2, 4, 5, and 16.\n",
      "\n",
      "2, please specify index/indices of non-preferred solutions in a numpy array (indexing starts from 0).\n",
      "For example: \n",
      "\tnumpy.array([3]), for choosing the solutions with index 3.\n",
      "\tnumpy.array([1, 2]), for choosing the solutions with indices 1 and 2.\n",
      "\n",
      "3, please provide a reference point worse than or equal to the ideal point:\n",
      "\n",
      "f1       6.33643\n",
      "f2       3.40833\n",
      "f3       7.49815\n",
      "f4   -0.00301699\n",
      "f5      0.013136\n",
      "Name: ideal, dtype: object\n",
      "The reference point will be used to focus the reference vectors towards the preferred region.\n",
      "If a reference point is not provided, the previous state of the reference vectors is used.\n",
      "If the reference point is the same as the ideal point, the reference vectors are spread uniformly in the objective space.\n",
      "\n",
      "4, please specify desired lower and upper bound for each objective, starting from \n",
      "the first objective and ending with the last one. Please specify the bounds as a numpy array containing \n",
      "lists, so that the first item of list is the lower bound and the second the upper bound, for each \n",
      "objective. \n",
      "\tFor example: numpy.array([[1, 2], [2, 5], [0, 3.5]]), for problem with three objectives.\n",
      "Ideal vector: \n",
      "f1       6.33643\n",
      "f2       3.40833\n",
      "f3       7.49815\n",
      "f4   -0.00301699\n",
      "f5      0.013136\n",
      "Name: ideal, dtype: object\n",
      "Nadir vector: \n",
      "f1   -inf\n",
      "f2   -inf\n",
      "f3   -inf\n",
      "f4   -inf\n",
      "f5    inf\n",
      "Name: nadir, dtype: object.\n"
     ]
    }
   ],
   "source": [
    "print(pref[0].content['message'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [],
   "source": [
    "pref[2].response = pd.DataFrame([[6.3,3.3,7,-2,0.3]],\n",
    "                             columns=pref[2].content['dimensions_data'].columns)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Current generation number:400. Is looping back recommended: Yes\n"
     ]
    }
   ],
   "source": [
    "pref, plot = evolver.iterate(pref[2])\n",
    "figure = animate_next_(\n",
    "    plot.content['data'].values,\n",
    "    figure,\n",
    "    filename=\"river.html\",\n",
    "    generation=evolver._iteration_counter,\n",
    ")\n",
    "\n",
    "message = (f\"Current generation number:{evolver._current_gen_count}. \"\n",
    "           f\"Is looping back recommended: {'Yes' if evolver.continue_evolution() else 'No'}\")\n",
    "print(message)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "desdeo-emo",
   "language": "python",
   "name": "desdeo-emo"
  },
  "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.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
