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-10 10:24:14 +00:00
"execution_count": null,
2021-11-26 13:51:01 +00:00
"metadata": {},
2021-12-10 10:24:14 +00:00
"outputs": [],
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-10 10:24:14 +00:00
"execution_count": 2,
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-10 10:24:14 +00:00
"execution_count": 3,
2021-12-05 14:25:55 +00:00
"metadata": {},
"outputs": [],
"source": [
2021-12-09 15:43:14 +00:00
"# # on convert tous les .opb en .lp pour les utiliser dans glpk\n",
"# for (root, dirs, files) in walkdir(\"data\")\n",
"# for file in files\n",
"# if endswith(file, \".opb\")\n",
"# price, weight, capacity = readKnapInstance(root * \"/\" * file)\n",
"# filename = splitext(file)[1]\n",
"# f = open(root * \"/\" * filename * \".lp\", \"w\");\n",
"# write(f, \"Maximize\\n\")\n",
"# write(f, \" Knap: \")\n",
"# for (i, p) in enumerate(price)\n",
"# write(f, \"+ \" * string(p) * \" obj\" * string(i) * \" \")\n",
"# end\n",
"# write(f, \"\\n\")\n",
2021-12-09 14:53:39 +00:00
"\n",
2021-12-09 15:43:14 +00:00
"# write(f, \"\\nSubject To\\n\")\n",
"# write(f, \" MaxKnap: \")\n",
"# for (i, w) in enumerate(weight)\n",
"# write(f, \"+ \" * string(w) * \" obj\" * string(i) * \" \")\n",
"# end\n",
"# write(f, \"<= \" * string(capacity) * \"\\n\")\n",
2021-12-09 14:53:39 +00:00
"\n",
2021-12-09 15:43:14 +00:00
"# write(f, \"\\nBinary\\n\")\n",
"# for (i, p) in enumerate(price)\n",
"# write(f, \" obj\" * string(i) * \"\\n\")\n",
"# end\n",
2021-12-09 14:53:39 +00:00
"\n",
2021-12-09 15:43:14 +00:00
"# write(f, \"\\nEnd\\n\")\n",
"# close(f)\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-10 10:24:14 +00:00
"execution_count": 4,
2021-11-26 13:51:01 +00:00
"metadata": {},
2021-12-05 15:21:15 +00:00
"outputs": [
{
"data": {
"text/plain": [
2021-12-09 15:43:14 +00:00
"TestsSondabilite"
2021-12-05 15:21:15 +00:00
]
},
"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-12-09 15:43:14 +00:00
"function TestsSondabilite(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-10 10:24:14 +00:00
"execution_count": 5,
2021-11-26 13:51:01 +00:00
"metadata": {},
2021-12-05 15:21:15 +00:00
"outputs": [
{
"data": {
"text/plain": [
2021-12-09 10:54:09 +00:00
"SeparerNoeud"
2021-12-05 15:21:15 +00:00
]
},
"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-12-09 10:54:09 +00:00
"function SeparerNoeud(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-09 10:54:09 +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-10 10:24:14 +00:00
"execution_count": 6,
2021-12-05 15:21:15 +00:00
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2021-12-09 15:43:14 +00:00
"ExplorerAutreNoeud"
2021-12-05 15:21:15 +00:00
]
},
"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-12-09 15:43:14 +00:00
"function ExplorerAutreNoeud(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-10 10:24:14 +00:00
"execution_count": 7,
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-10 10:24:14 +00:00
"execution_count": 8,
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",
2021-12-09 15:43:14 +00:00
" affich = true\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",
2021-12-09 15:43:14 +00:00
"\n",
" tri = true\n",
2021-12-09 10:54:09 +00:00
" if tri\n",
" couples = zip(price, weight)\n",
" couples = sort(collect(couples), by = x -> x[1] / x[2])\n",
" unzip(a) = map(x->getfield.(a, x), fieldnames(eltype(a)))\n",
" price, weight = unzip(couples)\n",
" end\n",
2021-11-26 16:57:38 +00:00
"\n",
2021-12-09 15:43:14 +00:00
" expected = split(split(filename, \"-\")[2], \".\")[1]\n",
" nodes_nb = length(price)\n",
" nodes_max = 2^nodes_nb\n",
"\n",
2021-12-05 15:21:15 +00:00
" if affich\n",
2021-12-09 15:43:14 +00:00
" println(\"---\", filename, \"---\")\n",
" println(\"Capacity = \", capacity)\n",
" println(\"Number of objects = \", nodes_nb)\n",
" println(\"Expected optimal value = \", expected)\n",
" println(\"Maximum number of nodes = \", nodes_max)\n",
" println() 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",
2021-12-09 15:43:14 +00:00
" println(\"Node n°\", current_node_number, \": \\tBestProfit = \", BestProfit)\n",
" LastBestProfit = BestProfit\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-12-09 15:43:14 +00:00
" TA, TO, TR, Bestsol, BestProfit = TestsSondabilite(x, price, weight, capacity, BestProfit, Bestsol, false)\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-12-09 15:43:14 +00:00
" listvars, listvals = SeparerNoeud(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-12-09 15:43:14 +00:00
" listvars, listvals, stop = ExplorerAutreNoeud(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-09 15:43:14 +00:00
" println(\"\\n--------------------------------------------------\")\n",
" println(\"Expected optimal value = \", expected)\n",
" println(\"Optimal value = \", BestProfit)\n",
" println(\"Optimal x = \", Bestsol)\n",
" println(\"Maximum number of nodes = \", nodes_max)\n",
" println(\"Nodes explored = \", current_node_number) \n",
2021-12-05 15:21:15 +00:00
" \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-10 10:24:14 +00:00
"execution_count": 9,
2021-12-05 15:21:15 +00:00
"metadata": {},
2021-12-09 10:54:09 +00:00
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2021-12-10 10:24:14 +00:00
"---data/test-65.opb---\n",
"Capacity = 10\n",
"Number of objects = 4\n",
"Expected optimal value = 65\n",
"Maximum number of nodes = 16\n",
2021-12-09 10:54:09 +00:00
"\n",
2021-12-09 15:43:14 +00:00
"Node n°0: \tBestProfit = -1\n",
2021-12-09 10:54:09 +00:00
"\n",
2021-12-09 15:43:14 +00:00
"--------------------------------------------------\n",
2021-12-10 10:24:14 +00:00
"Expected optimal value = 65\n",
"Optimal value = 65\n",
"Optimal x = [0, 1, 0, 1]\n",
"Maximum number of nodes = 16\n",
"Nodes explored = 23\n"
2021-12-09 10:54:09 +00:00
]
},
{
"data": {
"text/plain": [
2021-12-10 10:24:14 +00:00
"([1, 1, 2, 2, 4, 4, 7, 7, 5, 5 … 3, 3, 14, 14, 17, 17, 15, 15, 20, 20], [2, 3, 4, 5, 6, 7, 8, 9, 10, 11 … 14, 15, 16, 17, 18, 19, 20, 21, 22, 23], Any[0, 1, 2, 3, 4, 5, 6, 7, 8, 9 … 13, 14, 15, 16, 17, 18, 19, 20, 21, 22])"
2021-12-09 10:54:09 +00:00
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
2021-12-10 10:24:14 +00:00
"trParentnodes, trChildnodes, trNamenodes = SolveKnapInstance(\"data/test-65.opb\")"
2021-12-09 10:54:09 +00:00
]
},
{
"cell_type": "code",
2021-12-10 10:24:14 +00:00
"execution_count": 10,
2021-12-09 10:54:09 +00:00
"metadata": {},
"outputs": [
{
"data": {
2021-12-10 10:24:14 +00:00
"image/png": "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
"image/svg+xml": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"600\" height=\"400\" viewBox=\"0 0 2400 1600\">\n<defs>\n <clipPath id=\"clip160\">\n <rect x=\"0\" y=\"0\" width=\"2400\" height=\"1600\"/>\n </clipPath>\n</defs>\n<path clip-path=\"url(#clip160)\" d=\"\nM0 1600 L2400 1600 L2400 0 L0 0 Z\n \" fill=\"#ffffff\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n<defs>\n <clipPath id=\"clip161\">\n <rect x=\"480\" y=\"0\" width=\"1681\" height=\"1600\"/>\n </clipPath>\n</defs>\n<path clip-path=\"url(#clip160)\" d=\"\nM447.244 1552.76 L1952.76 1552.76 L1952.76 47.2441 L447.244 47.2441 Z\n \" fill=\"#ffffff\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n<defs>\n <clipPath id=\"clip162\">\n <rect x=\"447\" y=\"47\" width=\"1507\" height=\"1507\"/>\n </clipPath>\n</defs>\n<polyline clip-path=\"url(#clip162)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 1213.87,262.317 1213.32,272.903 1211.74,283.465 1209.21,294.006 1205.79,304.527 1201.56,315.029 1196.61,325.516 1191.01,335.988 1184.83,346.447 1178.15,356.895 \n 1171.05,367.334 1163.61,377.765 1155.9,388.19 1147.99,398.61 1139.97,409.028 1131.91,419.445 1123.89,429.863 1115.99,440.284 1108.28,450.709 1100.83,461.139 \n 1093.73,471.578 1087.06,482.026 1080.88,492.485 1075.27,502.957 1070.32,513.444 1066.1,523.947 1062.68,534.468 1060.14,545.009 1058.56,555.571 1058.02,566.156 \n \n \"/>\n<polyline clip-path=\"url(#clip162)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 1213.87,262.317 1214.37,274.405 1215.85,286.561 1218.23,298.781 1221.43,311.059 1225.39,323.391 1230.03,335.771 1235.28,348.194 1241.07,360.655 1247.33,373.15 \n 1253.98,385.672 1260.96,398.217 1268.18,410.78 1275.59,423.355 1283.11,435.939 1290.66,448.524 1298.17,461.108 1305.58,473.683 1312.8,486.246 1319.78,498.791 \n 1326.43,511.314 1332.69,523.808 1338.48,536.269 1343.73,548.692 1348.37,561.072 1352.33,573.404 1355.53,585.682 1357.91,597.902 1359.39,610.058 1359.9,622.146 \n \n \"/>\n<polyline clip-path=\"url(#clip162)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 1058.02,566.156 1057.47,574.075 1055.87,581.808 1053.29,589.367 1049.83,596.766 1045.54,604.02 1040.52,611.143 1034.84,618.147 1028.57,625.048 1021.8,631.858 \n 1014.6,638.593 1007.05,645.265 999.223,651.888 991.205,658.477 983.072,665.045 974.899,671.606 966.765,678.174 958.748,684.763 950.925,691.386 943.375,698.058 \n 936.174,704.793 929.401,711.603 923.134,718.504 917.45,725.509 912.427,732.631 908.143,739.885 904.676,747.285 902.103,754.844 900.502,762.576 899.951,770.495 \n \n \"/>\n<polyline clip-path=\"url(#clip162)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 1058.02,566.156 1057.98,572.429 1057.87,578.833 1057.7,585.358 1057.46,591.995 1057.17,598.733 1056.83,605.564 1056.44,612.477 1056.01,619.462 1055.55,626.511 \n 1055.06,633.613 1054.55,640.758 1054.02,647.938 1053.47,655.141 1052.92,662.36 1052.36,669.583 1051.81,676.801 1051.26,684.005 1050.73,691.184 1050.22,698.33 \n 1049.72,705.432 1049.26,712.48 1048.84,719.466 1048.45,726.379 1048.11,733.209 1047.82,739.948 1047.58,746.584 1047.41,753.109 1047.3,759.513 1047.26,765.786 \n \n \"/>\n<polyline clip-path=\"url(#clip162)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 899.951,770.495 899.942,780.589 899.917,790.896 899.876,801.401 899.821,812.087 899.753,822.94 899.673,833.944 899.583,845.081 899.483,856.338 899.376,867.697 \n 899.261,879.143 899.142,890.66 899.017,902.233 898.89,913.845 898.761,925.481 898.631,937.125 898.502,948.761 898.375,960.373 898.251,971.946 898.131,983.463 \n 898.016,994.91 897.909,1006.27 897.809,1017.53 897.719
2021-12-09 10:54:09 +00:00
"text/html": [
"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n",
"<svg xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\" width=\"600\" height=\"400\" viewBox=\"0 0 2400 1600\">\n",
"<defs>\n",
2021-12-10 10:24:14 +00:00
" <clipPath id=\"clip190\">\n",
2021-12-09 10:54:09 +00:00
" <rect x=\"0\" y=\"0\" width=\"2400\" height=\"1600\"/>\n",
" </clipPath>\n",
"</defs>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip190)\" d=\"\n",
2021-12-09 10:54:09 +00:00
"M0 1600 L2400 1600 L2400 0 L0 0 Z\n",
" \" fill=\"#ffffff\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
"<defs>\n",
2021-12-10 10:24:14 +00:00
" <clipPath id=\"clip191\">\n",
2021-12-09 10:54:09 +00:00
" <rect x=\"480\" y=\"0\" width=\"1681\" height=\"1600\"/>\n",
" </clipPath>\n",
"</defs>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip190)\" d=\"\n",
2021-12-09 10:54:09 +00:00
"M447.244 1552.76 L1952.76 1552.76 L1952.76 47.2441 L447.244 47.2441 Z\n",
" \" fill=\"#ffffff\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
"<defs>\n",
2021-12-10 10:24:14 +00:00
" <clipPath id=\"clip192\">\n",
2021-12-09 10:54:09 +00:00
" <rect x=\"447\" y=\"47\" width=\"1507\" height=\"1507\"/>\n",
" </clipPath>\n",
"</defs>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1213.87,262.317 1213.32,272.903 1211.74,283.465 1209.21,294.006 1205.79,304.527 1201.56,315.029 1196.61,325.516 1191.01,335.988 1184.83,346.447 1178.15,356.895 \n",
" 1171.05,367.334 1163.61,377.765 1155.9,388.19 1147.99,398.61 1139.97,409.028 1131.91,419.445 1123.89,429.863 1115.99,440.284 1108.28,450.709 1100.83,461.139 \n",
" 1093.73,471.578 1087.06,482.026 1080.88,492.485 1075.27,502.957 1070.32,513.444 1066.1,523.947 1062.68,534.468 1060.14,545.009 1058.56,555.571 1058.02,566.156 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1213.87,262.317 1214.37,274.405 1215.85,286.561 1218.23,298.781 1221.43,311.059 1225.39,323.391 1230.03,335.771 1235.28,348.194 1241.07,360.655 1247.33,373.15 \n",
" 1253.98,385.672 1260.96,398.217 1268.18,410.78 1275.59,423.355 1283.11,435.939 1290.66,448.524 1298.17,461.108 1305.58,473.683 1312.8,486.246 1319.78,498.791 \n",
" 1326.43,511.314 1332.69,523.808 1338.48,536.269 1343.73,548.692 1348.37,561.072 1352.33,573.404 1355.53,585.682 1357.91,597.902 1359.39,610.058 1359.9,622.146 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1058.02,566.156 1057.47,574.075 1055.87,581.808 1053.29,589.367 1049.83,596.766 1045.54,604.02 1040.52,611.143 1034.84,618.147 1028.57,625.048 1021.8,631.858 \n",
" 1014.6,638.593 1007.05,645.265 999.223,651.888 991.205,658.477 983.072,665.045 974.899,671.606 966.765,678.174 958.748,684.763 950.925,691.386 943.375,698.058 \n",
" 936.174,704.793 929.401,711.603 923.134,718.504 917.45,725.509 912.427,732.631 908.143,739.885 904.676,747.285 902.103,754.844 900.502,762.576 899.951,770.495 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1058.02,566.156 1057.98,572.429 1057.87,578.833 1057.7,585.358 1057.46,591.995 1057.17,598.733 1056.83,605.564 1056.44,612.477 1056.01,619.462 1055.55,626.511 \n",
" 1055.06,633.613 1054.55,640.758 1054.02,647.938 1053.47,655.141 1052.92,662.36 1052.36,669.583 1051.81,676.801 1051.26,684.005 1050.73,691.184 1050.22,698.33 \n",
" 1049.72,705.432 1049.26,712.48 1048.84,719.466 1048.45,726.379 1048.11,733.209 1047.82,739.948 1047.58,746.584 1047.41,753.109 1047.3,759.513 1047.26,765.786 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 899.951,770.495 899.942,780.589 899.917,790.896 899.876,801.401 899.821,812.087 899.753,822.94 899.673,833.944 899.583,845.081 899.483,856.338 899.376,867.697 \n",
" 899.261,879.143 899.142,890.66 899.017,902.233 898.89,913.845 898.761,925.481 898.631,937.125 898.502,948.761 898.375,960.373 898.251,971.946 898.131,983.463 \n",
" 898.016,994.91 897.909,1006.27 897.809,1017.53 897.719,1028.66 897.639,1039.67 897.571,1050.52 897.516,1061.21 897.475,1071.71 897.45,1082.02 897.441,1092.11 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 899.951,770.495 899.546,780.607 898.37,790.792 896.479,801.044 893.932,811.359 890.784,821.73 887.094,832.153 882.917,842.621 878.312,853.13 873.336,863.674 \n",
" 868.046,874.247 862.498,884.845 856.75,895.462 850.86,906.092 844.883,916.73 838.878,927.371 832.902,938.01 827.011,948.64 821.264,959.257 815.716,969.855 \n",
" 810.425,980.428 805.449,990.972 800.844,1001.48 796.668,1011.95 792.977,1022.37 789.83,1032.74 787.282,1043.06 785.392,1053.31 784.215,1063.49 783.811,1073.61 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 783.811,1073.61 783.387,1078.98 782.157,1084.15 780.179,1089.13 777.514,1093.94 774.221,1098.59 770.361,1103.09 765.992,1107.47 761.175,1111.73 755.969,1115.89 \n",
" 750.435,1119.97 744.631,1123.98 738.619,1127.94 732.456,1131.86 726.205,1135.76 719.923,1139.65 713.671,1143.55 707.509,1147.47 701.497,1151.43 695.693,1155.44 \n",
" 690.159,1159.52 684.953,1163.69 680.136,1167.95 675.767,1172.32 671.907,1176.83 668.614,1181.48 665.949,1186.28 663.971,1191.26 662.741,1196.43 662.317,1201.81 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 783.811,1073.61 783.678,1081.97 783.291,1090.49 782.67,1099.16 781.833,1107.97 780.799,1116.9 779.586,1125.94 778.214,1135.08 776.701,1144.31 775.066,1153.62 \n",
" 773.328,1162.99 771.506,1172.41 769.617,1181.88 767.682,1191.37 765.718,1200.89 763.745,1210.4 761.782,1219.92 759.847,1229.41 757.958,1238.88 756.136,1248.3 \n",
" 754.397,1257.67 752.762,1266.98 751.249,1276.21 749.877,1285.35 748.665,1294.39 747.631,1303.32 746.794,1312.13 746.173,1320.8 745.786,1329.32 745.653,1337.68 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1047.26,765.786 1047.02,772.881 1046.31,780.053 1045.17,787.298 1043.64,794.609 1041.75,801.98 1039.53,809.407 1037.02,816.882 1034.25,824.401 1031.25,831.957 \n",
" 1028.07,839.545 1024.74,847.159 1021.28,854.793 1017.74,862.442 1014.14,870.099 1010.53,877.76 1006.94,885.417 1003.4,893.065 999.941,900.7 996.605,908.314 \n",
" 993.424,915.902 990.431,923.458 987.662,930.977 985.151,938.452 982.932,945.879 981.039,953.25 979.507,960.561 978.37,967.806 977.663,974.978 977.419,982.073 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1047.26,765.786 1047.48,773.058 1048.12,780.426 1049.15,787.883 1050.54,795.422 1052.25,803.037 1054.26,810.719 1056.53,818.462 1059.04,826.258 1061.75,834.101 \n",
" 1064.63,841.983 1067.65,849.897 1070.78,857.836 1073.99,865.793 1077.24,873.761 1080.51,881.732 1083.76,889.7 1086.97,897.657 1090.1,905.596 1093.12,913.51 \n",
" 1096,921.393 1098.71,929.235 1101.22,937.032 1103.49,944.775 1105.5,952.457 1107.22,960.071 1108.6,967.61 1109.63,975.068 1110.27,982.436 1110.49,989.707 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 977.419,982.073 977.164,991.645 976.422,1001.36 975.229,1011.21 973.622,1021.18 971.636,1031.27 969.308,1041.46 966.673,1051.73 963.768,1062.09 960.629,1072.52 \n",
" 957.292,1083 953.792,1093.54 950.166,1104.11 946.45,1114.71 942.679,1125.32 938.891,1135.94 935.121,1146.55 931.405,1157.15 927.779,1167.72 924.279,1178.25 \n",
" 920.941,1188.74 917.802,1199.17 914.897,1209.52 912.262,1219.8 909.934,1229.99 907.948,1240.07 906.341,1250.04 905.148,1259.89 904.406,1269.61 904.151,1279.18 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 977.419,982.073 977.563,992.797 977.981,1003.73 978.653,1014.86 979.559,1026.17 980.678,1037.64 981.99,1049.26 983.475,1061.02 985.112,1072.89 986.881,1084.86 \n",
" 988.762,1096.92 990.734,1109.05 992.777,1121.23 994.871,1133.45 996.996,1145.69 999.131,1157.95 1001.26,1170.19 1003.35,1182.41 1005.39,1194.6 1007.37,1206.72 \n",
" 1009.25,1218.78 1011.02,1230.75 1012.65,1242.62 1014.14,1254.38 1015.45,1266 1016.57,1277.47 1017.47,1288.78 1018.15,1299.91 1018.56,1310.85 1018.71,1321.57 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1359.9,622.146 1360.48,627.894 1362.16,633.261 1364.87,638.273 1368.52,642.96 1373.02,647.351 1378.31,651.472 1384.29,655.353 1390.88,659.022 1398,662.506 \n",
" 1405.58,665.836 1413.52,669.038 1421.75,672.14 1430.19,675.173 1438.74,678.162 1447.34,681.138 1455.9,684.127 1464.33,687.159 1472.56,690.262 1480.51,693.464 \n",
" 1488.08,696.793 1495.21,700.278 1501.8,703.947 1507.78,707.828 1513.06,711.949 1517.57,716.339 1521.22,721.027 1523.92,726.039 1525.61,731.406 1526.19,737.154 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1359.9,622.146 1359.94,628.126 1360.08,634.23 1360.31,640.448 1360.61,646.772 1360.98,653.191 1361.41,659.697 1361.9,666.28 1362.45,672.932 1363.03,679.644 \n",
" 1363.66,686.405 1364.31,693.208 1364.99,700.043 1365.68,706.901 1366.39,713.772 1367.09,720.648 1367.8,727.519 1368.49,734.377 1369.17,741.212 1369.82,748.015 \n",
" 1370.45,754.776 1371.03,761.488 1371.58,768.14 1372.07,774.723 1372.5,781.229 1372.88,787.648 1373.18,793.971 1373.4,800.19 1373.54,806.293 1373.58,812.274 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1526.19,737.154 1526.29,745.324 1526.57,753.658 1527.02,762.142 1527.62,770.766 1528.38,779.517 1529.26,788.382 1530.25,797.351 1531.35,806.409 1532.54,815.547 \n",
" 1533.8,824.751 1535.12,834.009 1536.5,843.31 1537.9,852.641 1539.33,861.99 1540.76,871.345 1542.19,880.695 1543.59,890.025 1544.96,899.326 1546.29,908.585 \n",
" 1547.55,917.789 1548.74,926.926 1549.83,935.985 1550.83,944.953 1551.71,953.819 1552.46,962.57 1553.07,971.193 1553.52,979.678 1553.8,988.011 1553.9,996.182 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1526.19,737.154 1526.62,747.291 1527.88,757.482 1529.9,767.721 1532.62,778.006 1535.99,788.331 1539.94,798.695 1544.4,809.091 1549.32,819.517 1554.64,829.968 \n",
" 1560.3,840.441 1566.23,850.932 1572.38,861.436 1578.68,871.951 1585.07,882.471 1591.49,892.993 1597.88,903.513 1604.17,914.027 1610.32,924.532 1616.25,935.022 \n",
" 1621.91,945.495 1627.23,955.947 1632.15,966.373 1636.62,976.769 1640.56,987.132 1643.93,997.458 1646.65,1007.74 1648.67,1017.98 1649.93,1028.17 1650.36,1038.31 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1650.36,1038.31 1650.67,1047.97 1651.55,1057.75 1652.97,1067.65 1654.89,1077.64 1657.26,1087.74 1660.03,1097.92 1663.17,1108.17 1666.63,1118.49 1670.37,1128.88 \n",
" 1674.35,1139.31 1678.52,1149.78 1682.84,1160.28 1687.27,1170.81 1691.77,1181.35 1696.28,1191.89 1700.77,1202.43 1705.2,1212.96 1709.52,1223.46 1713.7,1233.93 \n",
" 1717.67,1244.36 1721.41,1254.74 1724.88,1265.07 1728.02,1275.32 1730.79,1285.5 1733.16,1295.59 1735.07,1305.59 1736.49,1315.49 1737.38,1325.27 1737.68,1334.93 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1650.36,1038.31 1650.48,1045.67 1650.82,1053.17 1651.36,1060.79 1652.09,1068.54 1653,1076.4 1654.05,1084.35 1655.25,1092.39 1656.57,1100.52 1658,1108.7 \n",
" 1659.52,1116.95 1661.11,1125.24 1662.76,1133.57 1664.45,1141.92 1666.17,1150.29 1667.89,1158.67 1669.61,1167.04 1671.3,1175.39 1672.95,1183.72 1674.54,1192.01 \n",
" 1676.06,1200.26 1677.48,1208.45 1678.8,1216.57 1680,1224.61 1681.06,1232.57 1681.97,1240.42 1682.7,1248.17 1683.24,1255.8 1683.58,1263.3 1683.69,1270.65 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1373.58,812.274 1373.83,820.204 1374.54,828.237 1375.69,836.365 1377.23,844.58 1379.14,852.874 1381.37,861.241 1383.9,869.673 1386.69,878.161 1389.7,886.699 \n",
" 1392.91,895.279 1396.27,903.893 1399.75,912.533 1403.32,921.192 1406.94,929.863 1410.57,938.538 1414.19,947.208 1417.76,955.868 1421.24,964.508 1424.6,973.122 \n",
" 1427.81,981.702 1430.82,990.239 1433.61,998.728 1436.14,1007.16 1438.37,1015.53 1440.28,1023.82 1441.82,1032.04 1442.97,1040.16 1443.68,1048.2 1443.93,1056.13 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1373.58,812.274 1373.35,819.571 1372.66,826.957 1371.55,834.425 1370.07,841.967 1368.22,849.578 1366.07,857.251 1363.62,864.98 1360.93,872.758 1358.02,880.578 \n",
" 1354.93,888.434 1351.68,896.32 1348.32,904.228 1344.88,912.153 1341.39,920.088 1337.87,928.025 1334.38,935.96 1330.94,943.885 1327.57,951.793 1324.33,959.679 \n",
" 1321.24,967.535 1318.33,975.355 1315.63,983.133 1313.19,990.861 1311.03,998.535 1309.19,1006.15 1307.7,1013.69 1306.6,1021.16 1305.91,1028.54 1305.67,1035.84 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1443.93,1056.13 1443.77,1062.59 1443.33,1069.16 1442.62,1075.83 1441.66,1082.59 1440.47,1089.43 1439.08,1096.35 1437.5,1103.33 1435.77,1110.37 1433.89,1117.47 \n",
" 1431.89,1124.6 1429.8,1131.77 1427.64,1138.97 1425.41,1146.19 1423.16,1153.42 1420.9,1160.65 1418.64,1167.88 1416.42,1175.1 1414.25,1182.3 1412.16,1189.47 \n",
" 1410.17,1196.61 1408.29,1203.7 1406.55,1210.74 1404.98,1217.73 1403.59,1224.64 1402.4,1231.48 1401.44,1238.24 1400.73,1244.91 1400.28,1251.48 1400.13,1257.95 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1443.93,1056.13 1444.26,1062.95 1445.21,1069.77 1446.76,1076.6 1448.83,1083.43 1451.4,1090.27 1454.41,1097.11 1457.81,1103.95 1461.57,1110.79 1465.63,1117.63 \n",
" 1469.94,1124.47 1474.46,1131.32 1479.15,1138.17 1483.95,1145.01 1488.82,1151.86 1493.72,1158.71 1498.59,1165.55 1503.39,1172.4 1508.08,1179.25 1512.6,1186.09 \n",
" 1516.92,1192.94 1520.98,1199.78 1524.73,1206.62 1528.13,1213.46 1531.14,1220.3 1533.71,1227.13 1535.79,1233.96 1537.33,1240.79 1538.29,1247.62 1538.62,1254.44 \n",
2021-12-09 15:43:14 +00:00
" \n",
2021-12-09 10:54:09 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M1226.83 262.317 L1220.35 251.093 L1207.38 251.093 L1200.9 262.317 L1207.38 273.541 L1220.35 273.541 L1226.83 262.317 L1226.83 262.317 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1226.83,262.317 1220.35,251.093 1207.38,251.093 1200.9,262.317 1207.38,273.541 1220.35,273.541 1226.83,262.317 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M1070.98 566.156 L1064.5 554.932 L1051.54 554.932 L1045.06 566.156 L1051.54 577.38 L1064.5 577.38 L1070.98 566.156 L1070.98 566.156 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1070.98,566.156 1064.5,554.932 1051.54,554.932 1045.06,566.156 1051.54,577.38 1064.5,577.38 1070.98,566.156 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M1372.86 622.146 L1366.38 610.922 L1353.42 610.922 L1346.94 622.146 L1353.42 633.37 L1366.38 633.37 L1372.86 622.146 L1372.86 622.146 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1372.86,622.146 1366.38,610.922 1353.42,610.922 1346.94,622.146 1353.42,633.37 1366.38,633.37 1372.86,622.146 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M912.911 770.495 L906.431 759.271 L893.471 759.271 L886.99 770.495 L893.471 781.719 L906.431 781.719 L912.911 770.495 L912.911 770.495 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 912.911,770.495 906.431,759.271 893.471,759.271 886.99,770.495 893.471,781.719 906.431,781.719 912.911,770.495 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M1060.22 765.786 L1053.74 754.562 L1040.78 754.562 L1034.3 765.786 L1040.78 777.01 L1053.74 777.01 L1060.22 765.786 L1060.22 765.786 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1060.22,765.786 1053.74,754.562 1040.78,754.562 1034.3,765.786 1040.78,777.01 1053.74,777.01 1060.22,765.786 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M910.402 1092.11 L903.921 1080.89 L890.961 1080.89 L884.481 1092.11 L890.961 1103.34 L903.921 1103.34 L910.402 1092.11 L910.402 1092.11 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 910.402,1092.11 903.921,1080.89 890.961,1080.89 884.481,1092.11 890.961,1103.34 903.921,1103.34 910.402,1092.11 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M796.771 1073.61 L790.291 1062.38 L777.33 1062.38 L770.85 1073.61 L777.33 1084.83 L790.291 1084.83 L796.771 1073.61 L796.771 1073.61 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 796.771,1073.61 790.291,1062.38 777.33,1062.38 770.85,1073.61 777.33,1084.83 790.291,1084.83 796.771,1073.61 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M675.278 1201.81 L668.797 1190.58 L655.837 1190.58 L649.357 1201.81 L655.837 1213.03 L668.797 1213.03 L675.278 1201.81 L675.278 1201.81 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 675.278,1201.81 668.797,1190.58 655.837,1190.58 649.357,1201.81 655.837,1213.03 668.797,1213.03 675.278,1201.81 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M758.614 1337.68 L752.133 1326.46 L739.173 1326.46 L732.693 1337.68 L739.173 1348.91 L752.133 1348.91 L758.614 1337.68 L758.614 1337.68 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 758.614,1337.68 752.133,1326.46 739.173,1326.46 732.693,1337.68 739.173,1348.91 752.133,1348.91 758.614,1337.68 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M990.38 982.073 L983.9 970.848 L970.939 970.848 L964.459 982.073 L970.939 993.297 L983.9 993.297 L990.38 982.073 L990.38 982.073 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 990.38,982.073 983.9,970.848 970.939,970.848 964.459,982.073 970.939,993.297 983.9,993.297 990.38,982.073 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M1133.06 989.707 L1121.78 970.165 L1099.21 970.165 L1087.93 989.707 L1099.21 1009.25 L1121.78 1009.25 L1133.06 989.707 L1133.06 989.707 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1133.06,989.707 1121.78,970.165 1099.21,970.165 1087.93,989.707 1099.21,1009.25 1121.78,1009.25 1133.06,989.707 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M926.716 1279.18 L915.434 1259.64 L892.868 1259.64 L881.585 1279.18 L892.868 1298.73 L915.434 1298.73 L926.716 1279.18 L926.716 1279.18 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 926.716,1279.18 915.434,1259.64 892.868,1259.64 881.585,1279.18 892.868,1298.73 915.434,1298.73 926.716,1279.18 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M1041.27 1321.57 L1029.99 1302.03 L1007.42 1302.03 L996.142 1321.57 L1007.42 1341.11 L1029.99 1341.11 L1041.27 1321.57 L1041.27 1321.57 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1041.27,1321.57 1029.99,1302.03 1007.42,1302.03 996.142,1321.57 1007.42,1341.11 1029.99,1341.11 1041.27,1321.57 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M1548.75 737.154 L1537.47 717.612 L1514.91 717.612 L1503.62 737.154 L1514.91 756.696 L1537.47 756.696 L1548.75 737.154 L1548.75 737.154 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1548.75,737.154 1537.47,717.612 1514.91,717.612 1503.62,737.154 1514.91,756.696 1537.47,756.696 1548.75,737.154 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M1396.15 812.274 L1384.87 792.732 L1362.3 792.732 L1351.02 812.274 L1362.3 831.816 L1384.87 831.816 L1396.15 812.274 L1396.15 812.274 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1396.15,812.274 1384.87,792.732 1362.3,792.732 1351.02,812.274 1362.3,831.816 1384.87,831.816 1396.15,812.274 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M1576.46 996.182 L1565.18 976.639 L1542.62 976.639 L1531.33 996.182 L1542.62 1015.72 L1565.18 1015.72 L1576.46 996.182 L1576.46 996.182 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1576.46,996.182 1565.18,976.639 1542.62,976.639 1531.33,996.182 1542.62,1015.72 1565.18,1015.72 1576.46,996.182 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M1672.93 1038.31 L1661.65 1018.77 L1639.08 1018.77 L1627.8 1038.31 L1639.08 1057.85 L1661.65 1057.85 L1672.93 1038.31 L1672.93 1038.31 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1672.93,1038.31 1661.65,1018.77 1639.08,1018.77 1627.8,1038.31 1639.08,1057.85 1661.65,1057.85 1672.93,1038.31 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M1760.25 1334.93 L1748.97 1315.39 L1726.4 1315.39 L1715.12 1334.93 L1726.4 1354.47 L1748.97 1354.47 L1760.25 1334.93 L1760.25 1334.93 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1760.25,1334.93 1748.97,1315.39 1726.4,1315.39 1715.12,1334.93 1726.4,1354.47 1748.97,1354.47 1760.25,1334.93 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M1706.26 1270.65 L1694.98 1251.11 L1672.41 1251.11 L1661.13 1270.65 L1672.41 1290.2 L1694.98 1290.2 L1706.26 1270.65 L1706.26 1270.65 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1706.26,1270.65 1694.98,1251.11 1672.41,1251.11 1661.13,1270.65 1672.41,1290.2 1694.98,1290.2 1706.26,1270.65 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M1466.49 1056.13 L1455.21 1036.58 L1432.64 1036.58 L1421.36 1056.13 L1432.64 1075.67 L1455.21 1075.67 L1466.49 1056.13 L1466.49 1056.13 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1466.49,1056.13 1455.21,1036.58 1432.64,1036.58 1421.36,1056.13 1432.64,1075.67 1455.21,1075.67 1466.49,1056.13 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M1328.24 1035.84 L1316.96 1016.3 L1294.39 1016.3 L1283.11 1035.84 L1294.39 1055.38 L1316.96 1055.38 L1328.24 1035.84 L1328.24 1035.84 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1328.24,1035.84 1316.96,1016.3 1294.39,1016.3 1283.11,1035.84 1294.39,1055.38 1316.96,1055.38 1328.24,1035.84 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M1422.7 1257.95 L1411.41 1238.41 L1388.85 1238.41 L1377.57 1257.95 L1388.85 1277.49 L1411.41 1277.49 L1422.7 1257.95 L1422.7 1257.95 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1422.7,1257.95 1411.41,1238.41 1388.85,1238.41 1377.57,1257.95 1388.85,1277.49 1411.41,1277.49 1422.7,1257.95 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<path clip-path=\"url(#clip192)\" d=\"\n",
"M1561.18 1254.44 L1549.9 1234.9 L1527.33 1234.9 L1516.05 1254.44 L1527.33 1273.98 L1549.9 1273.98 L1561.18 1254.44 L1561.18 1254.44 Z\n",
2021-12-09 15:43:14 +00:00
" \" fill=\"#009af9\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n",
2021-12-10 10:24:14 +00:00
"<polyline clip-path=\"url(#clip192)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n",
" 1561.18,1254.44 1549.9,1234.9 1527.33,1234.9 1516.05,1254.44 1527.33,1273.98 1549.9,1273.98 1561.18,1254.44 \n",
2021-12-09 15:43:14 +00:00
" \"/>\n",
2021-12-10 10:24:14 +00:00
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1213.87\" cy=\"262.317\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1058.02\" cy=\"566.156\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1359.9\" cy=\"622.146\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"899.951\" cy=\"770.495\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1047.26\" cy=\"765.786\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"897.441\" cy=\"1092.11\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"783.811\" cy=\"1073.61\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"662.317\" cy=\"1201.81\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"745.653\" cy=\"1337.68\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"977.419\" cy=\"982.073\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1110.49\" cy=\"989.707\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"904.151\" cy=\"1279.18\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1018.71\" cy=\"1321.57\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1526.19\" cy=\"737.154\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1373.58\" cy=\"812.274\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1553.9\" cy=\"996.182\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1650.36\" cy=\"1038.31\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1737.68\" cy=\"1334.93\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1683.69\" cy=\"1270.65\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1443.93\" cy=\"1056.13\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1305.67\" cy=\"1035.84\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1400.13\" cy=\"1257.95\" r=\"2\"/>\n",
"<circle clip-path=\"url(#clip192)\" style=\"fill:#009af9; stroke:none; fill-opacity:1\" cx=\"1538.62\" cy=\"1254.44\" r=\"2\"/>\n",
"<path clip-path=\"url(#clip190)\" d=\"M1213.87 249.891 Q1210.71 249.891 1209.11 253.01 Q1207.53 256.109 1207.53 262.348 Q1207.53 268.566 1209.11 271.685 Q1210.71 274.784 1213.87 274.784 Q1217.05 274.784 1218.63 271.685 Q1220.23 268.566 1220.23 262.348 Q1220.23 256.109 1218.63 253.01 Q1217.05 249.891 1213.87 249.891 M1213.87 246.65 Q1218.95 246.65 1221.62 250.681 Q1224.32 254.691 1224.32 262.348 Q1224.32 269.984 1221.62 274.014 Q1218.95 278.025 1213.87 278.025 Q1208.78 278.025 1206.09 274.014 Q1203.41 269.984 1203.41 262.348 Q1203.41 254.691 1206.09 250.681 Q1208.78 246.65 1213.87 246.65 Z\" fill=\"#000000\" fill-rule=\"evenodd\" fill-opacity=\"1\" /><path clip-path=\"url(#clip190)\" d=\"M1049.6 577.833 L1056.29 577.833 L1056.29 554.763 L1049.02 556.221 L1049.02 552.494 L1056.25 551.036 L1060.34 551.036 L1060.34 577.833 L1067.02 577.833 L1067.02 581.276 L1049.6 581.276 L1049.6 577.833 Z\" fill=\"#000000\" fill-rule=\"evenodd\" fill-opacity=\"1\" /><path clip-path=\"url(#clip190)\" d=\"M1355.22 633.823 L1369.5 633.823 L1369.5 637.266 L1350.3 637.266 L1350.3 633.823 Q1352.63 631.412 1356.64 627.361 Q1360.67 623.29 1361.7 622.116 Q1363.66 619.908 1364.43 618.389 Q1365.22 616.849 1365.22 615.371 Q1365.22 612.961 1363.52 611.441 Q1361.84 609.922 1359.13 609.922 Q1357.2 609.922 1355.06 610.591 Q1352.93 611.259 1350.5 612.616 L1350.5 608.484 Q1352.97 607.492 1355.12 606.985 Q1357.26 606.479 1359.05 606.479 Q1363.75 606.479 1366.54 608.829 Q1369.34 611.178 1369.34 615.107 Q1369.34 616.971 1368.63 618.652 Q1367.94 620.313 1366.09 622.581 Q1365.59 623.169 1362.87 625.984 Q1360.16 628.779 1355.22 633.823 Z\" fill=\"#000000\" fill-rule=\"evenodd\" fill-opacity=\"1\" /><path clip-path=\"url(#clip190)\" d=\"M903.668 769.31 Q906.605 769.938 908.245 771.923 Q909.906 773.908 909.906 776.825 Q909.906 781.301 906.827 783.752 Q903.749 786.203 898.077 786.203 Q896.173 786.203 894.148 785.818 Q892.143 785.453 889.996 784.704 L889.996 780.754 Q891.697 781.747 893.723 782.253 Q895.748 782.759 897.956 782.759 Q901.804 782.759 903.809 781.24 Q905.835 779.721 905.835 776.825 Q905.835 774.151 903.951 772.652 Q902.088 771.133 898.746 771.133 L895.221 771.133 L895.221 767.771 L898.908 767.771 Q901.926 767.771 903.526 766.576 Q905.126 765.361 905.126 763.092 Q905.126 760.763 903.465 759.527 Q901.824 758.272 898.746 758.272 Q897.065 758.272 895.14 758.636 Q893.216 759.001 890.907 759.77 L890.907 756.125 Q893.237 755.476 895.262 755.152 Q897.308 754.828 899.11 754.828 Q903.769 754.828 906.483 756.955 Q909.197 759.061 909.197 762.667 Q909.197 765.178 907.759 766.92 Q906.321 768.642 903.668 769.31 Z\" fill=\"#000000\" fill-rule=\"evenodd\" fill-opacity=\"1\" /><path clip-path=\"url(#clip190)\" d=\"M1049.89 754.231 L1039.56 770.374 L1049.89 770.374 L1049.89 754.231 M1048.82 750.666 L1053.96 750.666 L1053.96 770.374 L1058.28 770.374 L1058.28 773.777 L1053.96 773.777 L1053.96 780.906 L1049.89 780.906 L1049.89 773.777 L1036.24 773.777 L1036.24 769.827 L1048.82 750.666 Z\" fill=\"#000000\" fill-rule=\"evenodd\" fill-opacity=\"1\" /><path clip-path=\"url(#clip190)\" d=\"M888.934 1076.99 L904.996 1076.99 L904.996 1080.43 L892.681 1080.43 L892.681 1087.85 Q893.573 1087.54 894.464 1087.4 Q895.355 1087.24 896.246 1087.24 Q901.31 1087.24 904.267 1090.01 Q907.224 1092.79 907.224 1097.53 Q907.224 1102.41 904.186 1105.12 Q901.148 1107.82 895.618 1107.82 Q893.714 1107.82 891.729 1107.49 Q889.765 1107.17 887.658 1106.52 L887.658 1102.41 Q889.481 1103.4 891.426 1103.89 Q893.37 1104.38 895.537 1104.38 Q899.041 1104.38 901.087 1102.53 Q903.133 1100.69 903.133 1097.53 Q903.133 1094.37 901.087 1092.53 Q899.041 1090.68 895.537 1090.68 Q893.897 1090.68 892.256 1091.05 Q890.636 1091.41 888.934 1092.18 L888.934 1076.99 Z\" fill=\"#000000\" fill-rule=\"evenodd\" fill-opacity=\"1\" /><path clip-path=\"url(#clip190)\" d=\"M784.165 1071.98 Q781.41 1071.98 779.79 1073.86 Q778.19 1075.74 778.19 1079.02 Q778.19 1082.29 779.79 1084.19 Q781.41 1086.07 784.165 1086.07 Q786.92 1086.07 788.52 1084.19 Q790.14 1082.29 790.14 1079.02 Q790.14 1075.74 788.52 1073.86 Q786.92 1071.98 784.16
2021-12-09 15:43:14 +00:00
]
},
"metadata": {},
"output_type": "display_data"
2021-12-09 10:54:09 +00:00
}
],
2021-12-05 15:21:15 +00:00
"source": [
2021-12-10 10:24:14 +00:00
"# graphplot(trParentnodes, trChildnodes, names = trNamenodes, method = :tree)"
2021-11-26 16:57:38 +00:00
]
2021-12-09 10:54:09 +00:00
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Rapport\n",
"\n",
"- Quelques détails sur les points clés et non triviaux de votre implémentation\n",
"- Une courte argumentation de l’ adéquation du résultat avec l’ instance résolue\n",
"- Quelques éléments d’ analyse, par exemple :\n",
"- Analyser l’ impact des différents paramètres de la PSE sur la performance en terme de vitesse/délais (en temps cpu et nombre de noeuds explorés) pour l’ obtention d’ une solution réalisable, pour l’ obtention de la meilleure solution, pour l’ obtention de bornes supérieures de qualité et pour la complétion de l’ algorithme\n",
"\n",
"## Notre implémentation\n",
"\n",
2021-12-09 15:43:14 +00:00
"Pour l'implémentation de notre `branch and bound`, nous avons gardé la même architecture que celle du sujet. Nous avons simplement ré-écrit les fonctions qui calculent la valeur objectif et la valeur de la capacité. \\\n",
2021-12-10 10:07:22 +00:00
"Notre vecteur de décision $x$ est tel que $x\\in\\{-1,0,1\\}^n$ avec $n$ le nombre d'objets disponibles. $1$ et $0$ représentent, respectivement, un objet pris ou non-pris. La valeur $-1$ représente un objet ou la décision n'a pas encore été faite. \\\n",
"Dans la fonction `Objective`, si la valeur est a $-1$, on fait comme-ci elle était à $1$ pour calculer une borne supérieur. Dans la fonction `Constraints` les $-1$ sont concidérés comme des $0$ pour avoir une borne inférieur de notre problème. \\\n",
"\n",
2021-12-09 10:54:09 +00:00
"Pour l'exploration et la création de noeud, nous faisons une exploration des noeuds avec le plus de $1$ en premier. \\\n",
2021-12-10 10:07:22 +00:00
"Lorsque nous arrivons sur un noeud, nous l'enlevons de la pile des noeuds. Nous calculons ensuite s'il est \"trivial\", s'il dépasse déjà l'une des bornes ou s'il est divisible.\n",
"- Dans le cas ou il est \"trivial\", nous calculons sa valeur et remplaçons la meilleure valeur si nécessaire.\n",
"- Dans le cas ou il dépasse une borne, nous l'abandonnons.\n",
"- Et enfin, si il est séparable, nous le séparons en deux en ajoutant la pile des noeuds les deux sous noeuds. Exemple : $[(0,-1,-1)]$ -> $[(0,0,-1) ; (0,1,-1)]$\n",
2021-12-09 10:54:09 +00:00
"\n",
"## Justification de nos résultats\n",
"\n",
2021-12-10 10:07:22 +00:00
"Notre algorithme trouve bien les solutions idéales. Pour le test `uncorrelated_span/knapPI_11_20_1000_1_-1428` Nous avons trouvé la valeur optimale qui est de `1428` en `2131` exploration de noeuds là ou un algorithme classique de parcours de l'ensemble des noeuds aurait exploré `1048576` noeuds, et ce sans dépasser la capacité maximale du sac bien evidemment.\n",
2021-12-09 10:54:09 +00:00
"\n",
"## Analyse\n",
"\n",
2021-12-10 10:07:22 +00:00
"Nous avaons réalisé les calculs de deux manières différentes:\n",
"- La première fois, nous mettions a jour les coordonnées de $x$ dans l'ordre des indices.\n",
"- La deuxième fois, nous avons d'abbord trié les vecteurs `weight` et `price` par leur rapport $prix / poids$. Cela revient à mettre à jour les coordonnées de $x$ dans l'ordre du meilleur rapport $prix / poids$. (NB : le vecteur résultat n'est pas ré-ordonné comme l'était les `price` et `weight` initialement)\n",
2021-12-09 10:54:09 +00:00
"\n",
2021-12-10 10:07:22 +00:00
"Pour le fichier `weakly_correlated/knapPI_2_50_1000_1_-1396`, nous avons comparé les résultats :\n",
"| Valeurs | Sans tri | Avec tri |\n",
"| :------------- | :------- | :------- |\n",
"| Optimal value | 1396 | 1396 |\n",
"| Nodes explored | 3053865 | 846447 |\n",
"| time | 29.372s | 4.480s |\n",
2021-12-09 10:54:09 +00:00
"\n",
2021-12-10 10:07:22 +00:00
"Il serait possible d'optimiser encore plus notre algorithme en ne stockant que les changements de valeurs dans l'abre, au lieu de stocker le vecteurs $x$ en entier à chaque noeud de l'arbre. Cela permetterait d'économiser pas mal de RAM.\n",
2021-12-09 10:54:09 +00:00
"\n",
2021-12-10 10:07:22 +00:00
"## Bonus: Comparaison avec GLPK\n",
2021-12-09 15:43:14 +00:00
"\n",
2021-12-10 10:07:22 +00:00
"La huitième cellule de ce notebook permet de convertir les `.opb` en `.lp`, et permet ainsi de résoudre les problèmes en utilisant GLPK.\n",
2021-12-10 10:24:14 +00:00
"Via les fichiers `test.jl` et `distrib.py` on lance sur toutes les machines de l'enseeiht (la nuit), la résolution de chaque problème via GLPK et via notre implémentation. On observe alors que GLPK obtient la même valeur optimale finale que notre implémentation, cependant le nombre de noeuds explorés par GLPK ainsi que son temps d'exécution sont nettement inférieur à ceux de notre algorithme."
2021-12-09 10:54:09 +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
}