TP-recherche-operationnelle/notebook.ipynb

768 lines
51 KiB
Plaintext
Raw Normal View History

2021-11-26 13:51:01 +00:00
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# TP 2-3 : Branch-and-bound applied to a knapsack problem"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Initialisation (à faire une seule fois)"
]
},
{
"cell_type": "code",
"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): <span style=\"color:red\"> SECTION A SUPPRIMER !!!! </span>\n",
"\n",
"<span style=\"color:red\"> 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 </span>"
]
},
{
"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": "<?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=\"clip990\">\n <rect x=\"0\" y=\"0\" width=\"2400\" height=\"1600\"/>\n </clipPath>\n</defs>\n<path clip-path=\"url(#clip990)\" d=\"\nM0 1600 L2400 1600 L2400 0 L0 0 Z\n \" fill=\"#ffffff\" fill-rule=\"evenodd\" fill-opacity=\"1\"/>\n<defs>\n <clipPath id=\"clip991\">\n <rect x=\"480\" y=\"0\" width=\"1681\" height=\"1600\"/>\n </clipPath>\n</defs>\n<path clip-path=\"url(#clip990)\" 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=\"clip992\">\n <rect x=\"447\" y=\"47\" width=\"1507\" height=\"1507\"/>\n </clipPath>\n</defs>\n<polyline clip-path=\"url(#clip992)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 1206.87,262.317 1206.11,271.046 1203.92,279.317 1200.39,287.164 1195.64,294.623 1189.77,301.725 1182.88,308.506 1175.09,314.998 1166.5,321.237 1157.22,327.255 \n 1147.35,333.087 1137,338.766 1126.28,344.327 1115.29,349.804 1104.14,355.229 1092.94,360.638 1081.79,366.063 1070.8,371.539 1060.08,377.1 1049.73,382.78 \n 1039.86,388.612 1030.57,394.63 1021.98,400.869 1014.19,407.361 1007.31,414.142 1001.44,421.244 996.683,428.702 993.156,436.55 990.962,444.821 990.207,453.55 \n \n \"/>\n<polyline clip-path=\"url(#clip992)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 990.207,453.55 990.303,464.517 990.58,475.71 991.027,487.11 991.628,498.703 992.371,510.471 993.242,522.397 994.228,534.464 995.315,546.657 996.49,558.958 \n 997.739,571.351 999.049,583.819 1000.41,596.345 1001.8,608.913 1003.21,621.505 1004.62,634.107 1006.04,646.699 1007.43,659.267 1008.78,671.793 1010.09,684.261 \n 1011.34,696.654 1012.52,708.955 1013.6,721.148 1014.59,733.215 1015.46,745.141 1016.2,756.909 1016.81,768.501 1017.25,779.902 1017.53,791.095 1017.63,802.062 \n \n \"/>\n<polyline clip-path=\"url(#clip992)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 990.207,453.55 989.616,464.256 987.897,474.896 985.136,485.477 981.414,496.001 976.816,506.475 971.425,516.903 965.324,527.29 958.597,537.64 951.327,547.959 \n 943.599,558.252 935.494,568.522 927.098,578.776 918.493,589.018 909.762,599.252 900.99,609.484 892.26,619.718 883.654,629.96 875.258,640.214 867.154,650.484 \n 859.425,660.777 852.155,671.096 845.428,681.446 839.328,691.833 833.936,702.261 829.338,712.734 825.616,723.259 822.855,733.839 821.136,744.48 820.545,755.186 \n \n \"/>\n<polyline clip-path=\"url(#clip992)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 820.545,755.186 819.994,764.197 818.391,773.092 815.816,781.882 812.345,790.573 808.056,799.175 803.028,807.696 797.339,816.145 791.065,824.529 784.285,832.859 \n 777.078,841.141 769.52,849.386 761.689,857.6 753.664,865.794 745.522,873.974 737.341,882.15 729.199,890.331 721.173,898.524 713.343,906.739 705.785,914.983 \n 698.577,923.265 691.797,931.595 685.524,939.98 679.834,948.428 674.806,956.949 670.518,965.551 667.047,974.243 664.471,983.032 662.869,991.928 662.317,1000.94 \n \n \"/>\n<polyline clip-path=\"url(#clip992)\" style=\"stroke:#000000; stroke-linecap:butt; stroke-linejoin:round; stroke-width:4; stroke-opacity:1; fill:none\" points=\"\n 820.545,755.186 820.492,762.912 820.337,770.798 820.087,778.832 819.751,787.003 819.336,795.299 818.849,803.708 818.298,812.217 817.69,820.816 817.034,829.492 \n 816.336,838.233 815.604,847.028 814.846,855.864 814.069,864.73 813.28,873.614 812.488,882.504 811.7,891.388 810.923,900.254 810.164,909.09 809.433,917.885 \n 808.735,926.626 808.078,935.302 807.471,943.901 806.92,952.411 806.433,
},
"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
}