{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# TP 2-3 : Branch-and-bound applied to a knapsack problem" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Initialisation (à faire une seule fois)" ] }, { "cell_type": "code", "execution_count": 48, "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", "\u001b[32m\u001b[1m Resolving\u001b[22m\u001b[39m package versions...\n", "\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.6/Project.toml`\n", "\u001b[32m\u001b[1m No Changes\u001b[22m\u001b[39m to `~/.julia/environments/v1.6/Manifest.toml`\n" ] } ], "source": [ "import Pkg; \n", "Pkg.add(\"GraphRecipes\"); Pkg.add(\"Plots\"); \n", "using GraphRecipes, Plots #only used to visualize the search tree at the end of the branch-and-bound" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Récupération des données" ] }, { "cell_type": "code", "execution_count": 49, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "readKnaptxtInstance (generic function with 1 method)" ] }, "execution_count": 49, "metadata": {}, "output_type": "execute_result" } ], "source": [ "function readKnaptxtInstance(filename)\n", " price=[]\n", " weight=[]\n", " KnapCap=[]\n", " open(filename) do f\n", " for i in 1:3\n", " tok = split(readline(f))\n", " if (tok[1] == \"ListPrices=\")\n", " for i in 2:(length(tok)-1)\n", " push!(price,parse(Int64, tok[i]))\n", " end\n", " 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", " else\n", " println(\"Unknown read :\", tok)\n", " end \n", " end\n", " end\n", " capacity=KnapCap[1]\n", " return price, weight, capacity\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Procédure d'application des tests de sondabilités TA, TO et TR pour le cas de la relaxation linéaire" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "TestsSondabilite_relaxlin (generic function with 1 method)" ] }, "execution_count": 50, "metadata": {}, "output_type": "execute_result" } ], "source": [ "function TestsSondabilite_relaxlin(model2, x, varsbin, BestProfit, Bestsol)\n", " TA, TO, TR = false, false, false\n", " if (termination_status(model2) == MOI.INFEASIBLE)#Test de faisabilite\n", " TA=true\n", " println(\"TA\")\n", " elseif (objective_value(model2) <= 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", " println(\"TR\")\n", " #if (value(benef) >= BestProfit)\n", " if (objective_value(model2) >= BestProfit)\n", " Bestsol = value.(x)\n", " #BestProfit=value(benef)\n", " BestProfit=objective_value(model2)\n", " end\n", " else\n", " println(\"non sondable\")\n", " end\n", " TA, TO, TR, Bestsol, BestProfit\n", "end" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Procédure de séparation et stratégie d'exploration permettant de se placer au prochain noeud à traiter" ] }, { "cell_type": "code", "execution_count": 51, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "ExplorerAutreNoeud_relaxlin (generic function with 1 method)" ] }, "execution_count": 51, "metadata": {}, "output_type": "execute_result" } ], "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", " \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", " 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", " listvars, listvals\n", "end\n", "\n", "\n", "function ExplorerAutreNoeud_relaxlin(listvars, listvals, listnodes)\n", " #this node is sondable, go back to parent node then right child if possible\n", " \n", " stop=false\n", " #check if we are not at the root node\n", " if (length(listvars)>= 1)\n", " #go back to parent node\n", " var=pop!(listvars)\n", " theval=pop!(listvals)\n", " tmp=pop!(listnodes)\n", " set_lower_bound(var,0.0)\n", " set_upper_bound(var,1.0)\n", "\n", " #go to right child if possible, otherwise go back to parent\n", " while ( (theval==0.0) && (length(listvars)>= 1))\n", " var=pop!(listvars)\n", " theval=pop!(listvals)\n", " tmp=pop!(listnodes)\n", " set_lower_bound(var,0.0) \n", " set_upper_bound(var,1.0)\n", " end\n", " if theval==1.0\n", " set_lower_bound(var,0.0)\n", " set_upper_bound(var,0.0)\n", " push!(listvars,var)\n", " push!(listvals,0.0)\n", " else\n", " println(\"\\nFINISHED\")\n", " stop=true\n", " end\n", " else\n", " #the root node was sondable\n", " println(\"\\nFINISHED\")\n", " stop=true\n", " end\n", " listvars, listvals, listnodes, stop \n", "end" ] }, { "cell_type": "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, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "CreationModeleLP (generic function with 1 method)" ] }, "execution_count": 53, "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", " end\n", "\n", " println(\"\\n******\\n\\nOptimal value = \", BestProfit, \"\\n\\nOptimal x=\", Bestsol)\n", "\n", " return BestProfit, Bestsol, trParentnodes, trChildnodes, trNamenodes\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)" ] } ], "metadata": { "kernelspec": { "display_name": "Julia 1.6.3", "language": "julia", "name": "julia-1.6" }, "language_info": { "file_extension": ".jl", "mimetype": "application/julia", "name": "julia", "version": "1.6.3" } }, "nbformat": 4, "nbformat_minor": 4 }