diff --git a/notebook-exemple.ipynb b/notebook-exemple.ipynb index fb5c308..759e653 100644 --- a/notebook-exemple.ipynb +++ b/notebook-exemple.ipynb @@ -16,17 +16,42 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m\u001b[1m Resolving\u001b[22m\u001b[39m package versions...\n", + "\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 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/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/Project.toml`\n", "\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.6/Manifest.toml`\n" ] @@ -47,7 +72,7 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 2, "metadata": {}, "outputs": [ { @@ -56,9 +81,8 @@ "readKnaptxtInstance (generic function with 1 method)" ] }, - "execution_count": 49, "metadata": {}, - "output_type": "execute_result" + "output_type": "display_data" } ], "source": [ @@ -98,7 +122,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 3, "metadata": {}, "outputs": [ { @@ -107,9 +131,8 @@ "TestsSondabilite_relaxlin (generic function with 1 method)" ] }, - "execution_count": 50, "metadata": {}, - "output_type": "execute_result" + "output_type": "display_data" } ], "source": [ @@ -147,7 +170,7 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -156,9 +179,8 @@ "ExplorerAutreNoeud_relaxlin (generic function with 1 method)" ] }, - "execution_count": 51, "metadata": {}, - "output_type": "execute_result" + "output_type": "display_data" } ], "source": [ @@ -250,14 +272,20 @@ }, { "cell_type": "code", - "execution_count": 52, + "execution_count": 5, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ - "\u001b[32m\u001b[1m Resolving\u001b[22m\u001b[39m package versions...\n", + "\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/Project.toml`\n", "\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.6/Manifest.toml`\n" ] @@ -270,7 +298,7 @@ }, { "cell_type": "code", - "execution_count": 53, + "execution_count": 6, "metadata": {}, "outputs": [ { @@ -279,9 +307,8 @@ "CreationModeleLP (generic function with 1 method)" ] }, - "execution_count": 53, "metadata": {}, - "output_type": "execute_result" + "output_type": "display_data" } ], "source": [ @@ -317,7 +344,7 @@ }, { "cell_type": "code", - "execution_count": 54, + "execution_count": 7, "metadata": {}, "outputs": [ { @@ -326,9 +353,8 @@ "SolveKnapInstance (generic function with 1 method)" ] }, - "execution_count": 54, "metadata": {}, - "output_type": "execute_result" + "output_type": "display_data" } ], "source": [ @@ -412,16 +438,30 @@ }, { "cell_type": "code", - "execution_count": 55, + "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]\n", + "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", "Subject to\n", - " 7 x[1] + 4 x[2] + 3 x[3] + 5 x[4] ≤ 10.0\n", + " " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "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", @@ -446,15 +486,50 @@ " x[3] ≤ 1.0\n", " x[4] ≤ 1.0\n", "\n", - "Solve model2 to compute the bounds of the current node: start ... ... end\n", + "Solve model2 to compute the bounds of the current node: start ... " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "... end\n", "\n", - "Solution relax lin\tx[1]=0.857142857142857\tx[2]=1.0\tx[3]=0.0\tx[4]=0.0 \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", "\n", - "Previous Solution memorized Any[] with bestprofit -1\n", + "Previous Solution memorized " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Any[] with bestprofit -1\n", "\n", - "non sondable\n", + "non sondable" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ "\n", - "Node number 1: \n", + "\n", + "Node number " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "1: \n", "-----\n", "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]\n", "Subject to\n", @@ -582,7 +657,14 @@ "\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 [1.0, 0.0, 1.0, 0.0] with bestprofit 54.0\n", + "Previous Solution memorized " + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[1.0, 0.0, 1.0, 0.0] with bestprofit 54.0\n", "\n", "non sondable\n", "\n", @@ -735,11 +817,200 @@ }, { "data": { - "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" + "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" + ] }, - "execution_count": 55, "metadata": {}, - "output_type": "execute_result" + "output_type": "display_data" } ], "source": [ diff --git a/notebook.ipynb b/notebook.ipynb index fb5c308..6ab646a 100644 --- a/notebook.ipynb +++ b/notebook.ipynb @@ -16,13 +16,14 @@ }, { "cell_type": "code", - "execution_count": 48, + "execution_count": 2, "metadata": {}, "outputs": [ { "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", @@ -47,25 +48,25 @@ }, { "cell_type": "code", - "execution_count": 49, + "execution_count": 9, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "readKnaptxtInstance (generic function with 1 method)" + "(Any[42, 40, 12, 25], Any[7, 4, 3, 5], 10)" ] }, - "execution_count": 49, + "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "function readKnaptxtInstance(filename)\n", + "function readKnapInstance(filename)\n", " price=[]\n", " weight=[]\n", - " KnapCap=[]\n", + " capacity = -1\n", " open(filename) do f\n", " for i in 1:3\n", " tok = split(readline(f))\n", @@ -73,20 +74,23 @@ " for i in 2:(length(tok)-1)\n", " push!(price,parse(Int64, tok[i]))\n", " end\n", - " elseif(tok[1] == \"ListWeights=\")\n", + " elseif (tok[1] == \"ListWeights=\")\n", " for i in 2:(length(tok)-1)\n", " push!(weight,parse(Int64, tok[i]))\n", " end\n", - " elseif(tok[1] == \"Capacity=\")\n", - " push!(KnapCap, parse(Int64, tok[2]))\n", + " elseif (tok[1] == \"Capacity=\")\n", + " capacity = parse(Int64, tok[2])\n", " else\n", " println(\"Unknown read :\", tok)\n", " end \n", " end\n", " end\n", - " capacity=KnapCap[1]\n", + " \n", " return price, weight, capacity\n", - "end" + "end\n", + "\n", + "# readKnapInstance(\"data/test.opb\")\n", + "# readKnapInstance(\"data/almost_strongly_correlated/knapPI_5_50_1000_1_-2096.opb\")" ] }, { @@ -98,7 +102,7 @@ }, { "cell_type": "code", - "execution_count": 50, + "execution_count": 4, "metadata": {}, "outputs": [ { @@ -107,29 +111,28 @@ "TestsSondabilite_relaxlin (generic function with 1 method)" ] }, - "execution_count": 50, + "execution_count": 4, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "function TestsSondabilite_relaxlin(model2, x, varsbin, BestProfit, Bestsol)\n", + "function TestsSondabilite_relaxlin(x, price, weight, capacity, varsbin, BestProfit, Bestsol)\n", " TA, TO, TR = false, false, false\n", - " if (termination_status(model2) == MOI.INFEASIBLE)#Test de faisabilite\n", - " TA=true\n", + " if (!Constraints(x, weight, capacity)) # Test de faisabilite\n", + " TA = true\n", " println(\"TA\")\n", - " elseif (objective_value(model2) <= BestProfit) #Test d'optimalite\n", - " TO=true\n", + " elseif (Objective(x, price) <= BestProfit) # Test d'optimalite\n", + " TO = true\n", " println(\"TO\")\n", - " elseif ( prod(abs.([round.(v, digits=0) for v in value.(varsbin)]-value.(varsbin)) .<= fill(10^-5, size(varsbin))) \n", - " ) #Test de resolution\n", - " TR=true\n", + " elseif (AllDef(x)) # Test de resolution\n", + " TR = true\n", " println(\"TR\")\n", " #if (value(benef) >= BestProfit)\n", - " if (objective_value(model2) >= BestProfit)\n", - " Bestsol = value.(x)\n", + " if (Objective(x, price) >= BestProfit)\n", + " Bestsol = x\n", " #BestProfit=value(benef)\n", - " BestProfit=objective_value(model2)\n", + " BestProfit = Objective(x, price)\n", " end\n", " else\n", " println(\"non sondable\")\n", @@ -147,7 +150,7 @@ }, { "cell_type": "code", - "execution_count": 51, + "execution_count": 5, "metadata": {}, "outputs": [ { @@ -156,7 +159,7 @@ "ExplorerAutreNoeud_relaxlin (generic function with 1 method)" ] }, - "execution_count": 51, + "execution_count": 5, "metadata": {}, "output_type": "execute_result" } @@ -164,35 +167,15 @@ "source": [ "\n", "function SeparerNoeud_relaxlin(varsshouldbebinary, listvars, listvals)\n", - " # le noeud est non-sondable. Appliquer le critère de séparation pour le séparer en sous-noeuds \n", - " # et choisir un noeud-fils le plus à gauche \n", + " # 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", " \n", - " #find a fractionnal variable\n", - " i, var = 1, 0\n", - " while ((i <= length(varsshouldbebinary)) && (var==0))\n", - " #if (varsshouldbebinary[i] ∉ listvars)\n", - " if (abs(round(value(varsshouldbebinary[i]), digits=0) - value(varsshouldbebinary[i]) ) >= 10^-5)\n", - " var=varsshouldbebinary[i]\n", - " end\n", - " i+=1\n", + " # Cas du noeud le plus à gauche\n", + " predX = first(listvars)\n", + " nextX0 = predX\n", + " for xi in predX\n", + " \n", " end\n", - " \n", - " #=\n", - " #find most fractionnal variable ?\n", - " i, var, maxfrac = -1, 0, 0.0\n", - " for i in 1:length(varsshouldbebinary)\n", - " if (abs(round(value(varsshouldbebinary[i]), digits=0) - value(varsshouldbebinary[i]) ) >= maxfrac) \n", - " #if a variable is more fractinonal\n", - " var=varsshouldbebinary[i]\n", - " maxfrac=abs(round(value(varsshouldbebinary[i]), digits=0) - value(varsshouldbebinary[i]) )\n", - " #println(i, \" \", var, \" \", maxfrac)\n", - " end\n", - " end\n", - " =#\n", - " \n", "\n", - " set_lower_bound(var,1.0)\n", - " set_upper_bound(var,1.0)\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", @@ -239,513 +222,53 @@ "end" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Création de la relaxation linéaire (= modèle associé au noeud 0): SECTION A SUPPRIMER !!!! \n", - "\n", - " Cette section est à commenter/supprimer et remplacer par vos propres calculs de bornes supérieures et autres, par exemple basées sur les bornes 1 et 2 vues en cours, ou d'autres calculs de bornes de votre choix/conception validés au préalable par votre encadrant/e de TP " - ] - }, { "cell_type": "code", - "execution_count": 52, - "metadata": {}, - "outputs": [ - { - "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" - ] - } - ], - "source": [ - "Pkg.add(\"Clp\");\n", - "using JuMP, Clp" - ] - }, - { - "cell_type": "code", - "execution_count": 53, + "execution_count": 10, "metadata": {}, "outputs": [ { "data": { "text/plain": [ - "CreationModeleLP (generic function with 1 method)" + "Constraints (generic function with 1 method)" ] }, - "execution_count": 53, + "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ - "function CreationModeleLP(price, weight, capacity)\n", - "# ROOT NODE\n", - " \n", - " model2 = Model(Clp.Optimizer) # set optimizer\n", - " set_optimizer_attribute(model2, \"LogLevel\", 0) #don't display anything during solve\n", - " set_optimizer_attribute(model2, \"Algorithm\", 4) #LP solver chosen is simplex\n", - "\n", - " # define x variables as CONTINUOUS (recall that it is not possible to define binary variables in Clp)\n", - " @variable(model2, 0 <= x[i in 1:4] <= 1)\n", - " varsshouldbebinary=[x[1] x[2] x[3] x[4]]\n", - "\n", - " # define objective function\n", - " @objective(model2, Max, sum(price[i]*x[i] for i in 1:4))\n", - "\n", - " # define the capacity constraint \n", - " @constraint(model2, sum(weight[i]*x[i] for i in 1:4) <= capacity)\n", - "\n", - " println(model2)\n", - "\n", - " return model2, x, varsshouldbebinary\n", - "end\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Boucle principale : résoudre la relaxation linéaire, appliquer les tests de sondabilité, identifier le prochain noeud, répéter." - ] - }, - { - "cell_type": "code", - "execution_count": 54, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "SolveKnapInstance (generic function with 1 method)" - ] - }, - "execution_count": 54, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "\n", - "function SolveKnapInstance(filename)\n", - "\n", - " if (split(filename,\"/\")[end] != \"test.opb\")\n", - " println(\"This version of the code works only for the test instance !!!!\")\n", - " else\n", - " price, weight, capacity = readKnaptxtInstance(filename)\n", - " model2, x, varsshouldbebinary = CreationModeleLP(price, weight, capacity)\n", - " \n", - " #create the structure to memorize the search tree for visualization at the end\n", - " trParentnodes=Int64[] #will store orig node of arc in search tree\n", - " trChildnodes=Int64[] #will store destination node of arc in search tree\n", - " trNamenodes=[] #will store names of nodes in search tree\n", - " \n", - " #intermediate structure to navigate in the search tree\n", - " listvars=[]\n", - " listvals=[]\n", - " listnodes=[]\n", - "\n", - " BestProfit=-1\n", - " Bestsol=[]\n", - "\n", - " current_node_number=0\n", - " stop = false\n", - "\n", - " while (!stop)\n", - "\n", - " println(\"\\nNode number \", current_node_number, \": \\n-----\\n\", model2)\n", - "\n", - " #Update the search tree\n", - " push!(trNamenodes,current_node_number+1) \n", - " if (length(trNamenodes)>=2)\n", - " push!(trParentnodes,listnodes[end]+1) # +1 because the 1st node is \"node 0\"\n", - " push!(trChildnodes, current_node_number+1) # +1 because the 1st node is \"node 0\"\n", - " end\n", - " push!(listnodes, current_node_number)\n", - "\n", - "\n", - " print(\"Solve model2 to compute the bounds of the current node: start ... \")\n", - " status = optimize!(model2)\n", - " println(\"... end\")\n", - "\n", - " print(\"\\nSolution relax lin\"); \n", - " if (termination_status(model2) == MOI.INFEASIBLE)#(has_values(model2))\n", - " print(\" : NOT AVAILABLE (probably infeasible or ressources limit reached)\")\n", - " else\n", - " [print(\"\\t\", name(v),\"=\",value(v)) for v in all_variables(model2)] \n", - " end\n", - " println(\" \"); println(\"\\nPrevious Solution memorized \", Bestsol, \" with bestprofit \", BestProfit, \"\\n\")\n", - "\n", - " TA, TO, TR, Bestsol, BestProfit = TestsSondabilite_relaxlin(model2, x, varsshouldbebinary, BestProfit, Bestsol)\n", - "\n", - " is_node_sondable = TA || TO || TR\n", - "\n", - " if (!is_node_sondable)\n", - " listvars, listvals = SeparerNoeud_relaxlin(varsshouldbebinary, listvars, listvals)\n", - " else\n", - " listvars, listvals, listnodes, stop = ExplorerAutreNoeud_relaxlin(listvars, listvals, listnodes)\n", - " end\n", - "\n", - " current_node_number = current_node_number + 1\n", + "# 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", "\n", - " println(\"\\n******\\n\\nOptimal value = \", BestProfit, \"\\n\\nOptimal x=\", Bestsol)\n", + "# 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", + " end\n", + " for i in 1:length(x)\n", + " ) <= capacity\n", "\n", - " return BestProfit, Bestsol, trParentnodes, trChildnodes, trNamenodes\n", + "\n", + "AllDef(x) =\n", + " for xi in x\n", + " if xi < 0\n", + " return false\n", + " end\n", " end\n", - "\n", - "end\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### Affichage du résultat final" - ] - }, - { - "cell_type": "code", - "execution_count": 55, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]\n", - "Subject to\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", - " x[4] ≥ 0.0\n", - " x[1] ≤ 1.0\n", - " x[2] ≤ 1.0\n", - " x[3] ≤ 1.0\n", - " x[4] ≤ 1.0\n", - "\n", - "\n", - "Node number 0: \n", - "-----\n", - "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]\n", - "Subject to\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", - " x[4] ≥ 0.0\n", - " x[1] ≤ 1.0\n", - " x[2] ≤ 1.0\n", - " x[3] ≤ 1.0\n", - " x[4] ≤ 1.0\n", - "\n", - "Solve model2 to compute the bounds of the current node: start ... ... end\n", - "\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 Any[] with bestprofit -1\n", - "\n", - "non sondable\n", - "\n", - "Node number 1: \n", - "-----\n", - "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]\n", - "Subject to\n", - " 7 x[1] + 4 x[2] + 3 x[3] + 5 x[4] ≤ 10.0\n", - " x[1] ≥ 1.0\n", - " x[2] ≥ 0.0\n", - " x[3] ≥ 0.0\n", - " x[4] ≥ 0.0\n", - " x[1] ≤ 1.0\n", - " x[2] ≤ 1.0\n", - " x[3] ≤ 1.0\n", - " x[4] ≤ 1.0\n", - "\n", - "Solve model2 to compute the bounds of the current node: start ... ... end\n", - "\n", - "Solution relax lin\tx[1]=1.0\tx[2]=0.7500000000000001\tx[3]=0.0\tx[4]=0.0 \n", - "\n", - "Previous Solution memorized Any[] with bestprofit -1\n", - "\n", - "non sondable\n", - "\n", - "Node number 2: \n", - "-----\n", - "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]\n", - "Subject to\n", - " 7 x[1] + 4 x[2] + 3 x[3] + 5 x[4] ≤ 10.0\n", - " x[1] ≥ 1.0\n", - " x[2] ≥ 1.0\n", - " x[3] ≥ 0.0\n", - " x[4] ≥ 0.0\n", - " x[1] ≤ 1.0\n", - " x[2] ≤ 1.0\n", - " x[3] ≤ 1.0\n", - " x[4] ≤ 1.0\n", - "\n", - "Solve model2 to compute the bounds of the current node: start ... ... end\n", - "\n", - "Solution relax lin : NOT AVAILABLE (probably infeasible or ressources limit reached) \n", - "\n", - "Previous Solution memorized Any[] with bestprofit -1\n", - "\n", - "TA\n", - "\n", - "Node number 3: \n", - "-----\n", - "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]\n", - "Subject to\n", - " 7 x[1] + 4 x[2] + 3 x[3] + 5 x[4] ≤ 10.0\n", - " x[1] ≥ 1.0\n", - " x[2] ≥ 0.0\n", - " x[3] ≥ 0.0\n", - " x[4] ≥ 0.0\n", - " x[1] ≤ 1.0\n", - " x[2] ≤ 0.0\n", - " x[3] ≤ 1.0\n", - " x[4] ≤ 1.0\n", - "\n", - "Solve model2 to compute the bounds of the current node: start ... ... end\n", - "\n", - "Solution relax lin\tx[1]=1.0\tx[2]=0.0\tx[3]=0.0\tx[4]=0.6 \n", - "\n", - "Previous Solution memorized Any[] with bestprofit -1\n", - "\n", - "non sondable\n", - "\n", - "Node number 4: \n", - "-----\n", - "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]\n", - "Subject to\n", - " 7 x[1] + 4 x[2] + 3 x[3] + 5 x[4] ≤ 10.0\n", - " x[1] ≥ 1.0\n", - " x[2] ≥ 0.0\n", - " x[3] ≥ 0.0\n", - " x[4] ≥ 1.0\n", - " x[1] ≤ 1.0\n", - " x[2] ≤ 0.0\n", - " x[3] ≤ 1.0\n", - " x[4] ≤ 1.0\n", - "\n", - "Solve model2 to compute the bounds of the current node: start ... ... end\n", - "\n", - "Solution relax lin : NOT AVAILABLE (probably infeasible or ressources limit reached) \n", - "\n", - "Previous Solution memorized Any[] with bestprofit -1\n", - "\n", - "TA\n", - "\n", - "Node number 5: \n", - "-----\n", - "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]\n", - "Subject to\n", - " 7 x[1] + 4 x[2] + 3 x[3] + 5 x[4] ≤ 10.0\n", - " x[1] ≥ 1.0\n", - " x[2] ≥ 0.0\n", - " x[3] ≥ 0.0\n", - " x[4] ≥ 0.0\n", - " x[1] ≤ 1.0\n", - " x[2] ≤ 0.0\n", - " x[3] ≤ 1.0\n", - " x[4] ≤ 0.0\n", - "\n", - "Solve model2 to compute the bounds of the current node: start ... ... end\n", - "\n", - "Solution relax lin\tx[1]=1.0\tx[2]=0.0\tx[3]=1.0\tx[4]=0.0 \n", - "\n", - "Previous Solution memorized Any[] with bestprofit -1\n", - "\n", - "TR\n", - "\n", - "Node number 6: \n", - "-----\n", - "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]\n", - "Subject to\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", - " x[4] ≥ 0.0\n", - " x[1] ≤ 0.0\n", - " x[2] ≤ 1.0\n", - " x[3] ≤ 1.0\n", - " x[4] ≤ 1.0\n", - "\n", - "Solve model2 to compute the bounds of the current node: start ... ... end\n", - "\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 [1.0, 0.0, 1.0, 0.0] with bestprofit 54.0\n", - "\n", - "non sondable\n", - "\n", - "Node number 7: \n", - "-----\n", - "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]\n", - "Subject to\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] ≥ 1.0\n", - " x[4] ≥ 0.0\n", - " x[1] ≤ 0.0\n", - " x[2] ≤ 1.0\n", - " x[3] ≤ 1.0\n", - " x[4] ≤ 1.0\n", - "\n", - "Solve model2 to compute the bounds of the current node: start ... ... end\n", - "\n", - "Solution relax lin\tx[1]=0.0\tx[2]=1.0\tx[3]=1.0\tx[4]=0.6000000000000001 \n", - "\n", - "Previous Solution memorized [1.0, 0.0, 1.0, 0.0] with bestprofit 54.0\n", - "\n", - "non sondable\n", - "\n", - "Node number 8: \n", - "-----\n", - "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]\n", - "Subject to\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] ≥ 1.0\n", - " x[4] ≥ 1.0\n", - " x[1] ≤ 0.0\n", - " x[2] ≤ 1.0\n", - " x[3] ≤ 1.0\n", - " x[4] ≤ 1.0\n", - "\n", - "Solve model2 to compute the bounds of the current node: start ... ... end\n", - "\n", - "Solution relax lin\tx[1]=0.0\tx[2]=0.5\tx[3]=1.0\tx[4]=1.0 \n", - "\n", - "Previous Solution memorized [1.0, 0.0, 1.0, 0.0] with bestprofit 54.0\n", - "\n", - "non sondable\n", - "\n", - "Node number 9: \n", - "-----\n", - "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]\n", - "Subject to\n", - " 7 x[1] + 4 x[2] + 3 x[3] + 5 x[4] ≤ 10.0\n", - " x[1] ≥ 0.0\n", - " x[2] ≥ 1.0\n", - " x[3] ≥ 1.0\n", - " x[4] ≥ 1.0\n", - " x[1] ≤ 0.0\n", - " x[2] ≤ 1.0\n", - " x[3] ≤ 1.0\n", - " x[4] ≤ 1.0\n", - "\n", - "Solve model2 to compute the bounds of the current node: start ... ... end\n", - "\n", - "Solution relax lin : NOT AVAILABLE (probably infeasible or ressources limit reached) \n", - "\n", - "Previous Solution memorized [1.0, 0.0, 1.0, 0.0] with bestprofit 54.0\n", - "\n", - "TA\n", - "\n", - "Node number 10: \n", - "-----\n", - "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]\n", - "Subject to\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] ≥ 1.0\n", - " x[4] ≥ 1.0\n", - " x[1] ≤ 0.0\n", - " x[2] ≤ 0.0\n", - " x[3] ≤ 1.0\n", - " x[4] ≤ 1.0\n", - "\n", - "Solve model2 to compute the bounds of the current node: start ... ... end\n", - "\n", - "Solution relax lin\tx[1]=0.0\tx[2]=0.0\tx[3]=1.0\tx[4]=1.0 \n", - "\n", - "Previous Solution memorized [1.0, 0.0, 1.0, 0.0] with bestprofit 54.0\n", - "\n", - "TO\n", - "\n", - "Node number 11: \n", - "-----\n", - "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]\n", - "Subject to\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] ≥ 1.0\n", - " x[4] ≥ 0.0\n", - " x[1] ≤ 0.0\n", - " x[2] ≤ 1.0\n", - " x[3] ≤ 1.0\n", - " x[4] ≤ 0.0\n", - "\n", - "Solve model2 to compute the bounds of the current node: start ... ... end\n", - "\n", - "Solution relax lin\tx[1]=0.0\tx[2]=1.0\tx[3]=1.0\tx[4]=0.0 \n", - "\n", - "Previous Solution memorized [1.0, 0.0, 1.0, 0.0] with bestprofit 54.0\n", - "\n", - "TO\n", - "\n", - "Node number 12: \n", - "-----\n", - "Max 42 x[1] + 40 x[2] + 12 x[3] + 25 x[4]\n", - "Subject to\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", - " x[4] ≥ 0.0\n", - " x[1] ≤ 0.0\n", - " x[2] ≤ 1.0\n", - " x[3] ≤ 0.0\n", - " x[4] ≤ 1.0\n", - "\n", - "Solve model2 to compute the bounds of the current node: start ... ... end\n", - "\n", - "Solution relax lin\tx[1]=0.0\tx[2]=1.0\tx[3]=0.0\tx[4]=1.0 \n", - "\n", - "Previous Solution memorized [1.0, 0.0, 1.0, 0.0] with bestprofit 54.0\n", - "\n", - "TR\n", - "\n", - "FINISHED\n", - "\n", - "******\n", - "\n", - "Optimal value = 65.0\n", - "\n", - "Optimal x=[0.0, 1.0, 0.0, 1.0]\n", - "\n", - "******\n", - "\n", - "Optimal value = 65.0\n", - "\n", - "Optimal x=[0.0, 1.0, 0.0, 1.0]\n" - ] - }, - { - "data": { - "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" - }, - "execution_count": 55, - "metadata": {}, - "output_type": "execute_result" - } - ], - "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)" + " return true" ] } ],