diff --git a/notebook-exemple.ipynb b/notebook-exemple.ipynb index 759e653..46afd38 100644 --- a/notebook-exemple.ipynb +++ b/notebook-exemple.ipynb @@ -23,37 +23,19 @@ "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m registry at `~/.julia/registries/General`\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[32m\u001b[1m Resolving\u001b[22m\u001b[39m package versions...\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ + "\u001b[32m\u001b[1m Updating\u001b[22m\u001b[39m registry at `~/.julia/registries/General`\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" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\u001b[32m\u001b[1m Resolving\u001b[22m\u001b[39m package versions...\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ + "\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.6/Manifest.toml`\n", + "\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m project...\n", + "\u001b[32m ✓ \u001b[39mTestOptinum\n", + " 1 dependency successfully precompiled in 6 seconds (158 already precompiled)\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" + "\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.6/Manifest.toml`\n", + "\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m project...\n", + "\u001b[32m ✓ \u001b[39mTestOptinum\n", + " 1 dependency successfully precompiled in 2 seconds (158 already precompiled)\n" ] } ], @@ -81,8 +63,9 @@ "readKnaptxtInstance (generic function with 1 method)" ] }, + "execution_count": 2, "metadata": {}, - "output_type": "display_data" + "output_type": "execute_result" } ], "source": [ @@ -131,8 +114,9 @@ "TestsSondabilite_relaxlin (generic function with 1 method)" ] }, + "execution_count": 3, "metadata": {}, - "output_type": "display_data" + "output_type": "execute_result" } ], "source": [ @@ -179,8 +163,9 @@ "ExplorerAutreNoeud_relaxlin (generic function with 1 method)" ] }, + "execution_count": 4, "metadata": {}, - "output_type": "display_data" + "output_type": "execute_result" } ], "source": [ @@ -272,22 +257,19 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m\u001b[1m Resolving\u001b[22m\u001b[39m package versions...\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ + "\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 No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.6/Manifest.toml`\n", + "\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m project...\n", + "\u001b[32m ✓ \u001b[39mTestOptinum\n", + " 1 dependency successfully precompiled in 3 seconds (167 already precompiled)\n" ] } ], @@ -298,7 +280,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 10, "metadata": {}, "outputs": [ { @@ -307,8 +289,9 @@ "CreationModeleLP (generic function with 1 method)" ] }, + "execution_count": 10, "metadata": {}, - "output_type": "display_data" + "output_type": "execute_result" } ], "source": [ @@ -344,7 +327,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 11, "metadata": {}, "outputs": [ { @@ -353,8 +336,9 @@ "SolveKnapInstance (generic function with 1 method)" ] }, + "execution_count": 11, "metadata": {}, - "output_type": "display_data" + "output_type": "execute_result" } ], "source": [ @@ -438,30 +422,16 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "\n", + "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]\n", "Subject to\n", - " " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "7 x[1] + 4 x[2] + 3 x[3] + 5 x[4] ≤ 10.0\n", + " 7 x[1] + 4 x[2] + 3 x[3] + 5 x[4] ≤ 10.0\n", " x[1] ≥ 0.0\n", " x[2] ≥ 0.0\n", " x[3] ≥ 0.0\n", @@ -486,50 +456,15 @@ " x[3] ≤ 1.0\n", " x[4] ≤ 1.0\n", "\n", - "Solve model2 to compute the bounds of the current node: start ... " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "... end\n", + "Solve model2 to compute the bounds of the current node: start ... ... end\n", "\n", - "Solution relax lin\t" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "x[1]=0.857142857142857\tx[2]=1.0\tx[3]=0.0\tx[4]=0.0 \n", + "Solution relax lin\tx[1]=0.857142857142857\tx[2]=1.0\tx[3]=0.0\tx[4]=0.0 \n", "\n", - "Previous Solution memorized " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Any[] with bestprofit -1\n", + "Previous Solution memorized Any[] with bestprofit -1\n", "\n", - "non sondable" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ + "non sondable\n", "\n", - "\n", - "Node number " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "1: \n", + "Node number 1: \n", "-----\n", "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]\n", "Subject to\n", @@ -657,14 +592,7 @@ "\n", "Solution relax lin\tx[1]=0.0\tx[2]=1.0\tx[3]=0.3333333333333332\tx[4]=1.0 \n", "\n", - "Previous Solution memorized " - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "[1.0, 0.0, 1.0, 0.0] with bestprofit 54.0\n", + "Previous Solution memorized [1.0, 0.0, 1.0, 0.0] with bestprofit 54.0\n", "\n", "non sondable\n", "\n", @@ -812,212 +740,28 @@ "\n", "Optimal value = 65.0\n", "\n", - "Optimal x=[0.0, 1.0, 0.0, 1.0]\n" + "Optimal x=[0.0, 1.0, 0.0, 1.0]\n", + "[1, 2, 2, 4, 4, 1, 7, 8, 9, 9, 8, 7]\n", + "[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]\n", + "Any[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]\n" ] - }, - { - "data": { - "image/png": "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", - "image/svg+xml": "\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n \n \n \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n", - "text/html": [ - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - " \n", - " \n", - " \n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n", - "\n" - ] - }, - "metadata": {}, - "output_type": "display_data" } ], "source": [ "BestProfit, Bestsol, trParentnodes, trChildnodes, trNamenodes = SolveKnapInstance(\"data/test.opb\")\n", "println(\"\\n******\\n\\nOptimal value = \", BestProfit, \"\\n\\nOptimal x=\", Bestsol)\n", - "graphplot(trParentnodes, trChildnodes, names=trNamenodes, method=:tree)" + "graphplot(trParentnodes, trChildnodes, names=trNamenodes, method=:tree)\n", + "println(trParentnodes)\n", + "println(trChildnodes)\n", + "println(trNamenodes)" ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] } ], "metadata": { @@ -1030,7 +774,7 @@ "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", - "version": "1.6.3" + "version": "1.6.4" } }, "nbformat": 4, diff --git a/notebook.ipynb b/notebook.ipynb index 7dda3e5..07854f0 100644 --- a/notebook.ipynb +++ b/notebook.ipynb @@ -29,13 +29,13 @@ "\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.6/Manifest.toml`\n", "\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m project...\n", "\u001b[32m ✓ \u001b[39mTestOptinum\n", - " 1 dependency successfully precompiled in 6 seconds (158 already precompiled)\n", + " 1 dependency successfully precompiled in 6 seconds (167 already precompiled)\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", "\u001b[32m\u001b[1mPrecompiling\u001b[22m\u001b[39m project...\n", "\u001b[32m ✓ \u001b[39mTestOptinum\n", - " 1 dependency successfully precompiled in 3 seconds (158 already precompiled)\n" + " 1 dependency successfully precompiled in 3 seconds (167 already precompiled)\n" ] } ], @@ -54,7 +54,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -63,7 +63,7 @@ "readKnapInstance (generic function with 1 method)" ] }, - "execution_count": 1, + "execution_count": 2, "metadata": {}, "output_type": "execute_result" } @@ -108,7 +108,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -117,7 +117,7 @@ "TestsSondabilite_relaxlin (generic function with 1 method)" ] }, - "execution_count": 2, + "execution_count": 3, "metadata": {}, "output_type": "execute_result" } @@ -160,6 +160,7 @@ " if affich\n", " println(\"\\n\")\n", " end\n", + " \n", " TA, TO, TR, Bestsol, BestProfit\n", "end" ] @@ -173,7 +174,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -182,7 +183,7 @@ "ExplorerAutreNoeud_relaxlin (generic function with 1 method)" ] }, - "execution_count": 3, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } @@ -218,13 +219,14 @@ " break\n", " end\n", " end\n", + " \n", " # On ajoute les sous-noeuds a la pile des noeuds a explorer\n", - " push!(listvars, nextX1)\n", " push!(listvars, nextX0)\n", + " push!(listvars, nextX1)\n", "\n", " # On ajoute aussi leurs valeurs\n", - " push!(listvals, val1)\n", " push!(listvals, val0)\n", + " push!(listvals, val1)\n", "\n", " listvars, listvals\n", "end\n", @@ -250,7 +252,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -259,7 +261,7 @@ "AllDef (generic function with 1 method)" ] }, - "execution_count": 4, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -300,48 +302,41 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 6, "metadata": {}, "outputs": [ { - "name": "stdout", - "output_type": "stream", - "text": [ - "Capacity : 994 | Number of objects : 50\n", - "\n", - "----------\n", - "Node n°1001 : \n", - "\n", - "Previous Solution memorized with bestprofit 994\n", - "\n", - "non sondable\n", - "\n", - "\n", - "\n", - "FINISHED\n", - "\n", - "******\n", - "\n", - "Optimal value = 994\n", - "\n", - "Optimal x=[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]\n" - ] + "data": { + "text/plain": [ + "SolveKnapInstance (generic function with 1 method)" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" } ], "source": [ "function SolveKnapInstance(filename)\n", "\n", + " # Extraction des données\n", " price, weight, capacity = readKnapInstance(filename)\n", "\n", " println(\"Capacity : \", capacity, \" | Number of objects : \", length(price), \"\\n\")\n", "\n", + " # Pour dessiner le graph\n", + " trParentnodes = Int64[]\n", + " trChildnodes = Int64[]\n", + " trNamenodes = []\n", + "\n", " # Liste des variable pour naviguer de noeuds en noeuds\n", - " listvars=[]\n", - " listvals=[]\n", + " listvars = []\n", + " listvals = []\n", + " listnodes = []\n", "\n", " # La meilleur solution et sa valeur\n", - " BestProfit=-1\n", - " Bestsol=[]\n", + " BestProfit = -1\n", + " Bestsol = []\n", "\n", " # Compter le nombre de noeud explorés\n", " current_node_number = 0\n", @@ -352,8 +347,12 @@ " # On ajoute le premier noeud à explorer (la racine)\n", " push!(listvars, [-1 for p in price])\n", " push!(listvals, Objective(last(listvars), price))\n", + " push!(listnodes, 1)\n", + " push!(trNamenodes, 0)\n", + " newnodeid = 2\n", "\n", " while (!stop)\n", + "\n", " # Le noeud actuel\n", " x = last(listvars)\n", "\n", @@ -371,9 +370,28 @@ " if (!is_node_sondable)\n", " # Le noeud n'est pas sondable, on le sépare en 2 sous-noeuds\n", " listvars, listvals = SeparerNoeud_relaxlin(price, listvars, listvals)\n", + "\n", + " curnode = pop!(listnodes)\n", + "\n", + " push!(trParentnodes, curnode)\n", + " push!(trParentnodes, curnode)\n", + "\n", + " push!(listnodes, newnodeid+1)\n", + " push!(listnodes, newnodeid)\n", + "\n", + " push!(trChildnodes, newnodeid)\n", + " push!(trChildnodes, newnodeid+1)\n", + "\n", + " push!(trNamenodes, newnodeid-1)\n", + " push!(trNamenodes, newnodeid)\n", + "\n", + " newnodeid += 2\n", + "\n", " else\n", " # Le noeud est sondable, on passe au noeud suivant\n", " listvars, listvals, stop = ExplorerAutreNoeud_relaxlin(listvars, listvals)\n", + "\n", + " pop!(listnodes)\n", " end\n", "\n", " # On évite de spammer l'output donc on n'affiche pas tout les résultats\n", @@ -386,11 +404,21 @@ " current_node_number += 1\n", " end\n", "\n", - " println(\"\\n******\\n\\nOptimal value = \", BestProfit, \"\\n\\nOptimal x=\", Bestsol)\n", + " println(\"\\n******\\n\\nOptimal value = \", BestProfit, \"\\n\\nOptimal x = \", Bestsol)\n", "\n", - "end\n", + " trParentnodes, trChildnodes, trNamenodes\n", + "end" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [], + "source": [ + "trParentnodes, trChildnodes, trNamenodes = SolveKnapInstance(\"data/circle/knapPI_16_8_1000_1_-2291.opb\")\n", "\n", - "SolveKnapInstance(\"data/subset_sum/knapPI_6_50_1000_1_-994.opb\")" + "graphplot(trParentnodes, trChildnodes, names=trNamenodes, method=:tree)" ] }, {