Knapsack problem/Bounded: Difference between revisions
Content added Content deleted
(Knapsack problem/Bounded in FreeBASIC) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 82: | Line 82: | ||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="11l">V items = [ |
||
‘sandwich’ = (50, 60, 2), |
‘sandwich’ = (50, 60, 2), |
||
‘map’ = (9, 150, 1), |
‘map’ = (9, 150, 1), |
||
Line 142: | Line 142: | ||
w += items[name][0] * cnt |
w += items[name][0] * cnt |
||
print(‘Total weight: ’w‘ Value: ’v)</ |
print(‘Total weight: ’w‘ Value: ’v)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 162: | Line 162: | ||
=={{header|AutoHotkey}}== |
=={{header|AutoHotkey}}== |
||
iterative dynamic programming solution |
iterative dynamic programming solution |
||
< |
<syntaxhighlight lang="autohotkey">Item = map,compass,water,sandwich,glucose,tin,banana,apple,cheese,beer,suntan cream |
||
,camera,tshirt,trousers,umbrella,waterproof trousers,waterproof overclothes,notecase |
,camera,tshirt,trousers,umbrella,waterproof trousers,waterproof overclothes,notecase |
||
,sunglasses,towel,socks,book |
,sunglasses,towel,socks,book |
||
Line 198: | Line 198: | ||
} |
} |
||
MsgBox % "Value = " m%N%_%W% "`nWeight = " s "`n`n" t</ |
MsgBox % "Value = " m%N%_%W% "`nWeight = " s "`n`n" t</syntaxhighlight> |
||
=={{header|Bracmat}}== |
=={{header|Bracmat}}== |
||
< |
<syntaxhighlight lang="bracmat">(knapsack= |
||
( things |
( things |
||
= (map.9.150.1) |
= (map.9.150.1) |
||
Line 274: | Line 274: | ||
); |
); |
||
!knapsack;</ |
!knapsack;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> 1010 |
<pre> 1010 |
||
Line 291: | Line 291: | ||
=={{header|C}}== |
=={{header|C}}== |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
Line 375: | Line 375: | ||
return 0; |
return 0; |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{output}} |
{{output}} |
||
Line 393: | Line 393: | ||
=={{header|C sharp|C#}}== |
=={{header|C sharp|C#}}== |
||
Similar to Knapsack/0-1. |
Similar to Knapsack/0-1. |
||
< |
<syntaxhighlight lang="csharp">using System; // 4790@3.6 |
||
class program |
class program |
||
{ |
{ |
||
Line 466: | Line 466: | ||
items = pItems; |
items = pItems; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C++}}== |
=={{header|C++}}== |
||
C++ DP solution. Initially taken from C but than fixed and refactored.<br> |
C++ DP solution. Initially taken from C but than fixed and refactored.<br> |
||
Remark: The above comment implies there is a bug in the C code, but refers to a much older and very different version [[User:Petelomax|Pete Lomax]] ([[User talk:Petelomax|talk]]) 19:28, 20 March 2017 (UTC) |
Remark: The above comment implies there is a bug in the C code, but refers to a much older and very different version [[User:Petelomax|Pete Lomax]] ([[User talk:Petelomax|talk]]) 19:28, 20 March 2017 (UTC) |
||
< |
<syntaxhighlight lang="cpp">#include <iostream> |
||
#include <vector> |
#include <vector> |
||
#include <algorithm> |
#include <algorithm> |
||
Line 706: | Line 706: | ||
cout << "Weight: " << solution.w << " Value: " << solution.v << endl; |
cout << "Weight: " << solution.w << " Value: " << solution.v << endl; |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Clojure}}== |
=={{header|Clojure}}== |
||
We convert the problem to a Knapsack-0/1 problem by replacing (n-max item) vith n-max identical occurences of 1 item. |
We convert the problem to a Knapsack-0/1 problem by replacing (n-max item) vith n-max identical occurences of 1 item. |
||
Adapted Knapsack-0/1 problem solution from [https://www.rosettacode.org/wiki/Knapsack_problem/0-1#Clojure] |
Adapted Knapsack-0/1 problem solution from [https://www.rosettacode.org/wiki/Knapsack_problem/0-1#Clojure] |
||
< |
<syntaxhighlight lang="lisp">(ns knapsack |
||
(:gen-class)) |
(:gen-class)) |
||
Line 771: | Line 771: | ||
(println "Total value:" value) |
(println "Total value:" value) |
||
(println "Total weight:" (reduce + (map (comp :weight items) indexes)))) |
(println "Total weight:" (reduce + (map (comp :weight items) indexes)))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{Output}} |
{{Output}} |
||
<pre> |
<pre> |
||
Line 791: | Line 791: | ||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
< |
<syntaxhighlight lang="lisp">;;; memoize |
||
(defmacro mm-set (p v) `(if ,p ,p (setf ,p ,v))) |
(defmacro mm-set (p v) `(if ,p ,p (setf ,p ,v))) |
||
Line 824: | Line 824: | ||
(T-shirt 24 15 2) (trousers 48 10 2) (umbrella 73 40 1) |
(T-shirt 24 15 2) (trousers 48 10 2) (umbrella 73 40 1) |
||
(trousers 42 70 1) (overclothes 43 75 1) (notecase 22 80 1) |
(trousers 42 70 1) (overclothes 43 75 1) (notecase 22 80 1) |
||
(glasses 7 20 1) (towel 18 12 2) (socks 4 50 1) (book 30 10 2))))</ |
(glasses 7 20 1) (towel 18 12 2) (socks 4 50 1) (book 30 10 2))))</syntaxhighlight> |
||
=={{header|Crystal}}== |
=={{header|Crystal}}== |
||
==== Branch and Bound solution ==== |
==== Branch and Bound solution ==== |
||
< |
<syntaxhighlight lang="ruby">record Item, name : String, weight : Int32, value : Int32, count : Int32 |
||
record Selection, mask : Array(Int32), cur_index : Int32, total_value : Int32 |
record Selection, mask : Array(Int32), cur_index : Int32, total_value : Int32 |
||
Line 904: | Line 904: | ||
puts "total weight #{used.sum { |item, count| item.weight*count }}" |
puts "total weight #{used.sum { |item, count| item.weight*count }}" |
||
puts "total value #{used.sum { |item, count| item.value*count }}" |
puts "total value #{used.sum { |item, count| item.value*count }}" |
||
puts "checked nodes: #{solver.checked_nodes}"</ |
puts "checked nodes: #{solver.checked_nodes}"</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>optimal choice: map, socks, suntan cream, 2x glucose, note-case, sunglasses, compass, 3x banana, waterproof overclothes, water, cheese |
<pre>optimal choice: map, socks, suntan cream, 2x glucose, note-case, sunglasses, compass, 3x banana, waterproof overclothes, water, cheese |
||
Line 914: | Line 914: | ||
==== Dynamic programming solution ==== |
==== Dynamic programming solution ==== |
||
{{trans|Ruby}} |
{{trans|Ruby}} |
||
< |
<syntaxhighlight lang="ruby"># Item struct to represent each item in the problem |
||
record Item, name : String, weight : Int32, value : Int32, count : Int32 |
record Item, name : String, weight : Int32, value : Int32, count : Int32 |
||
Line 973: | Line 973: | ||
end |
end |
||
p "Total weight: #{w}, Value: #{val}"</ |
p "Total weight: #{w}, Value: #{val}"</syntaxhighlight> |
||
=={{header|D}}== |
=={{header|D}}== |
||
{{trans|Python}} |
{{trans|Python}} |
||
Solution with memoization. |
Solution with memoization. |
||
< |
<syntaxhighlight lang="d">import std.stdio, std.typecons, std.functional; |
||
immutable struct Item { |
immutable struct Item { |
||
Line 1,034: | Line 1,034: | ||
writeln("Total weight: ", w, " Value: ", v_lst[0]); |
writeln("Total weight: ", w, " Value: ", v_lst[0]); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>1 map |
<pre>1 map |
||
Line 1,051: | Line 1,051: | ||
=={{header|EchoLisp}}== |
=={{header|EchoLisp}}== |
||
We convert the problem to a Knapsack-0/1 problem by replacing (n-max item) vith n-max identical occurences of 1 item. |
We convert the problem to a Knapsack-0/1 problem by replacing (n-max item) vith n-max identical occurences of 1 item. |
||
< |
<syntaxhighlight lang="scheme"> |
||
(lib 'struct) |
(lib 'struct) |
||
(lib 'sql) |
(lib 'sql) |
||
Line 1,107: | Line 1,107: | ||
(name i)))) |
(name i)))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
< |
<syntaxhighlight lang="scheme"> |
||
(define goodies |
(define goodies |
||
'((map 9 150 1) (compass 13 35 1)(water 153 200 3) |
'((map 9 150 1) (compass 13 35 1)(water 153 200 3) |
||
Line 1,129: | Line 1,129: | ||
(length (hash-keys H)) |
(length (hash-keys H)) |
||
→ 10827 ;; # of entries in cache |
→ 10827 ;; # of entries in cache |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
< |
<syntaxhighlight lang="freebasic">#define PesoMax 400 |
||
#define items 22 |
#define items 22 |
||
#define Tabu Chr(9) |
#define Tabu Chr(9) |
||
Line 1,192: | Line 1,192: | ||
Print !"\nTotal value: "; TValor |
Print !"\nTotal value: "; TValor |
||
Print "Total weight: "; PesoMax + TPeso |
Print "Total weight: "; PesoMax + TPeso |
||
Sleep</ |
Sleep</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Knapsack contents: |
<pre>Knapsack contents: |
||
Line 1,213: | Line 1,213: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
Solution with caching. |
Solution with caching. |
||
< |
<syntaxhighlight lang="go">package main |
||
import "fmt" |
import "fmt" |
||
Line 1,311: | Line 1,311: | ||
} |
} |
||
fmt.Printf("Value: %d; weight: %d\n", v, w) |
fmt.Printf("Value: %d; weight: %d\n", v, w) |
||
}</ |
}</syntaxhighlight> |
||
(A simple test and benchmark used while making changes to make sure performance wasn't sacrificed is available at [[/Go_test]].) |
(A simple test and benchmark used while making changes to make sure performance wasn't sacrificed is available at [[/Go_test]].) |
||
{{out}} |
{{out}} |
||
Line 1,330: | Line 1,330: | ||
=={{header|Groovy}}== |
=={{header|Groovy}}== |
||
Solution: dynamic programming |
Solution: dynamic programming |
||
< |
<syntaxhighlight lang="groovy">def totalWeight = { list -> list.collect{ it.item.weight * it.count }.sum() } |
||
def totalValue = { list -> list.collect{ it.item.value * it.count }.sum() } |
def totalValue = { list -> list.collect{ it.item.value * it.count }.sum() } |
||
Line 1,347: | Line 1,347: | ||
} |
} |
||
m[n][400] |
m[n][400] |
||
}</ |
}</syntaxhighlight> |
||
Test: |
Test: |
||
< |
<syntaxhighlight lang="groovy">def items = [ |
||
[name:"map", weight: 9, value:150, pieces:1], |
[name:"map", weight: 9, value:150, pieces:1], |
||
[name:"compass", weight: 13, value: 35, pieces:1], |
[name:"compass", weight: 13, value: 35, pieces:1], |
||
Line 1,384: | Line 1,384: | ||
printf (' item: %-22s weight:%4d value:%4d count:%2d\n', |
printf (' item: %-22s weight:%4d value:%4d count:%2d\n', |
||
it.item.name, it.item.weight, it.item.value, it.count) |
it.item.name, it.item.weight, it.item.value, it.count) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Elapsed Time: 0.603 s |
<pre>Elapsed Time: 0.603 s |
||
Line 1,403: | Line 1,403: | ||
=={{header|Haskell}}== |
=={{header|Haskell}}== |
||
Directly lifted from 1-0 problem: |
Directly lifted from 1-0 problem: |
||
< |
<syntaxhighlight lang="haskell">inv = [("map",9,150,1), ("compass",13,35,1), ("water",153,200,2), ("sandwich",50,60,2), |
||
("glucose",15,60,2), ("tin",68,45,3), ("banana",27,60,3), ("apple",39,40,3), |
("glucose",15,60,2), ("tin",68,45,3), ("banana",27,60,3), ("apple",39,40,3), |
||
("cheese",23,30,1), ("beer",52,10,3), ("cream",11,70,1), ("camera",32,30,1), |
("cheese",23,30,1), ("beer",52,10,3), ("cream",11,70,1), ("camera",32,30,1), |
||
Line 1,417: | Line 1,417: | ||
new = map (\(val,itms)->(val + v * i, (name,i):itms)) old |
new = map (\(val,itms)->(val + v * i, (name,i):itms)) old |
||
main = print $ (knapsack inv) !! 400</ |
main = print $ (knapsack inv) !! 400</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,424: | Line 1,424: | ||
</pre> |
</pre> |
||
The above uses merging lists for cache. It's faster, and maybe easier to understand when some constant-time lookup structure is used for cache (same output): |
The above uses merging lists for cache. It's faster, and maybe easier to understand when some constant-time lookup structure is used for cache (same output): |
||
< |
<syntaxhighlight lang="haskell">import Data.Array |
||
-- snipped the item list; use the one from above |
-- snipped the item list; use the one from above |
||
Line 1,434: | Line 1,434: | ||
prepend (x,n) (y,s) = (x+y,n:s) |
prepend (x,n) (y,s) = (x+y,n:s) |
||
main = do print $ knapsack inv 400</ |
main = do print $ knapsack inv 400</syntaxhighlight> |
||
=={{header|J}}== |
=={{header|J}}== |
||
Brute force solution: |
Brute force solution: |
||
< |
<syntaxhighlight lang="j">'names numbers'=:|:".;._2]0 :0 |
||
'map'; 9 150 1 |
'map'; 9 150 1 |
||
'compass'; 13 35 1 |
'compass'; 13 35 1 |
||
Line 1,487: | Line 1,487: | ||
bestCombo'' |
bestCombo'' |
||
978832641</ |
978832641</syntaxhighlight> |
||
Interpretation of answer: |
Interpretation of answer: |
||
< |
<syntaxhighlight lang="j"> decode 978832641 |
||
1 1 1 0 2 0 3 0 1 0 1 0 0 0 0 0 1 1 1 0 1 0 |
1 1 1 0 2 0 3 0 1 0 1 0 0 0 0 0 1 1 1 0 1 0 |
||
(0<decode 978832641) # (":,.decode 978832641),.' ',.names |
(0<decode 978832641) # (":,.decode 978832641),.' ',.names |
||
Line 1,506: | Line 1,506: | ||
396 |
396 |
||
values +/ .* decode 978832641 |
values +/ .* decode 978832641 |
||
1010</ |
1010</syntaxhighlight> |
||
Dynamic programming solution (faster): |
Dynamic programming solution (faster): |
||
< |
<syntaxhighlight lang="j">dyn=:3 :0 |
||
m=. 0$~1+400,+/pieces NB. maximum value cache |
m=. 0$~1+400,+/pieces NB. maximum value cache |
||
b=. m NB. best choice cache |
b=. m NB. best choice cache |
||
Line 1,534: | Line 1,534: | ||
dyn'' |
dyn'' |
||
1 1 1 0 2 0 3 0 1 0 1 0 0 0 0 0 1 1 1 0 1 0</ |
1 1 1 0 2 0 3 0 1 0 1 0 0 0 0 0 1 1 1 0 1 0</syntaxhighlight> |
||
Note: the brute force approach would return multiple "best answers" if more than one combination of choices would satisfy the "best" constraint. The dynamic approach arbitrarily picks one of those choices. That said, with this particular choice of item weights and values, this is an irrelevant distinction. |
Note: the brute force approach would return multiple "best answers" if more than one combination of choices would satisfy the "best" constraint. The dynamic approach arbitrarily picks one of those choices. That said, with this particular choice of item weights and values, this is an irrelevant distinction. |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
General dynamic solution after [[wp:Knapsack_problem#0-1_knapsack_problem|wikipedia]]. The solution extends the method of [[Knapsack problem/0-1#Java ]]. |
General dynamic solution after [[wp:Knapsack_problem#0-1_knapsack_problem|wikipedia]]. The solution extends the method of [[Knapsack problem/0-1#Java ]]. |
||
< |
<syntaxhighlight lang="java">package hu.pj.alg.test; |
||
import hu.pj.alg.BoundedKnapsack; |
import hu.pj.alg.BoundedKnapsack; |
||
Line 1,621: | Line 1,621: | ||
new BoundedKnapsackForTourists(); |
new BoundedKnapsackForTourists(); |
||
} |
} |
||
} // class</ |
} // class</syntaxhighlight> |
||
< |
<syntaxhighlight lang="java">package hu.pj.alg; |
||
import hu.pj.obj.Item; |
import hu.pj.obj.Item; |
||
Line 1,684: | Line 1,684: | ||
setInitialStateForCalculation(); |
setInitialStateForCalculation(); |
||
} |
} |
||
} // class</ |
} // class</syntaxhighlight> |
||
< |
<syntaxhighlight lang="java">package hu.pj.alg; |
||
import hu.pj.obj.Item; |
import hu.pj.obj.Item; |
||
Line 1,836: | Line 1,836: | ||
solutionWeight = 0; |
solutionWeight = 0; |
||
} |
} |
||
} // class</ |
} // class</syntaxhighlight> |
||
< |
<syntaxhighlight lang="java">package hu.pj.obj; |
||
public class Item { |
public class Item { |
||
Line 1,905: | Line 1,905: | ||
public int getInKnapsack() {return inKnapsack;} |
public int getInKnapsack() {return inKnapsack;} |
||
public int getBounding() {return bounding;} |
public int getBounding() {return bounding;} |
||
} // class</ |
} // class</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,928: | Line 1,928: | ||
=={{header|JavaScript}}== |
=={{header|JavaScript}}== |
||
Based on the (dynamic) J implementation. Expressed as an htm page: |
Based on the (dynamic) J implementation. Expressed as an htm page: |
||
< |
<syntaxhighlight lang="javascript"><html><head><title></title></head><body></body></html> |
||
<script type="text/javascript"> |
<script type="text/javascript"> |
||
Line 2,006: | Line 2,006: | ||
} |
} |
||
findBestPack(); |
findBestPack(); |
||
</script></ |
</script></syntaxhighlight> |
||
This will generate (translating html to mediawiki markup): |
This will generate (translating html to mediawiki markup): |
||
{| |
{| |
||
Line 2,077: | Line 2,077: | ||
'''Works with gojq, the Go implementation of jq''' |
'''Works with gojq, the Go implementation of jq''' |
||
< |
<syntaxhighlight lang="jq"># Item {name, weight, value, count} |
||
def Item($name; $weight; $value; $count): {$name, $weight, $value, $count}; |
def Item($name; $weight; $value; $count): {$name, $weight, $value, $count}; |
||
Line 2,165: | Line 2,165: | ||
task(400) |
task(400) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,191: | Line 2,191: | ||
'''Type and Function''': |
'''Type and Function''': |
||
< |
<syntaxhighlight lang="julia">using MathProgBase, Cbc |
||
struct KPDSupply{T<:Integer} |
struct KPDSupply{T<:Integer} |
||
Line 2,219: | Line 2,219: | ||
return pack |
return pack |
||
end |
end |
||
end</ |
end</syntaxhighlight> |
||
'''Main''': |
'''Main''': |
||
< |
<syntaxhighlight lang="julia">gear = [KPDSupply("map", 9, 150, 1), |
||
KPDSupply("compass", 13, 35, 1), |
KPDSupply("compass", 13, 35, 1), |
||
KPDSupply("water", 153, 200, 2), |
KPDSupply("water", 153, 200, 2), |
||
Line 2,248: | Line 2,248: | ||
println("The hiker should pack: \n - ", join(pack, "\n - ")) |
println("The hiker should pack: \n - ", join(pack, "\n - ")) |
||
println("\nPacked weight: ", sum(getfield.(pack, :weight)), " kg") |
println("\nPacked weight: ", sum(getfield.(pack, :weight)), " kg") |
||
println("Packed value: ", sum(getfield.(pack, :value)), " €")</ |
println("Packed value: ", sum(getfield.(pack, :value)), " €")</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,269: | Line 2,269: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
{{trans|C}} |
{{trans|C}} |
||
< |
<syntaxhighlight lang="scala">// version 1.1.2 |
||
data class Item(val name: String, val weight: Int, val value: Int, val count: Int) |
data class Item(val name: String, val weight: Int, val value: Int, val count: Int) |
||
Line 2,350: | Line 2,350: | ||
println("--------------------- ------ ----- ------") |
println("--------------------- ------ ----- ------") |
||
println("Items chosen $itemCount ${"%3d".format(sumWeight)} ${"%4d".format(sumValue)} ${"%2d".format(sumNumber)}") |
println("Items chosen $itemCount ${"%3d".format(sumWeight)} ${"%4d".format(sumValue)} ${"%2d".format(sumNumber)}") |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,372: | Line 2,372: | ||
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
=={{header|Mathematica}}/{{header|Wolfram Language}}== |
||
< |
<syntaxhighlight lang="mathematica">Transpose@{#[[;; , 1]], |
||
LinearProgramming[-#[[;; , 3]], -{#[[;; , 2]]}, -{400}, |
LinearProgramming[-#[[;; , 3]], -{#[[;; , 2]]}, -{400}, |
||
{0, #[[4]]} & /@ #, Integers]} &@{{"map", 9, 150, 1}, |
{0, #[[4]]} & /@ #, Integers]} &@{{"map", 9, 150, 1}, |
||
Line 2,395: | Line 2,395: | ||
{"towel", 18, 12, 2}, |
{"towel", 18, 12, 2}, |
||
{"socks", 4, 50, 1}, |
{"socks", 4, 50, 1}, |
||
{"book", 30, 10, 2}}</ |
{"book", 30, 10, 2}}</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>{{"map", 1}, {"compass", 1}, {"water", 1}, {"sandwich", |
<pre>{{"map", 1}, {"compass", 1}, {"water", 1}, {"sandwich", |
||
Line 2,406: | Line 2,406: | ||
=={{header|Mathprog}}== |
=={{header|Mathprog}}== |
||
< |
<syntaxhighlight lang="mathprog">/*Knapsack |
||
This model finds the integer optimal packing of a knapsack |
This model finds the integer optimal packing of a knapsack |
||
Line 2,451: | Line 2,451: | ||
; |
; |
||
end;</ |
end;</syntaxhighlight> |
||
The solution produced using glpk is here: [[Knapsack problem/Bounded/Mathprog]] |
The solution produced using glpk is here: [[Knapsack problem/Bounded/Mathprog]] |
||
Line 2,460: | Line 2,460: | ||
=={{header|MiniZinc}}== |
=={{header|MiniZinc}}== |
||
<syntaxhighlight lang="minizinc"> |
|||
<lang MiniZinc> |
|||
%Solve Knapsack Problem Bounded. Nigel Galloway, Octoer 12th., 2020. |
%Solve Knapsack Problem Bounded. Nigel Galloway, Octoer 12th., 2020. |
||
enum Items={map,compass,water,sandwich,glucose,tin,banana,apple,cheese,beer,suntan_cream,camera,t_shirt,trousers,umbrella,waterproof_trousers,waterproof_overclothes,note_case,sunglasses,towel,socks,book}; |
enum Items={map,compass,water,sandwich,glucose,tin,banana,apple,cheese,beer,suntan_cream,camera,t_shirt,trousers,umbrella,waterproof_trousers,waterproof_overclothes,note_case,sunglasses,towel,socks,book}; |
||
Line 2,473: | Line 2,473: | ||
solve maximize wValue; |
solve maximize wValue; |
||
output[concat([let {string: g=show(take[n])} in "Take "++(if g==show(quantity[n]) then "all" else g endif)++" of \(n)\n" | n in Items where show(take[n])!="0"])++"\nTotal Weight=\(wTaken) Total Value="++show_float(4,2,wValue)] |
output[concat([let {string: g=show(take[n])} in "Take "++(if g==show(quantity[n]) then "all" else g endif)++" of \(n)\n" | n in Items where show(take[n])!="0"])++"\nTotal Weight=\(wTaken) Total Value="++show_float(4,2,wValue)] |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,492: | Line 2,492: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
We expand the list of items and apply the 0-1 algorithm. |
We expand the list of items and apply the 0-1 algorithm. |
||
< |
<syntaxhighlight lang="python"># Knapsack. Recursive solution. |
||
import strformat |
import strformat |
||
Line 2,600: | Line 2,600: | ||
echo "Total weight: ", weight |
echo "Total weight: ", weight |
||
echo "Total value: ", value |
echo "Total value: ", value |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 2,654: | Line 2,654: | ||
=={{header|OxygenBasic}}== |
=={{header|OxygenBasic}}== |
||
< |
<syntaxhighlight lang="oxygenbasic"> |
||
type KnapSackItem string name,sys dag,value,tag |
type KnapSackItem string name,sys dag,value,tag |
||
Line 2,765: | Line 2,765: | ||
' |
' |
||
'Weight: 396 |
'Weight: 396 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Oz}}== |
=={{header|Oz}}== |
||
Using constraint programming. |
Using constraint programming. |
||
< |
<syntaxhighlight lang="oz">declare |
||
%% maps items to tuples of |
%% maps items to tuples of |
||
%% Weight(hectogram), Value and available Pieces |
%% Weight(hectogram), Value and available Pieces |
||
Line 2,837: | Line 2,837: | ||
{System.printInfo "\n"} |
{System.printInfo "\n"} |
||
{System.showInfo "total value: "#{Value Best}} |
{System.showInfo "total value: "#{Value Best}} |
||
{System.showInfo "total weight: "#{Weight Best}}</ |
{System.showInfo "total weight: "#{Weight Best}}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,860: | Line 2,860: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
Recursive solution with caching. |
Recursive solution with caching. |
||
< |
<syntaxhighlight lang="perl">#!/usr/bin/perl |
||
use strict; |
use strict; |
||
Line 2,932: | Line 2,932: | ||
} |
} |
||
} |
} |
||
print "Value: $v; Weight: $w\n";</ |
print "Value: $v; Weight: $w\n";</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>1 of map |
<pre>1 of map |
||
Line 2,950: | Line 2,950: | ||
===Very dumb and very slow brute force version=== |
===Very dumb and very slow brute force version=== |
||
Of no practical use, except for comparison against improvements. |
Of no practical use, except for comparison against improvements. |
||
<!--< |
<!--<syntaxhighlight lang="phix">(phixonline)--> |
||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
||
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span> |
<span style="color: #004080;">atom</span> <span style="color: #000000;">t0</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">time</span><span style="color: #0000FF;">()</span> |
||
Line 3,016: | Line 3,016: | ||
<span style="color: #008080;">if</span> <span style="color: #000000;">points</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- sanity check</span> |
<span style="color: #008080;">if</span> <span style="color: #000000;">points</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">res</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span> <span style="color: #008080;">then</span> <span style="color: #0000FF;">?</span><span style="color: #000000;">9</span><span style="color: #0000FF;">/</span><span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span> <span style="color: #000080;font-style:italic;">-- sanity check</span> |
||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Value %d, weight %g [%3.2fs]\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">points</span><span style="color: #0000FF;">,</span><span style="color: #000000;">weight</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">})</span> |
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"Value %d, weight %g [%3.2fs]\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">points</span><span style="color: #0000FF;">,</span><span style="color: #000000;">weight</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">time</span><span style="color: #0000FF;">()-</span><span style="color: #000000;">t0</span><span style="color: #0000FF;">})</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,035: | Line 3,035: | ||
Much faster but limited to integer weights |
Much faster but limited to integer weights |
||
{{trans|C}} |
{{trans|C}} |
||
<!--< |
<!--<syntaxhighlight lang="phix">(phixonline)--> |
||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">items</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span> |
<span style="color: #004080;">sequence</span> <span style="color: #000000;">items</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span> |
||
Line 3,113: | Line 3,113: | ||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span> |
||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%-22s %5d %5d %5d\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"count, weight, points:"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tc</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tw</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tv</span><span style="color: #0000FF;">})</span> |
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%-22s %5d %5d %5d\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #008000;">"count, weight, points:"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tc</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tw</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">tv</span><span style="color: #0000FF;">})</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,135: | Line 3,135: | ||
duplicate solutions for w=15.783, 15.784, 15.785, and everything in between. |
duplicate solutions for w=15.783, 15.784, 15.785, and everything in between. |
||
Using a (bespoke) range cache solves this problem, although the simplistic version given could probably be improved with a binary search or similar. It also significantly reduces the workload; for instance if you find a solution for 170 that actually weighs 150 then any subsequent query in 150..170 requires zero work, unlike the naive cache and dp solutions. |
Using a (bespoke) range cache solves this problem, although the simplistic version given could probably be improved with a binary search or similar. It also significantly reduces the workload; for instance if you find a solution for 170 that actually weighs 150 then any subsequent query in 150..170 requires zero work, unlike the naive cache and dp solutions. |
||
<!--< |
<!--<syntaxhighlight lang="phix">(phixonline)--> |
||
<span style="color: #000080;font-style:italic;">-- demo\rosetta\knapsackB.exw</span> |
<span style="color: #000080;font-style:italic;">-- demo\rosetta\knapsackB.exw</span> |
||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span> |
||
Line 3,277: | Line 3,277: | ||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"cache_entries:%d, hits:%d, misses:%d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">cache_entries</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cache_hits</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cache_misses</span><span style="color: #0000FF;">})</span> |
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"cache_entries:%d, hits:%d, misses:%d\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">cache_entries</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cache_hits</span><span style="color: #0000FF;">,</span><span style="color: #000000;">cache_misses</span><span style="color: #0000FF;">})</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,309: | Line 3,309: | ||
=={{header|Picat}}== |
=={{header|Picat}}== |
||
< |
<syntaxhighlight lang="picat">import mip,util. |
||
go => |
go => |
||
Line 3,389: | Line 3,389: | ||
["socks", 4, 50, 1], |
["socks", 4, 50, 1], |
||
["book", 30, 10, 2]], |
["book", 30, 10, 2]], |
||
MaxWeight = 400.</ |
MaxWeight = 400.</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,410: | Line 3,410: | ||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
< |
<syntaxhighlight lang="picolisp">(de *Items |
||
("map" 9 150 1) ("compass" 13 35 1) |
("map" 9 150 1) ("compass" 13 35 1) |
||
("water" 153 200 3) ("sandwich" 50 60 2) |
("water" 153 200 3) ("sandwich" 50 60 2) |
||
Line 3,441: | Line 3,441: | ||
(for I K |
(for I K |
||
(apply tab I (3 -24 6 6) NIL) ) |
(apply tab I (3 -24 6 6) NIL) ) |
||
(tab (27 6 6) NIL (sum cadr K) (sum caddr K)) )</ |
(tab (27 6 6) NIL (sum cadr K) (sum caddr K)) )</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> map 9 150 |
<pre> map 9 150 |
||
Line 3,464: | Line 3,464: | ||
{{libheader|clpfd}} |
{{libheader|clpfd}} |
||
Library clpfd is written by <b>Markus Triska</b>. Takes about 3 seconds to compute the best solution. |
Library clpfd is written by <b>Markus Triska</b>. Takes about 3 seconds to compute the best solution. |
||
< |
<syntaxhighlight lang="prolog">:- use_module(library(clpfd)). |
||
% tuples (name, weights, value, nb pieces). |
% tuples (name, weights, value, nb pieces). |
||
Line 3,539: | Line 3,539: | ||
sformat(W3, A3, [V]), |
sformat(W3, A3, [V]), |
||
format('~w~w~w~w~n', [W0,W1,W2,W3]), |
format('~w~w~w~w~n', [W0,W1,W2,W3]), |
||
print_results(A1, A2, A3, T, TR, WM, VM).</ |
print_results(A1, A2, A3, T, TR, WM, VM).</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> ?- knapsack. |
<pre> ?- knapsack. |
||
Line 3,559: | Line 3,559: | ||
===Library simplex=== |
===Library simplex=== |
||
Library simplex is written by <b>Markus Triska</b>. Takes about 10 seconds to compute the best solution. |
Library simplex is written by <b>Markus Triska</b>. Takes about 10 seconds to compute the best solution. |
||
< |
<syntaxhighlight lang="prolog">:- use_module(library(simplex)). |
||
% tuples (name, weights, value, pieces). |
% tuples (name, weights, value, pieces). |
||
knapsack :- |
knapsack :- |
||
Line 3,638: | Line 3,638: | ||
W2 is W1 + X * W, |
W2 is W1 + X * W, |
||
V2 is V1 + X * V), |
V2 is V1 + X * V), |
||
print_results(S, A1, A2, A3, T, TN, W2, V2).</ |
print_results(S, A1, A2, A3, T, TN, W2, V2).</syntaxhighlight> |
||
=={{header|Python}}== |
=={{header|Python}}== |
||
Not as [[Knapsack problem/0-1#Python|dumb a search]] over all possible combinations under the maximum allowed weight: |
Not as [[Knapsack problem/0-1#Python|dumb a search]] over all possible combinations under the maximum allowed weight: |
||
< |
<syntaxhighlight lang="python">from itertools import groupby |
||
from collections import namedtuple |
from collections import namedtuple |
||
Line 3,692: | Line 3,692: | ||
print("Bagged the following %i items" % len(bagged[COMB])) |
print("Bagged the following %i items" % len(bagged[COMB])) |
||
print('\n\t'.join('%i off: %s' % (len(list(grp)), item.name) for item, grp in groupby(sorted(bagged[COMB])))) |
print('\n\t'.join('%i off: %s' % (len(list(grp)), item.name) for item, grp in groupby(sorted(bagged[COMB])))) |
||
print("for a total value of %i and a total weight of %i" % bagged[1:])</ |
print("for a total value of %i and a total weight of %i" % bagged[1:])</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Bagged the following 14 items |
<pre>Bagged the following 14 items |
||
Line 3,709: | Line 3,709: | ||
===Dynamic programming solution=== |
===Dynamic programming solution=== |
||
This is much faster. It expands the multiple possible instances of an item into individual instances then applies the zero-one dynamic knapsack solution: |
This is much faster. It expands the multiple possible instances of an item into individual instances then applies the zero-one dynamic knapsack solution: |
||
< |
<syntaxhighlight lang="python">from itertools import groupby |
||
try: |
try: |
||
Line 3,774: | Line 3,774: | ||
for item,grp in groupby(sorted(bagged)))) |
for item,grp in groupby(sorted(bagged)))) |
||
print("for a total value of %i and a total weight of %i" % ( |
print("for a total value of %i and a total weight of %i" % ( |
||
sum(item[2] for item in bagged), sum(item[1] for item in bagged)))</ |
sum(item[2] for item in bagged), sum(item[1] for item in bagged)))</syntaxhighlight> |
||
===Non-zero-one solution=== |
===Non-zero-one solution=== |
||
< |
<syntaxhighlight lang="python">items = { |
||
"sandwich": (50, 60, 2), |
"sandwich": (50, 60, 2), |
||
"map": (9, 150, 1), |
"map": (9, 150, 1), |
||
Line 3,834: | Line 3,834: | ||
w = w + items[name][0] * cnt |
w = w + items[name][0] * cnt |
||
print("Total weight:", w, "Value:", v)</ |
print("Total weight:", w, "Value:", v)</syntaxhighlight> |
||
=={{header|R}}== |
=={{header|R}}== |
||
Reading in task via web scraping. |
Reading in task via web scraping. |
||
< |
<syntaxhighlight lang="r">library(tidyverse) |
||
library(rvest) |
library(rvest) |
||
Line 3,849: | Line 3,849: | ||
mutate(weight= as.numeric(weight), |
mutate(weight= as.numeric(weight), |
||
value= as.numeric(value), |
value= as.numeric(value), |
||
pieces= as.numeric(pieces))</ |
pieces= as.numeric(pieces))</syntaxhighlight> |
||
Solution of the task using genetic algorithm. |
Solution of the task using genetic algorithm. |
||
< |
<syntaxhighlight lang="r">library(rgenoud) |
||
fitness= function(x= rep(1, nrow(task_table))){ |
fitness= function(x= rep(1, nrow(task_table))){ |
||
Line 3,874: | Line 3,874: | ||
cat("Weight:", sum(task_table$weight * evolution$par), "dag", "\n") |
cat("Weight:", sum(task_table$weight * evolution$par), "dag", "\n") |
||
data.frame(item= task_table$items, pieces= as.integer(solution)) %>% |
data.frame(item= task_table$items, pieces= as.integer(solution)) %>% |
||
filter(solution> 0)</ |
filter(solution> 0)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,899: | Line 3,899: | ||
The algorithm is nearly a direct translation of Haskell's array-based implementation. However, the data is taken from the webpage itself. |
The algorithm is nearly a direct translation of Haskell's array-based implementation. However, the data is taken from the webpage itself. |
||
<syntaxhighlight lang="racket"> |
|||
<lang Racket> |
|||
#lang racket |
#lang racket |
||
(require net/url html xml xml/path) |
(require net/url html xml xml/path) |
||
Line 3,988: | Line 3,988: | ||
(match-let ([(solution value choices) (best (vector->list (solution-vector capacity)))]) |
(match-let ([(solution value choices) (best (vector->list (solution-vector capacity)))]) |
||
(solution value (filter (compose positive? choice-count) choices)))) |
(solution value (filter (compose positive? choice-count) choices)))) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 4,013: | Line 4,013: | ||
Recursive algorithm, with cache. Idiomatic code style, using multi-subs and a class. |
Recursive algorithm, with cache. Idiomatic code style, using multi-subs and a class. |
||
{{works with|Rakudo|2017.01}} |
{{works with|Rakudo|2017.01}} |
||
<lang |
<syntaxhighlight lang="raku" line>my class KnapsackItem { has $.name; has $.weight; has $.unit; } |
||
multi sub pokem ([], $, $v = 0) { $v } |
multi sub pokem ([], $, $v = 0) { $v } |
||
Line 4,066: | Line 4,066: | ||
for %hash.sort -> $item { |
for %hash.sort -> $item { |
||
say " {$item.value} {$item.key}"; |
say " {$item.value} {$item.key}"; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Value = 1010 |
<pre>Value = 1010 |
||
Line 4,085: | Line 4,085: | ||
==== Faster alternative ==== |
==== Faster alternative ==== |
||
Also recursive, with cache, but substantially faster. Code more generic (ported from Perl solution). |
Also recursive, with cache, but substantially faster. Code more generic (ported from Perl solution). |
||
<lang |
<syntaxhighlight lang="raku" line>my $raw = qq:to/TABLE/; |
||
map 9 150 1 |
map 9 150 1 |
||
compass 13 35 1 |
compass 13 35 1 |
||
Line 4,139: | Line 4,139: | ||
my ($v, $w, @p) = pick($max_weight, @items.end); |
my ($v, $w, @p) = pick($max_weight, @items.end); |
||
{ say "{@p[$_]} of @items[$_]{'name'}" if @p[$_] } for 0 .. @p.end; |
{ say "{@p[$_]} of @items[$_]{'name'}" if @p[$_] } for 0 .. @p.end; |
||
say "Value: $v Weight: $w";</ |
say "Value: $v Weight: $w";</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>1 of map |
<pre>1 of map |
||
Line 4,160: | Line 4,160: | ||
<br>"unrolled" and converted into discrete combination checks (based on the number of items). The unused combinatorial |
<br>"unrolled" and converted into discrete combination checks (based on the number of items). The unused combinatorial |
||
<br>checks were discarded and only the pertinent code was retained. |
<br>checks were discarded and only the pertinent code was retained. |
||
< |
<syntaxhighlight lang="rexx">/*REXX program solves a knapsack problem (22 items + repeats, with weight restriction.*/ |
||
call @gen /*generate items and initializations. */ |
call @gen /*generate items and initializations. */ |
||
call @sort /*sort items by decreasing their weight*/ |
call @sort /*sort items by decreasing their weight*/ |
||
Line 4,315: | Line 4,315: | ||
do j37=j36+(j36>0) to h;if w.j37+w36>m then iterate j36;w37=w36+w.j37;z37=z36+v.j37;if z37>$ then call j? 37 |
do j37=j36+(j36>0) to h;if w.j37+w36>m then iterate j36;w37=w36+w.j37;z37=z36+v.j37;if z37>$ then call j? 37 |
||
end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end |
end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end;end |
||
end;end;end;end;end;end;end;end;end;end; return /* [↑] there is one END for each DO loop.*/</ |
end;end;end;end;end;end;end;end;end;end; return /* [↑] there is one END for each DO loop.*/</syntaxhighlight> |
||
'''output''' |
'''output''' |
||
<pre> |
<pre> |
||
Line 4,374: | Line 4,374: | ||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="ruby"> |
||
# Item struct to represent each item in the problem |
# Item struct to represent each item in the problem |
||
Struct.new('Item', :name, :weight, :value, :count) |
Struct.new('Item', :name, :weight, :value, :count) |
||
Line 4,434: | Line 4,434: | ||
p "Total weight: #{w}, Value: #{val}" |
p "Total weight: #{w}, Value: #{val}" |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|SAS}}== |
=={{header|SAS}}== |
||
Use MILP solver in SAS/OR: |
Use MILP solver in SAS/OR: |
||
< |
<syntaxhighlight lang="sas">/* create SAS data set */ |
||
data mydata; |
data mydata; |
||
input item $1-23 weight value pieces; |
input item $1-23 weight value pieces; |
||
Line 4,488: | Line 4,488: | ||
print TotalValue; |
print TotalValue; |
||
print {i in ITEMS: NumSelected[i].sol > 0.5} NumSelected; |
print {i in ITEMS: NumSelected[i].sol > 0.5} NumSelected; |
||
quit;</ |
quit;</syntaxhighlight> |
||
Output: |
Output: |
||
Line 4,511: | Line 4,511: | ||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
{{trans|Perl}} |
{{trans|Perl}} |
||
< |
<syntaxhighlight lang="ruby">var raw = <<'TABLE' |
||
map 9 150 1 |
map 9 150 1 |
||
compass 13 35 1 |
compass 13 35 1 |
||
Line 4,577: | Line 4,577: | ||
say "#{p[i]} of #{items[i].name}" if p[i].is_pos |
say "#{p[i]} of #{items[i].name}" if p[i].is_pos |
||
} |
} |
||
say "Value: #{v}; Weight: #{w}"</ |
say "Value: #{v}; Weight: #{w}"</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 4,598: | Line 4,598: | ||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="swift">public struct KnapsackItem: Hashable { |
||
public var name: String |
public var name: String |
||
public var weight: Int |
public var weight: Int |
||
Line 4,679: | Line 4,679: | ||
} |
} |
||
print("For a total value of \(totalVal) and weight of \(totalWeight)")</ |
print("For a total value of \(totalVal) and weight of \(totalWeight)")</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 4,703: | Line 4,703: | ||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
Classic dumb search algorithm: |
Classic dumb search algorithm: |
||
< |
<syntaxhighlight lang="tcl"># The list of items to consider, as list of lists |
||
set items { |
set items { |
||
{map 9 150 1} |
{map 9 150 1} |
||
Line 4,789: | Line 4,789: | ||
foreach {count item} [countednames $best] { |
foreach {count item} [countednames $best] { |
||
puts "\t$count * $item" |
puts "\t$count * $item" |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 4,810: | Line 4,810: | ||
Instead of an ''ad-hoc'' solution, we can convert this task to a |
Instead of an ''ad-hoc'' solution, we can convert this task to a |
||
[[wp:Mixed_integer_programming#Integer_unknowns|mixed integer programming]] problem instance and solve it with the [http://lpsolve.sourceforge.net lpsolve] library, which is callable in Ursala. |
[[wp:Mixed_integer_programming#Integer_unknowns|mixed integer programming]] problem instance and solve it with the [http://lpsolve.sourceforge.net lpsolve] library, which is callable in Ursala. |
||
< |
<syntaxhighlight lang="ursala">#import std |
||
#import flo |
#import flo |
||
#import lin |
#import lin |
||
Line 4,853: | Line 4,853: | ||
#show+ |
#show+ |
||
main = format solution system items</ |
main = format solution system items</syntaxhighlight> |
||
The <code>linear_system$[</code>...<code>]</code> function takes the item list as an argument and returns a data structure with the following fields, which is passed to the <code>solution</code> function, which calls the <code>lpsolve</code> routines. |
The <code>linear_system$[</code>...<code>]</code> function takes the item list as an argument and returns a data structure with the following fields, which is passed to the <code>solution</code> function, which calls the <code>lpsolve</code> routines. |
||
* <code>integers</code> declares that all variables in the list take integer values |
* <code>integers</code> declares that all variables in the list take integer values |
||
Line 4,877: | Line 4,877: | ||
{{trans|Kotlin}} |
{{trans|Kotlin}} |
||
{{libheader|Wren-fmt}} |
{{libheader|Wren-fmt}} |
||
< |
<syntaxhighlight lang="ecmascript">import "/fmt" for Fmt |
||
class Item { |
class Item { |
||
Line 4,969: | Line 4,969: | ||
} |
} |
||
System.print("--------------------- ------ ----- ------") |
System.print("--------------------- ------ ----- ------") |
||
Fmt.print("Items chosen $d $3d $4d $2d", itemCount, sumWeight, sumValue, sumNumber)</ |
Fmt.print("Items chosen $d $3d $4d $2d", itemCount, sumWeight, sumValue, sumNumber)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 4,992: | Line 4,992: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
{{trans|Haskell}} |
{{trans|Haskell}} |
||
< |
<syntaxhighlight lang="zkl">fcn addItem(old,[(nm,w,v,c)]){ // old:list:(cost of:,(name,#,...)) |
||
[1..c].reduce(fcn(list,i,nm,w,v,old){ |
[1..c].reduce(fcn(list,i,nm,w,v,old){ |
||
wi,left,right:=w*i,list[0,wi],list[wi,*]; |
wi,left,right:=w*i,list[0,wi],list[wi,*]; |
||
Line 4,999: | Line 4,999: | ||
fcn([(v1,_)]a,[(v2,_)]b){ v1>v2 and a or b },new)); |
fcn([(v1,_)]a,[(v2,_)]b){ v1>v2 and a or b },new)); |
||
},old,nm,w,v,old); |
},old,nm,w,v,old); |
||
}//--> new list</ |
}//--> new list</syntaxhighlight> |
||
< |
<syntaxhighlight lang="zkl">items:=T( // item: (name,weight,value,#) |
||
T("apple", 39, 40,3),T("banana", 27,60,3), |
T("apple", 39, 40,3),T("banana", 27,60,3), |
||
T("beer", 52, 10,3),T("book", 30,10,2),T("camera", 32, 30,1), |
T("beer", 52, 10,3),T("book", 30,10,2),T("camera", 32, 30,1), |
||
Line 5,013: | Line 5,013: | ||
'wrap(nm,n){ items[items.filter1n(fcn(it,nm){ it[0]==nm },nm)][1]*n }) |
'wrap(nm,n){ items[items.filter1n(fcn(it,nm){ it[0]==nm },nm)][1]*n }) |
||
.sum(0) |
.sum(0) |
||
};</ |
};</syntaxhighlight> |
||
< |
<syntaxhighlight lang="zkl">const MAX_WEIGHT=400; |
||
knapsack:=items.reduce(addItem,(MAX_WEIGHT).pump(List,T(0,T).copy))[-1]; |
knapsack:=items.reduce(addItem,(MAX_WEIGHT).pump(List,T(0,T).copy))[-1]; |
||
knapsack.toString(*).println(weight(knapsack));</ |
knapsack.toString(*).println(weight(knapsack));</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |