forked from anyoptimization/pymoo
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
250 additions
and
43 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,206 @@ | ||
{ | ||
"cells": [ | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": { | ||
"raw_mimetype": "text/restructuredtext" | ||
}, | ||
"source": [ | ||
".. _nb_repair:" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"## Repair Operator\n", | ||
"\n", | ||
"The repair operator is mostly problem dependent. Most commonly it is used to make sure the algorithm is only searching in the feasible space. It is applied after the offsprings have been reproduced. In the following, we are using the knapsack problem to demonstrate the repair operator in *pymoo*.\n", | ||
"\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"In the well-known **Knapsack Problem**. In this problem, a knapsack has to be filled with items without violating the maximum weight constraint. Each item $j$ has a value $b_j \\geq 0$ and a weight $w_j \\geq 0$ where $j \\in \\{1, .., m\\}$. The binary decision vector $z = (z_1, .., z_m)$ defines, if an item is picked or not. The aim is to maximize the profit $g(z)$:\n", | ||
"\n", | ||
"\\begin{eqnarray}\n", | ||
"max & & g(z) \\\\[2mm] \\notag \n", | ||
"\\text{s.t.} & & \\sum_{j=1}^m z_j \\, w_j \\leq Q \\\\[1mm] \\notag \n", | ||
"& & z = (z_1, .., z_m) \\in \\mathbb{B}^m \\\\[1mm] \\notag \n", | ||
"g(z) & = & \\sum_{j=1}^{m} z_j \\, b_j \\\\[2mm] \\notag \n", | ||
"\\end{eqnarray}\n", | ||
"\n", | ||
"Because the constraint $\\sum_{j=1}^m z_j \\, w_j \\leq Q$ is fairly easy to satisfy. Therefore, we make sure before evaluating the objective function, that this constraint is not violated.\n", | ||
"\n", | ||
"\n", | ||
"In this framework, a Repair class has to be defined. problem and the population are given as input. The repaired population has to be returned." | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 1, | ||
"metadata": {}, | ||
"outputs": [], | ||
"source": [ | ||
"from pymoo.model.repair import Repair\n", | ||
"\n", | ||
"class ConsiderMaximumWeightRepair(Repair):\n", | ||
"\n", | ||
" def _do(self, problem, pop, **kwargs):\n", | ||
" \n", | ||
" # maximum capacity for the problem\n", | ||
" Q = problem.C\n", | ||
" \n", | ||
" # the packing plan for the whole population (each row one individual)\n", | ||
" Z = pop.get(\"X\")\n", | ||
" \n", | ||
" # the corresponding weight of each individual\n", | ||
" weights = (Z * problem.W).sum(axis=1)\n", | ||
" \n", | ||
" # now repair each indvidiual i\n", | ||
" for i in range(len(Z)):\n", | ||
" \n", | ||
" # the packing plan for i\n", | ||
" z = Z[i]\n", | ||
" \n", | ||
" # while the maximum capacity violation holds\n", | ||
" while weights[i] > Q:\n", | ||
" \n", | ||
" # randomly select an item currently picked\n", | ||
" item_to_remove = random.choice(np.where(z)[0])\n", | ||
" \n", | ||
" # and remove it\n", | ||
" z[item_to_remove] = False\n", | ||
" \n", | ||
" # adjust the weight\n", | ||
" weights[i] -= problem.W[item_to_remove]\n", | ||
" \n", | ||
" # set the design variables for the population\n", | ||
" pop.set(\"X\", Z)\n", | ||
" return pop" | ||
] | ||
}, | ||
{ | ||
"cell_type": "code", | ||
"execution_count": 2, | ||
"metadata": {}, | ||
"outputs": [ | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"\n", | ||
"------------------\n", | ||
"Optimization with no Repair: \n", | ||
"------------------\n", | ||
"\n", | ||
"==================================================\n", | ||
"n_gen | n_eval | cv (min/avg) | favg | fopt \n", | ||
"==================================================\n", | ||
"1 | 200 | 154.00000 / 505.73500 | - | - \n", | ||
"2 | 400 | 154.00000 / 363.68000 | - | - \n", | ||
"3 | 600 | 58.00000 / 275.94000 | - | - \n", | ||
"4 | 800 | 0.00000 / 197.59500 | -205.00000 | -205.0000000000\n", | ||
"5 | 1000 | 0.00000 / 136.85500 | -219.66667 | -293.0000000000\n", | ||
"6 | 1200 | 0.00000 / 82.15500 | -281.37500 | -436.0000000000\n", | ||
"7 | 1400 | 0.00000 / 38.68000 | -262.23404 | -449.0000000000\n", | ||
"8 | 1600 | 0.00000 / 8.63000 | -253.61017 | -449.0000000000\n", | ||
"9 | 1800 | 0.00000 / 0.00000 | -262.31500 | -472.0000000000\n", | ||
"10 | 2000 | 0.00000 / 0.00000 | -316.07000 | -516.0000000000\n", | ||
"\n", | ||
"------------------\n", | ||
"Optimization with Repair: \n", | ||
"------------------\n", | ||
"\n", | ||
"==================================================\n", | ||
"n_gen | n_eval | cv (min/avg) | favg | fopt \n", | ||
"==================================================\n", | ||
"1 | 200 | 0.00000 / 0.00000 | -129.94500 | -418.0000000000\n" | ||
] | ||
}, | ||
{ | ||
"name": "stdout", | ||
"output_type": "stream", | ||
"text": [ | ||
"2 | 400 | 0.00000 / 0.00000 | -214.11000 | -418.0000000000\n", | ||
"3 | 600 | 0.00000 / 0.00000 | -268.92500 | -510.0000000000\n", | ||
"4 | 800 | 0.00000 / 0.00000 | -328.63000 | -527.0000000000\n", | ||
"5 | 1000 | 0.00000 / 0.00000 | -378.17500 | -563.0000000000\n", | ||
"6 | 1200 | 0.00000 / 0.00000 | -418.38500 | -581.0000000000\n", | ||
"7 | 1400 | 0.00000 / 0.00000 | -456.14000 | -644.0000000000\n", | ||
"8 | 1600 | 0.00000 / 0.00000 | -489.85000 | -644.0000000000\n", | ||
"9 | 1800 | 0.00000 / 0.00000 | -518.60500 | -677.0000000000\n", | ||
"10 | 2000 | 0.00000 / 0.00000 | -538.90500 | -677.0000000000\n" | ||
] | ||
} | ||
], | ||
"source": [ | ||
"import numpy as np\n", | ||
"\n", | ||
"from pymoo.factory import get_algorithm, get_crossover, get_mutation, get_sampling\n", | ||
"from pymoo.optimize import minimize\n", | ||
"from pymoo.rand import random\n", | ||
"from pymop import create_random_knapsack_problem\n", | ||
"\n", | ||
"\n", | ||
"method = get_algorithm(\"ga\",\n", | ||
" pop_size=200,\n", | ||
" sampling=get_sampling(\"bin_random\"),\n", | ||
" crossover=get_crossover(\"bin_hux\"),\n", | ||
" mutation=get_mutation(\"bin_bitflip\"),\n", | ||
" elimate_duplicates=True)\n", | ||
"\n", | ||
"print(\"\\n------------------\\nOptimization with no Repair: \\n------------------\\n\")\n", | ||
"\n", | ||
"res = minimize(create_random_knapsack_problem(30),\n", | ||
" method,\n", | ||
" termination=('n_gen', 10),\n", | ||
" disp=True)\n", | ||
"\n", | ||
"\n", | ||
"print(\"\\n------------------\\nOptimization with Repair: \\n------------------\\n\")\n", | ||
"\n", | ||
"\n", | ||
"method.repair = ConsiderMaximumWeightRepair()\n", | ||
"\n", | ||
"\n", | ||
"res = minimize(create_random_knapsack_problem(30),\n", | ||
" method,\n", | ||
" termination=('n_gen', 10),\n", | ||
" disp=True)\n", | ||
"\n", | ||
"\n" | ||
] | ||
}, | ||
{ | ||
"cell_type": "markdown", | ||
"metadata": {}, | ||
"source": [ | ||
"As it can be seen, the repair operator makes sure no infeasible solution is evaluated. Even though this exapmle seems to be quite easy, the repair operator makes especially sense for more complex constraints where domain specific knowledge is known." | ||
] | ||
} | ||
], | ||
"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.6.5" | ||
} | ||
}, | ||
"nbformat": 4, | ||
"nbformat_minor": 2 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters