\n",
"

"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's have a look at $f(x)$ in Equation 1. This is a function which takes the solution $x$ as input and then uses it for some calculations before giving us some output. The subscript $\\mathrm{M}$ indicates the number of objectives we can expect, so for a two-objective problem, we can say $\\mathrm{M}=2$. For the sake of example, let's say that $f_{1}(x)$ will calculate the sum of all elements in $x$, and $f_{2}$ will calculate the product of all elements in $x$."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"f_1(x) = \\sum_{k=1}^{n} x_k \\tag{3.1}\n",
"$$\n",
"\n",
"$$\n",
"f_2(x) = \\prod_{k=1}^{n} x_k \\tag{3.2}\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can implement such an objective function in Python quite easily."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [],
"source": [
"def f(x):\n",
" f1 = np.sum(x); # Equation (3.1)\n",
" f2 = np.prod(x); # Equation (3.2)\n",
" return np.array([f1, f2])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Now let's invoke this function and pass in the solution $x$ that we made earlier. We'll store the results in a variable named $y$, in line with Equation 4."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"$$\n",
"y_{M} = f(x) \\tag{4}\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Which translated to Python will look something like the following."
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[2.74649324e+00 5.04711459e-05]\n"
]
}
],
"source": [
"y = f(x)\n",
"print(y)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This has returned our two objective values which quantify the performance of the corresponding solution's problem variables. There is much more to an objective function than what we've covered here, and the objectives we have defined here are entirely arbitrary. Nonetheless, we have implemented a two-objective (or bi-objective) function which we may wish to minimise or maximise.\n",
"\n",
"Let's use Python to generate 50 more solutions $x$ with $\\mathrm{D}=8$ variables and calculate their objective values according to Equations 3.1 and 3.2."
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"objective_values = np.empty((0, 2))\n",
"\n",
"for i in range(50):\n",
" x = np.random.rand(8)\n",
" y = f(x)\n",
" objective_values = np.vstack([objective_values, y])\n",
" \n",
"# convert to DataFrame\n",
"objective_values = pd.DataFrame(objective_values, columns=['f1','f2'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We won't output these 50 solutions in the interest of saving space, but let's instead visualise all 50 of them using a scatter plot. "
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
" \n",
" "
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"Note

\n", "When running this notebook for yourself, you should expect the numbers to be different because we are generating random numbers.

\n", "\n",
" \n",
" \n",
" \n",
" \n",
"

"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"fig = go.Figure()\n",
"fig.add_scatter(x=objective_values.f1, y=objective_values.f2, mode='markers')\n",
"fig.show()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Conclusion"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"In this section, we covered the very basics in what we mean by an objective function. We expressed the concept mathematically and then made a direct implementation using Python. We then generated a set of 50 solutions, calculated the objective values for each one, and plotted the objective space using a scatterplot.\n",
"\n",
"In the next section, we will look at a popular and synthetic objective function named *ZDT1*, following a similar approach where we implement a Python function from its mathematical form."
]
}
],
"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.7.7"
},
"nikola": {
"category": "practical-evolutionary-algorithms",
"date": "2019-07-14 10:51:44 UTC+01:00",
"description": "",
"link": "",
"slug": "objective-functions",
"tags": "",
"title": "Objective Functions",
"type": "text"
}
},
"nbformat": 4,
"nbformat_minor": 4
}