2021-11-26 13:51:01 +00:00
|
|
|
{
|
|
|
|
"cells": [
|
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {},
|
|
|
|
"source": [
|
|
|
|
"# TP 2-3 : Branch-and-bound applied to a knapsack problem"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {},
|
|
|
|
"source": [
|
2021-12-05 15:21:15 +00:00
|
|
|
"## Initialisation (à faire une seule fois)"
|
2021-11-26 13:51:01 +00:00
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2021-12-09 07:25:20 +00:00
|
|
|
"execution_count": 40,
|
2021-11-26 13:51:01 +00:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"name": "stderr",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
|
|
|
"\u001b[32m\u001b[1m Resolving\u001b[22m\u001b[39m package versions...\n",
|
2021-12-09 07:25:20 +00:00
|
|
|
"\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.7/Project.toml`\n",
|
|
|
|
"\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.7/Manifest.toml`\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
"\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m project...\n",
|
|
|
|
"\u001b[32m ✓ \u001b[39mTestOptinum\n",
|
2021-12-09 07:25:20 +00:00
|
|
|
" 1 dependency successfully precompiled in 2 seconds (262 already precompiled, 2 skipped during auto due to previous errors)\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
"\u001b[32m\u001b[1m Resolving\u001b[22m\u001b[39m package versions...\n",
|
2021-12-09 07:25:20 +00:00
|
|
|
"\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.7/Project.toml`\n",
|
|
|
|
"\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.7/Manifest.toml`\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
"\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m project...\n",
|
|
|
|
"\u001b[32m ✓ \u001b[39mTestOptinum\n",
|
2021-12-09 07:25:20 +00:00
|
|
|
" 1 dependency successfully precompiled in 1 seconds (262 already precompiled, 2 skipped during auto due to previous errors)\n"
|
2021-11-26 13:51:01 +00:00
|
|
|
]
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
2021-12-05 15:21:15 +00:00
|
|
|
"import Pkg;\n",
|
2021-12-05 14:25:55 +00:00
|
|
|
"Pkg.add(\"GraphRecipes\");\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
"Pkg.add(\"Plots\");\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
"using GraphRecipes, Plots #only used to visualize the search tree at the end of the branch-and-bound"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {},
|
|
|
|
"source": [
|
2021-12-05 15:21:15 +00:00
|
|
|
"## Récupération des données"
|
2021-11-26 13:51:01 +00:00
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2021-12-09 07:25:20 +00:00
|
|
|
"execution_count": 41,
|
2021-11-26 13:51:01 +00:00
|
|
|
"metadata": {},
|
2021-12-05 15:21:15 +00:00
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"data": {
|
|
|
|
"text/plain": [
|
|
|
|
"readKnapInstance"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"metadata": {},
|
2021-12-09 07:25:20 +00:00
|
|
|
"output_type": "display_data"
|
2021-12-05 15:21:15 +00:00
|
|
|
}
|
|
|
|
],
|
2021-11-26 13:51:01 +00:00
|
|
|
"source": [
|
2021-12-05 14:25:55 +00:00
|
|
|
"\"\"\"Open and read a KnapFile.\n",
|
|
|
|
"\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
"Args: \\\\\n",
|
|
|
|
" - filename (String): the name of the file to read.\n",
|
2021-12-05 14:25:55 +00:00
|
|
|
"\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
"Returns: \\\\\n",
|
|
|
|
" - price (Vector{Integer}): prices of items to put in the KnapSack. \\\\\n",
|
|
|
|
" - weight (Vector{Integer}): weights of items to put in the KnapSack. \\\\\n",
|
|
|
|
" - capacity (Integer): the maximum capacity of the KnapSack.\n",
|
2021-12-05 14:25:55 +00:00
|
|
|
"\"\"\"\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
"function readKnapInstance(filename)\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" price = []\n",
|
|
|
|
" weight = []\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" capacity = -1\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" open(filename) do f\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" for i = 1:3\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" tok = split(readline(f))\n",
|
|
|
|
" if (tok[1] == \"ListPrices=\")\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" for i = 2:(length(tok)-1)\n",
|
|
|
|
" push!(price, parse(Int64, tok[i]))\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" end\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" elseif (tok[1] == \"ListWeights=\")\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" for i = 2:(length(tok)-1)\n",
|
|
|
|
" push!(weight, parse(Int64, tok[i]))\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" end\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" elseif (tok[1] == \"Capacity=\")\n",
|
|
|
|
" capacity = parse(Int64, tok[2])\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" else\n",
|
|
|
|
" println(\"Unknown read :\", tok)\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" end\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" end\n",
|
|
|
|
" end\n",
|
|
|
|
" return price, weight, capacity\n",
|
2021-12-05 14:25:55 +00:00
|
|
|
"end"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2021-12-09 07:25:20 +00:00
|
|
|
"execution_count": 42,
|
2021-12-05 14:25:55 +00:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [],
|
|
|
|
"source": [
|
|
|
|
"# on teste de lire tous les fichiers .opb\n",
|
|
|
|
"for (root, dirs, files) in walkdir(\"data\")\n",
|
|
|
|
" for file in files\n",
|
|
|
|
" if endswith(file, \".opb\")\n",
|
|
|
|
" readKnapInstance(root * \"/\" * file)\n",
|
|
|
|
" end\n",
|
|
|
|
" end\n",
|
|
|
|
"end"
|
2021-11-26 13:51:01 +00:00
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {},
|
|
|
|
"source": [
|
2021-12-05 15:21:15 +00:00
|
|
|
"## Procédure d'application des tests de sondabilités TA, TO et TR pour le cas de la relaxation linéaire"
|
2021-11-26 13:51:01 +00:00
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2021-12-09 07:25:20 +00:00
|
|
|
"execution_count": 43,
|
2021-11-26 13:51:01 +00:00
|
|
|
"metadata": {},
|
2021-12-05 15:21:15 +00:00
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"data": {
|
|
|
|
"text/plain": [
|
|
|
|
"TestsSondabilite_relaxlin"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"metadata": {},
|
2021-12-09 07:25:20 +00:00
|
|
|
"output_type": "display_data"
|
2021-12-05 15:21:15 +00:00
|
|
|
}
|
|
|
|
],
|
2021-11-26 13:51:01 +00:00
|
|
|
"source": [
|
2021-12-05 15:21:15 +00:00
|
|
|
"\"\"\"Test if a node should be pruned.\n",
|
|
|
|
"\n",
|
|
|
|
"Args: \\\\\n",
|
|
|
|
" - x (Vector{Integer}): the node to be tested. \\\\\n",
|
|
|
|
" - price (Vector{Integer}): prices of items to put in the KnapSack. \\\\\n",
|
|
|
|
" - weight (Vector{Integer}): weights of items to put in the KnapSack. \\\\\n",
|
|
|
|
" - capacity (Integer): the maximum capacity of the KnapSack. \\\\\n",
|
|
|
|
" - BestProfit (Integer): the current BestProfit value. \\\\\n",
|
|
|
|
" - Bestsol (Integer): the current BestSol values. \\\\\n",
|
|
|
|
" - affich (Bool): determine if the function should print to stdout.\n",
|
|
|
|
"\n",
|
|
|
|
"Returns: \\\\\n",
|
|
|
|
" - TA (Bool): true if the node is feasible. \\\\\n",
|
|
|
|
" - TO (Bool): true if the node is optimal. \\\\\n",
|
|
|
|
" - TR (Bool): true if the node is resolvable. \\\\\n",
|
|
|
|
" - BestProfit (Integer): the updated value of BestProfit. \\\\\n",
|
|
|
|
" - Bestsol (Vector{Integer}): the updated values of BestSol.\n",
|
|
|
|
"\"\"\"\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
"function TestsSondabilite_relaxlin(x, price, weight, capacity, BestProfit, Bestsol, affich)\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" TA, TO, TR = false, false, false\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
"\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" if (!Constraints(x, weight, capacity)) # Test de faisabilite\n",
|
|
|
|
" TA = true\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
" if affich\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" println(\"TA\\n\")\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
" end\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
"\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" elseif (Objective(x, price) <= BestProfit) # Test d'optimalite\n",
|
|
|
|
" TO = true\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
" if affich\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" println(\"TO\\n\")\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
" end\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
"\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" elseif (AllDef(x)) # Test de resolution\n",
|
|
|
|
" TR = true\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
" if affich\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" println(\"TR : solution \", \" de profit \", Objective(x, price), \"\\n\")\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
" end\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
" if (Objective(x, price) >= BestProfit) # Le profit de la solution trouvée est meilleur que les autres\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
" if affich\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" println(\"\\t-> Cette solution a un meilleur profit.\\n\")\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
" end\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
" # On remplace la solution et le profit par les nouvelles valeurs\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" Bestsol = x\n",
|
|
|
|
" BestProfit = Objective(x, price)\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
" else\n",
|
|
|
|
" if affich\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" println(\"\\t-> Cette solution est moins bonne.\\n\")\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
" end\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" end\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
"\n",
|
|
|
|
" elseif affich\n",
|
|
|
|
" println(\"non sondable\\n\")\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" end\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
"\n",
|
|
|
|
" return TA, TO, TR, Bestsol, BestProfit\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
"end"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {},
|
|
|
|
"source": [
|
2021-12-05 15:21:15 +00:00
|
|
|
"## Procédure de séparation et stratégie d'exploration permettant de se placer au prochain noeud à traiter"
|
2021-11-26 13:51:01 +00:00
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2021-12-09 07:25:20 +00:00
|
|
|
"execution_count": 44,
|
2021-11-26 13:51:01 +00:00
|
|
|
"metadata": {},
|
2021-12-05 15:21:15 +00:00
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"data": {
|
|
|
|
"text/plain": [
|
|
|
|
"SeparerNoeud_relaxlin"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"metadata": {},
|
2021-12-09 07:25:20 +00:00
|
|
|
"output_type": "display_data"
|
2021-12-05 15:21:15 +00:00
|
|
|
}
|
|
|
|
],
|
2021-11-26 13:51:01 +00:00
|
|
|
"source": [
|
2021-12-05 15:21:15 +00:00
|
|
|
"\"\"\"Split a node in two.\n",
|
|
|
|
"\n",
|
|
|
|
"Args: \\\\\n",
|
|
|
|
" - price (Vector{Integer}): prices of items to put in the KnapSack. \\\\\n",
|
|
|
|
" - listvars (Vector{Vector{Integer}}): the current values of listvars. \\\\\n",
|
|
|
|
" - listvals (Vector{Integer}): the current values of listvals.\n",
|
|
|
|
"\n",
|
|
|
|
"Returns: \\\\\n",
|
|
|
|
" - listvars (Vector{Vector{Integer}}): the updated values of listvars. \\\\\n",
|
|
|
|
" - listvals (Vector{Integer}): the updated values of listvals.\n",
|
|
|
|
"\"\"\"\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
"function SeparerNoeud_relaxlin(price, listvars, listvals)\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
" # Le noeud est non-sondable. Appliquer le critère de séparation pour le séparer en sous-noeuds \n",
|
2021-11-26 16:57:38 +00:00
|
|
|
"\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" # Cas du noeud le plus à gauche\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
"\n",
|
|
|
|
" # On sépare le noeud actuel en 2 sous-noeuds\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
" predX = pop!(listvars)\n",
|
|
|
|
" nextX0 = copy(predX)\n",
|
|
|
|
" nextX1 = copy(predX)\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
"\n",
|
|
|
|
" # On initialise leurs valeurs à zéro\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
" val0 = 0\n",
|
|
|
|
" val1 = 0\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
"\n",
|
|
|
|
" # On fixe la nouvelle variable des deux sous-noeuds\n",
|
|
|
|
" n = length(predX)\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" for i = 1:n\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
" if predX[i] == -1\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
" # L'un a zéro\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
" nextX0[i] = 0\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
" # L'autre a un\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
" nextX1[i] = 1\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
"\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
" # On calcule leurs valeurs\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
" val0 = Objective(nextX0, price)\n",
|
|
|
|
" val1 = Objective(nextX1, price)\n",
|
|
|
|
" break\n",
|
|
|
|
" end\n",
|
|
|
|
" end\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
"\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
" # On ajoute les sous-noeuds a la pile des noeuds a explorer\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
" push!(listvars, nextX0)\n",
|
2021-11-27 15:33:20 +00:00
|
|
|
" push!(listvars, nextX1)\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
"\n",
|
|
|
|
" # On ajoute aussi leurs valeurs\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
" push!(listvals, val0)\n",
|
2021-11-27 15:33:20 +00:00
|
|
|
" push!(listvals, val1)\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
"\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" return listvars, listvals\n",
|
|
|
|
"end"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2021-12-09 07:25:20 +00:00
|
|
|
"execution_count": 45,
|
2021-12-05 15:21:15 +00:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"data": {
|
|
|
|
"text/plain": [
|
|
|
|
"ExplorerAutreNoeud_relaxlin"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"metadata": {},
|
2021-12-09 07:25:20 +00:00
|
|
|
"output_type": "display_data"
|
2021-12-05 15:21:15 +00:00
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
|
|
|
"\"\"\"Pop node fom the list to explore another node.\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
"\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
"Args: \\\\\n",
|
|
|
|
" - price (Vector{Integer}): prices of items to put in the KnapSack. \\\\\n",
|
|
|
|
" - listvars (Vector{Vector{Integer}}): the current values of listvars. \\\\\n",
|
|
|
|
" - listvals (Vector{Integer}): the current values of listvals.\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
"\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
"Returns: \\\\\n",
|
|
|
|
" - listvars (Vector{Vector{Integer}}): the updated values of listvars. \\\\\n",
|
|
|
|
" - listvals (Vector{Integer}): the updated values of listvals. \\\\\n",
|
|
|
|
" - stop (Bool): true if the tree search is finished.\n",
|
|
|
|
"\"\"\"\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
"function ExplorerAutreNoeud_relaxlin(listvars, listvals)\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
" # Le noeud est sondable, on l'enlève de la pile des noeuds à sonder\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
"\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
" stop = false\n",
|
|
|
|
" if (length(listvars) > 1)\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
" # On passe au noeud suivant\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
" var = pop!(listvars)\n",
|
|
|
|
" val = pop!(listvals)\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" else\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
" # Il n'y a pas d'autre noeud\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
" stop = true\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" end\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
"\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" return listvars, listvals, stop\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
"end"
|
|
|
|
]
|
|
|
|
},
|
2021-12-05 15:21:15 +00:00
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {},
|
|
|
|
"source": [
|
|
|
|
"## Fonctions décrivant l'objectif et les contraintes"
|
|
|
|
]
|
|
|
|
},
|
2021-11-26 13:51:01 +00:00
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2021-12-09 07:25:20 +00:00
|
|
|
"execution_count": 46,
|
2021-11-26 13:51:01 +00:00
|
|
|
"metadata": {},
|
2021-12-05 15:21:15 +00:00
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"data": {
|
|
|
|
"text/plain": [
|
|
|
|
"AllDef (generic function with 1 method)"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"metadata": {},
|
2021-12-09 07:25:20 +00:00
|
|
|
"output_type": "display_data"
|
2021-12-05 15:21:15 +00:00
|
|
|
}
|
|
|
|
],
|
2021-11-26 13:51:01 +00:00
|
|
|
"source": [
|
2021-11-27 10:44:55 +00:00
|
|
|
"# Fonction objectif que l'on souhaite maximiser/minimiser (évalué dans le meilleur des cas)\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
"Objective(x, price) =\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" sum(\n",
|
|
|
|
" if x[i] < 0\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
" price[i]\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" else\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" price[i] * x[i]\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" end\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" for i = 1:length(x)\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" )\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
"\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
"# Fonction permettant de vérfier toutes les contraintes du modèle (dans le meilleur des cas)\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
"Constraints(x, weight, capacity) =\n",
|
|
|
|
" sum(\n",
|
|
|
|
" if x[i] < 0\n",
|
|
|
|
" 0\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" else\n",
|
|
|
|
" weight[i] * x[i]\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" end\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" for i = 1:length(x)\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" ) <= capacity\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
"\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
"# Fonction qui nous dis si toutes les variables de x sont fixées\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
"function AllDef(x)\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" for i = 1:length(x)\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
" if x[i] < 0\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" return false\n",
|
|
|
|
" end\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" end\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
" return true\n",
|
|
|
|
"end"
|
2021-11-26 13:51:01 +00:00
|
|
|
]
|
2021-11-26 16:57:38 +00:00
|
|
|
},
|
2021-12-05 15:21:15 +00:00
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {},
|
|
|
|
"source": [
|
|
|
|
"## Résolution du problème KnapSack"
|
|
|
|
]
|
|
|
|
},
|
2021-11-26 16:57:38 +00:00
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2021-12-09 07:25:20 +00:00
|
|
|
"execution_count": 47,
|
2021-11-26 16:57:38 +00:00
|
|
|
"metadata": {},
|
2021-12-05 15:21:15 +00:00
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"data": {
|
|
|
|
"text/plain": [
|
|
|
|
"SolveKnapInstance"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
"metadata": {},
|
2021-12-09 07:25:20 +00:00
|
|
|
"output_type": "display_data"
|
2021-12-05 15:21:15 +00:00
|
|
|
}
|
|
|
|
],
|
2021-11-26 16:57:38 +00:00
|
|
|
"source": [
|
2021-12-05 15:21:15 +00:00
|
|
|
"\"\"\"Solve the KnapSack problem for the data contained in `filename`.\n",
|
|
|
|
"\n",
|
|
|
|
"Args: \\\\\n",
|
|
|
|
" - filename (String): the name of the file to read.\n",
|
|
|
|
"\n",
|
|
|
|
"Returns: \\\\\n",
|
|
|
|
" - trParentnodes (Vector{Integer}): the parents nodes, to plot the tree.\n",
|
|
|
|
" - trChildnodes (Vector{Integer}): the child nodes, to plot the tree.\n",
|
|
|
|
" - trNamenodes (Vector{Integer}): the name of the nodes, to plot the tree.\n",
|
|
|
|
"\"\"\"\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
"function SolveKnapInstance(filename)\n",
|
|
|
|
"\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" stop = false\n",
|
|
|
|
" affich = false\n",
|
|
|
|
"\n",
|
2021-11-27 15:33:20 +00:00
|
|
|
" # Extraction des données\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
" price, weight, capacity = readKnapInstance(filename)\n",
|
|
|
|
"\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" if affich\n",
|
|
|
|
" println(\"Capacity : \", capacity, \" | Number of objects : \", length(price), \"\\n\")\n",
|
|
|
|
" end\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
"\n",
|
2021-11-27 15:33:20 +00:00
|
|
|
" # Pour dessiner le graph\n",
|
|
|
|
" trParentnodes = Int64[]\n",
|
|
|
|
" trChildnodes = Int64[]\n",
|
|
|
|
" trNamenodes = []\n",
|
|
|
|
"\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
" # Liste des variable pour naviguer de noeuds en noeuds\n",
|
2021-11-27 15:33:20 +00:00
|
|
|
" listvars = []\n",
|
|
|
|
" listvals = []\n",
|
|
|
|
" listnodes = []\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
"\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
" # La meilleur solution et sa valeur\n",
|
2021-11-27 15:33:20 +00:00
|
|
|
" BestProfit = -1\n",
|
|
|
|
" Bestsol = []\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
"\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
" # Compter le nombre de noeud explorés\n",
|
|
|
|
" current_node_number = 0\n",
|
|
|
|
"\n",
|
|
|
|
" # On ajoute le premier noeud à explorer (la racine)\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
" push!(listvars, [-1 for p in price])\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
" push!(listvals, Objective(last(listvars), price))\n",
|
2021-11-27 15:33:20 +00:00
|
|
|
" push!(listnodes, 1)\n",
|
|
|
|
" push!(trNamenodes, 0)\n",
|
|
|
|
" newnodeid = 2\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
"\n",
|
|
|
|
" while (!stop)\n",
|
2021-11-27 15:33:20 +00:00
|
|
|
"\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
" # Le noeud actuel\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
" x = last(listvars)\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
"\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" if affich && current_node_number % 10000 == 0\n",
|
|
|
|
" println(\"----------\\nNode n°\", current_node_number, \" :\\n\")\n",
|
|
|
|
" println(\"Previous Solution memorized \", \" with bestprofit \", BestProfit, \"\\n\")\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
" end\n",
|
|
|
|
"\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
" # Test de sondabilité du noeud actuel\n",
|
|
|
|
" # -> On mets a jour la solution et sa valeur si besoin\n",
|
2021-11-27 10:20:11 +00:00
|
|
|
" TA, TO, TR, Bestsol, BestProfit = TestsSondabilite_relaxlin(x, price, weight, capacity, BestProfit, Bestsol, affich)\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
"\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
" is_node_sondable = TA || TO || TR\n",
|
|
|
|
" if (!is_node_sondable)\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
" # Le noeud n'est pas sondable, on le sépare en 2 sous-noeuds\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
" listvars, listvals = SeparerNoeud_relaxlin(price, listvars, listvals)\n",
|
2021-11-27 15:33:20 +00:00
|
|
|
"\n",
|
|
|
|
" curnode = pop!(listnodes)\n",
|
|
|
|
"\n",
|
|
|
|
" push!(trParentnodes, curnode)\n",
|
|
|
|
" push!(trParentnodes, curnode)\n",
|
|
|
|
"\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" push!(listnodes, newnodeid + 1)\n",
|
2021-11-27 15:33:20 +00:00
|
|
|
" push!(listnodes, newnodeid)\n",
|
|
|
|
"\n",
|
|
|
|
" push!(trChildnodes, newnodeid)\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" push!(trChildnodes, newnodeid + 1)\n",
|
2021-11-27 15:33:20 +00:00
|
|
|
"\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" push!(trNamenodes, newnodeid - 1)\n",
|
2021-11-27 15:33:20 +00:00
|
|
|
" push!(trNamenodes, newnodeid)\n",
|
|
|
|
"\n",
|
|
|
|
" newnodeid += 2\n",
|
|
|
|
"\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
" else\n",
|
2021-11-27 10:44:55 +00:00
|
|
|
" # Le noeud est sondable, on passe au noeud suivant\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
" listvars, listvals, stop = ExplorerAutreNoeud_relaxlin(listvars, listvals)\n",
|
2021-11-27 15:33:20 +00:00
|
|
|
"\n",
|
|
|
|
" pop!(listnodes)\n",
|
2021-11-26 16:57:38 +00:00
|
|
|
" end\n",
|
|
|
|
"\n",
|
|
|
|
" current_node_number += 1\n",
|
|
|
|
" end\n",
|
|
|
|
"\n",
|
2021-12-05 15:21:15 +00:00
|
|
|
" if affich\n",
|
|
|
|
" println(\"\\n******\\n\\nOptimal value = \", BestProfit, \"\\n\\nOptimal x = \", Bestsol)\n",
|
|
|
|
" end\n",
|
|
|
|
" \n",
|
|
|
|
" return trParentnodes, trChildnodes, trNamenodes\n",
|
2021-11-27 15:33:20 +00:00
|
|
|
"end"
|
|
|
|
]
|
|
|
|
},
|
2021-12-05 15:21:15 +00:00
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2021-12-09 07:25:20 +00:00
|
|
|
"execution_count": 48,
|
2021-12-05 15:21:15 +00:00
|
|
|
"metadata": {},
|
2021-12-09 07:25:20 +00:00
|
|
|
"outputs": [],
|
2021-12-05 15:21:15 +00:00
|
|
|
"source": [
|
2021-12-09 07:25:20 +00:00
|
|
|
"trParentnodes, trChildnodes, trNamenodes = SolveKnapInstance(\"data/circle/knapPI_16_10000_1000_5_-912198.opb\")\n",
|
|
|
|
"# graphplot(trParentnodes, trChildnodes, names = trNamenodes, method = :tree)"
|
2021-12-05 15:21:15 +00:00
|
|
|
]
|
|
|
|
},
|
2021-11-27 15:33:20 +00:00
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2021-12-05 14:25:55 +00:00
|
|
|
"execution_count": null,
|
2021-11-27 15:33:20 +00:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [],
|
|
|
|
"source": [
|
2021-12-05 15:21:15 +00:00
|
|
|
"# # on teste de résoudre tous les fichiers .opb\n",
|
|
|
|
"# for (root, dirs, files) in walkdir(\"data\")\n",
|
|
|
|
"# for file in files\n",
|
|
|
|
"# if endswith(file, \".opb\")\n",
|
|
|
|
"# SolveKnapInstance(root * \"/\" * file)\n",
|
|
|
|
"# end\n",
|
|
|
|
"# end\n",
|
|
|
|
"# end"
|
2021-11-26 16:57:38 +00:00
|
|
|
]
|
2021-11-26 13:51:01 +00:00
|
|
|
}
|
|
|
|
],
|
|
|
|
"metadata": {
|
|
|
|
"kernelspec": {
|
2021-12-09 07:25:20 +00:00
|
|
|
"display_name": "Julia 1.7.0",
|
2021-11-26 13:51:01 +00:00
|
|
|
"language": "julia",
|
2021-12-09 07:25:20 +00:00
|
|
|
"name": "julia-1.7"
|
2021-11-26 13:51:01 +00:00
|
|
|
},
|
|
|
|
"language_info": {
|
|
|
|
"file_extension": ".jl",
|
|
|
|
"mimetype": "application/julia",
|
|
|
|
"name": "julia",
|
2021-12-09 07:25:20 +00:00
|
|
|
"version": "1.7.0"
|
2021-11-26 13:51:01 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
"nbformat": 4,
|
|
|
|
"nbformat_minor": 4
|
|
|
|
}
|