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": [
|
|
|
|
"### Initialisation (à faire une seule fois)"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2021-11-26 15:58:55 +00:00
|
|
|
"execution_count": 2,
|
2021-11-26 13:51:01 +00:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"name": "stderr",
|
|
|
|
"output_type": "stream",
|
|
|
|
"text": [
|
2021-11-26 15:58:55 +00:00
|
|
|
"\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m registry at `~/.julia/registries/General`\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
"\u001b[32m\u001b[1m Resolving\u001b[22m\u001b[39m package versions...\n",
|
|
|
|
"\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.6/Project.toml`\n",
|
|
|
|
"\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.6/Manifest.toml`\n",
|
|
|
|
"\u001b[32m\u001b[1m Resolving\u001b[22m\u001b[39m package versions...\n",
|
|
|
|
"\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.6/Project.toml`\n",
|
|
|
|
"\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.6/Manifest.toml`\n"
|
|
|
|
]
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
|
|
|
"import Pkg; \n",
|
|
|
|
"Pkg.add(\"GraphRecipes\"); Pkg.add(\"Plots\"); \n",
|
|
|
|
"using GraphRecipes, Plots #only used to visualize the search tree at the end of the branch-and-bound"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {},
|
|
|
|
"source": [
|
|
|
|
"### Récupération des données"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2021-11-26 15:58:55 +00:00
|
|
|
"execution_count": 9,
|
2021-11-26 13:51:01 +00:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"data": {
|
|
|
|
"text/plain": [
|
2021-11-26 15:58:55 +00:00
|
|
|
"(Any[42, 40, 12, 25], Any[7, 4, 3, 5], 10)"
|
2021-11-26 13:51:01 +00:00
|
|
|
]
|
|
|
|
},
|
2021-11-26 15:58:55 +00:00
|
|
|
"execution_count": 9,
|
2021-11-26 13:51:01 +00:00
|
|
|
"metadata": {},
|
|
|
|
"output_type": "execute_result"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
2021-11-26 15:58:55 +00:00
|
|
|
"function readKnapInstance(filename)\n",
|
2021-11-26 13:51:01 +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",
|
|
|
|
" for i in 1:3\n",
|
|
|
|
" tok = split(readline(f))\n",
|
|
|
|
" if (tok[1] == \"ListPrices=\")\n",
|
|
|
|
" for i in 2:(length(tok)-1)\n",
|
|
|
|
" push!(price,parse(Int64, tok[i]))\n",
|
|
|
|
" end\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" elseif (tok[1] == \"ListWeights=\")\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" for i in 2:(length(tok)-1)\n",
|
|
|
|
" push!(weight,parse(Int64, tok[i]))\n",
|
|
|
|
" 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",
|
|
|
|
" end \n",
|
|
|
|
" end\n",
|
|
|
|
" end\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" \n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" return price, weight, capacity\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
"end\n",
|
|
|
|
"\n",
|
|
|
|
"# readKnapInstance(\"data/test.opb\")\n",
|
|
|
|
"# readKnapInstance(\"data/almost_strongly_correlated/knapPI_5_50_1000_1_-2096.opb\")"
|
2021-11-26 13:51:01 +00:00
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {},
|
|
|
|
"source": [
|
|
|
|
"### Procédure d'application des tests de sondabilités TA, TO et TR pour le cas de la relaxation linéaire"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2021-11-26 15:58:55 +00:00
|
|
|
"execution_count": 4,
|
2021-11-26 13:51:01 +00:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"data": {
|
|
|
|
"text/plain": [
|
|
|
|
"TestsSondabilite_relaxlin (generic function with 1 method)"
|
|
|
|
]
|
|
|
|
},
|
2021-11-26 15:58:55 +00:00
|
|
|
"execution_count": 4,
|
2021-11-26 13:51:01 +00:00
|
|
|
"metadata": {},
|
|
|
|
"output_type": "execute_result"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
2021-11-26 15:58:55 +00:00
|
|
|
"function TestsSondabilite_relaxlin(x, price, weight, capacity, varsbin, BestProfit, Bestsol)\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" TA, TO, TR = false, false, false\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" if (!Constraints(x, weight, capacity)) # Test de faisabilite\n",
|
|
|
|
" TA = true\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" println(\"TA\")\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" elseif (Objective(x, price) <= BestProfit) # Test d'optimalite\n",
|
|
|
|
" TO = true\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" println(\"TO\")\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" elseif (AllDef(x)) # Test de resolution\n",
|
|
|
|
" TR = true\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" println(\"TR\")\n",
|
|
|
|
" #if (value(benef) >= BestProfit)\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" if (Objective(x, price) >= BestProfit)\n",
|
|
|
|
" Bestsol = x\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" #BestProfit=value(benef)\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" BestProfit = Objective(x, price)\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" end\n",
|
|
|
|
" else\n",
|
|
|
|
" println(\"non sondable\")\n",
|
|
|
|
" end\n",
|
|
|
|
" TA, TO, TR, Bestsol, BestProfit\n",
|
|
|
|
"end"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "markdown",
|
|
|
|
"metadata": {},
|
|
|
|
"source": [
|
|
|
|
"### Procédure de séparation et stratégie d'exploration permettant de se placer au prochain noeud à traiter"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2021-11-26 15:58:55 +00:00
|
|
|
"execution_count": 5,
|
2021-11-26 13:51:01 +00:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"data": {
|
|
|
|
"text/plain": [
|
|
|
|
"ExplorerAutreNoeud_relaxlin (generic function with 1 method)"
|
|
|
|
]
|
|
|
|
},
|
2021-11-26 15:58:55 +00:00
|
|
|
"execution_count": 5,
|
2021-11-26 13:51:01 +00:00
|
|
|
"metadata": {},
|
|
|
|
"output_type": "execute_result"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
|
|
|
"\n",
|
|
|
|
"function SeparerNoeud_relaxlin(varsshouldbebinary, listvars, listvals)\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" # le noeud est non-sondable. Appliquer le critère de séparation pour le séparer en sous-noeuds et choisir un noeud-fils le plus à gauche \n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" \n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" # Cas du noeud le plus à gauche\n",
|
|
|
|
" predX = first(listvars)\n",
|
|
|
|
" nextX0 = predX\n",
|
|
|
|
" for xi in predX\n",
|
|
|
|
" \n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" end\n",
|
|
|
|
"\n",
|
|
|
|
"\n",
|
|
|
|
" push!(listvars,var) #stocker l'identite de la variable choisie pour la séparation\n",
|
|
|
|
" push!(listvals,1.0) #stocker la branche choisie, identifiee par la valeur de la variable choisie\n",
|
|
|
|
" listvars, listvals\n",
|
|
|
|
"end\n",
|
|
|
|
"\n",
|
|
|
|
"\n",
|
|
|
|
"function ExplorerAutreNoeud_relaxlin(listvars, listvals, listnodes)\n",
|
|
|
|
" #this node is sondable, go back to parent node then right child if possible\n",
|
|
|
|
" \n",
|
|
|
|
" stop=false\n",
|
|
|
|
" #check if we are not at the root node\n",
|
|
|
|
" if (length(listvars)>= 1)\n",
|
|
|
|
" #go back to parent node\n",
|
|
|
|
" var=pop!(listvars)\n",
|
|
|
|
" theval=pop!(listvals)\n",
|
|
|
|
" tmp=pop!(listnodes)\n",
|
|
|
|
" set_lower_bound(var,0.0)\n",
|
|
|
|
" set_upper_bound(var,1.0)\n",
|
|
|
|
"\n",
|
|
|
|
" #go to right child if possible, otherwise go back to parent\n",
|
|
|
|
" while ( (theval==0.0) && (length(listvars)>= 1))\n",
|
|
|
|
" var=pop!(listvars)\n",
|
|
|
|
" theval=pop!(listvals)\n",
|
|
|
|
" tmp=pop!(listnodes)\n",
|
|
|
|
" set_lower_bound(var,0.0) \n",
|
|
|
|
" set_upper_bound(var,1.0)\n",
|
|
|
|
" end\n",
|
|
|
|
" if theval==1.0\n",
|
|
|
|
" set_lower_bound(var,0.0)\n",
|
|
|
|
" set_upper_bound(var,0.0)\n",
|
|
|
|
" push!(listvars,var)\n",
|
|
|
|
" push!(listvals,0.0)\n",
|
|
|
|
" else\n",
|
|
|
|
" println(\"\\nFINISHED\")\n",
|
|
|
|
" stop=true\n",
|
|
|
|
" end\n",
|
|
|
|
" else\n",
|
|
|
|
" #the root node was sondable\n",
|
|
|
|
" println(\"\\nFINISHED\")\n",
|
|
|
|
" stop=true\n",
|
|
|
|
" end\n",
|
|
|
|
" listvars, listvals, listnodes, stop \n",
|
|
|
|
"end"
|
|
|
|
]
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"cell_type": "code",
|
2021-11-26 15:58:55 +00:00
|
|
|
"execution_count": 10,
|
2021-11-26 13:51:01 +00:00
|
|
|
"metadata": {},
|
|
|
|
"outputs": [
|
|
|
|
{
|
|
|
|
"data": {
|
|
|
|
"text/plain": [
|
2021-11-26 15:58:55 +00:00
|
|
|
"Constraints (generic function with 1 method)"
|
2021-11-26 13:51:01 +00:00
|
|
|
]
|
|
|
|
},
|
2021-11-26 15:58:55 +00:00
|
|
|
"execution_count": 10,
|
2021-11-26 13:51:01 +00:00
|
|
|
"metadata": {},
|
|
|
|
"output_type": "execute_result"
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"source": [
|
2021-11-26 15:58:55 +00:00
|
|
|
"# fonction objectif que l'on souhaite maximiser/minimiser\n",
|
|
|
|
"Objective(x, price) = \n",
|
|
|
|
" sum(\n",
|
|
|
|
" if x[i] < 0\n",
|
|
|
|
" 1\n",
|
|
|
|
" else\n",
|
|
|
|
" price[i]*x[i] \n",
|
|
|
|
" end\n",
|
|
|
|
" for i in 1:length(x)\n",
|
|
|
|
" )\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
"\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
"# fonction permettant de vérfier toutes les contraintes du modèle\n",
|
|
|
|
"Constraints(x, weight, capacity) =\n",
|
|
|
|
" sum(\n",
|
|
|
|
" if x[i] < 0\n",
|
|
|
|
" 0\n",
|
|
|
|
" else \n",
|
|
|
|
" weight[i]*x[i]\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" end\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" for i in 1:length(x)\n",
|
|
|
|
" ) <= capacity\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
"\n",
|
|
|
|
"\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
"AllDef(x) =\n",
|
|
|
|
" for xi in x\n",
|
|
|
|
" if xi < 0\n",
|
|
|
|
" return false\n",
|
|
|
|
" end\n",
|
2021-11-26 13:51:01 +00:00
|
|
|
" end\n",
|
2021-11-26 15:58:55 +00:00
|
|
|
" return true"
|
2021-11-26 13:51:01 +00:00
|
|
|
]
|
|
|
|
}
|
|
|
|
],
|
|
|
|
"metadata": {
|
|
|
|
"kernelspec": {
|
|
|
|
"display_name": "Julia 1.6.3",
|
|
|
|
"language": "julia",
|
|
|
|
"name": "julia-1.6"
|
|
|
|
},
|
|
|
|
"language_info": {
|
|
|
|
"file_extension": ".jl",
|
|
|
|
"mimetype": "application/julia",
|
|
|
|
"name": "julia",
|
|
|
|
"version": "1.6.3"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"nbformat": 4,
|
|
|
|
"nbformat_minor": 4
|
|
|
|
}
|