C
#include <stdio.h>
#include <stdlib.h>
typedef struct {
char *name
;
int weight
;
int value
;
} item_t
;
item_t items
[] = {
{"map", 9, 150},
{"compass", 13, 35},
{"water", 153, 200},
{"sandwich", 50, 160},
{"glucose", 15, 60},
{"tin", 68, 45},
{"banana", 27, 60},
{"apple", 39, 40},
{"cheese", 23, 30},
{"beer", 52, 10},
{"suntan cream", 11, 70},
{"camera", 32, 30},
{"T-shirt", 24, 15},
{"trousers", 48, 10},
{"umbrella", 73, 40},
{"waterproof trousers", 42, 70},
{"waterproof overclothes", 43, 75},
{"note-case", 22, 80},
{"sunglasses", 7, 20},
{"towel", 18, 12},
{"socks", 4, 50},
{"book", 30, 10},
};
int *knapsack
(item_t
*items
, int n
, int w
) {
int i
, j
, a
, b
, *mm
, **m
, *s
;
mm
= calloc((n
+ 1) * (w
+ 1), sizeof (int));
m
= malloc((n
+ 1) * sizeof (int *));
m
[0] = mm
;
for (i
= 1; i
<= n
; i
++) {
m
[i
] = &mm
[i
* (w
+ 1)];
for (j
= 0; j
<= w
; j
++) {
if (items
[i
- 1].weight
> j
) {
m
[i
][j
] = m
[i
- 1][j
];
}
else {
a
= m
[i
- 1][j
];
b
= m
[i
- 1][j
- items
[i
- 1].weight
] + items
[i
- 1].value
;
m
[i
][j
] = a
> b
? a
: b
;
}
}
}
s
= calloc(n
, sizeof (int));
for (i
= n
, j
= w
; i
> 0; i
--) {
if (m
[i
][j
] > m
[i
- 1][j
]) {
s
[i
- 1] = 1;
j
-= items
[i
- 1].weight
;
}
}
free(mm
);
free(m
);
return s
;
}
int main
() {
int i
, n
, tw
= 0, tv
= 0, *s
;
n
= sizeof (items
) / sizeof (item_t
);
s
= knapsack(items
, n
, 400);
for (i
= 0; i
< n
; i
++) {
if (s
[i
]) {
printf("%-22s ] ]\n", items
[i
].name
, items
[i
].weight
, items
[i
].value
);
tw
+= items
[i
].weight
;
tv
+= items
[i
].value
;
}
}
printf("%-22s ] ]\n", "totals:", tw
, tv
);
return 0;
}
输出
map 9 150
compass 13 35
water 153 200
sandwich 50 160
glucose 15 60
banana 27 60
suntan cream 11 70
waterproof trousers 42 70
waterproof overclothes 43 75
note-case 22 80
sunglasses 7 20
socks 4 50
totals: 396 1030
C++
#include <vector>
#include <string>
#include <iostream>
#include <boost/tuple/tuple.hpp>
#include <set>
int findBestPack( const std
::vector
<boost
::tuple
<std
::string
, int , int> > & ,
std
::set
<int> & , const int ) ;
int main( ) {
std
::vector
<boost
::tuple
<std
::string
, int , int> > items
;
items
.push_back( boost
::make_tuple( "" , 0 , 0 ) ) ;
items
.push_back( boost
::make_tuple( "map" , 9 , 150 ) ) ;
items
.push_back( boost
::make_tuple( "compass" , 13 , 35 ) ) ;
items
.push_back( boost
::make_tuple( "water" , 153 , 200 ) ) ;
items
.push_back( boost
::make_tuple( "sandwich", 50 , 160 ) ) ;
items
.push_back( boost
::make_tuple( "glucose" , 15 , 60 ) ) ;
items
.push_back( boost
::make_tuple( "tin", 68 , 45 ) ) ;
items
.push_back( boost
::make_tuple( "banana", 27 , 60 ) ) ;
items
.push_back( boost
::make_tuple( "apple" , 39 , 40 ) ) ;
items
.push_back( boost
::make_tuple( "cheese" , 23 , 30 ) ) ;
items
.push_back( boost
::make_tuple( "beer" , 52 , 10 ) ) ;
items
.push_back( boost
::make_tuple( "suntan creme" , 11 , 70 ) ) ;
items
.push_back( boost
::make_tuple( "camera" , 32 , 30 ) ) ;
items
.push_back( boost
::make_tuple( "T-shirt" , 24 , 15 ) ) ;
items
.push_back( boost
::make_tuple( "trousers" , 48 , 10 ) ) ;
items
.push_back( boost
::make_tuple( "umbrella" , 73 , 40 ) ) ;
items
.push_back( boost
::make_tuple( "waterproof trousers" , 42 , 70 ) ) ;
items
.push_back( boost
::make_tuple( "waterproof overclothes" , 43 , 75 ) ) ;
items
.push_back( boost
::make_tuple( "note-case" , 22 , 80 ) ) ;
items
.push_back( boost
::make_tuple( "sunglasses" , 7 , 20 ) ) ;
items
.push_back( boost
::make_tuple( "towel" , 18 , 12 ) ) ;
items
.push_back( boost
::make_tuple( "socks" , 4 , 50 ) ) ;
items
.push_back( boost
::make_tuple( "book" , 30 , 10 ) ) ;
const int maximumWeight
= 400 ;
std
::set
<int> bestItems
;
int bestValue
= findBestPack( items
, bestItems
, maximumWeight
) ;
std
::cout
<< "The best value that can be packed in the given knapsack is " <<
bestValue
<< " !\n" ;
int totalweight
= 0 ;
std
::cout
<< "The following items should be packed in the knapsack:\n" ;
for ( std
::set
<int>::const_iterator si
= bestItems
.begin( ) ;
si
!= bestItems
.end( ) ; si
++ ) {
std
::cout
<< (items
.begin( ) + *si
)->get
<0>( ) << "\n" ;
totalweight
+= (items
.begin( ) + *si
)->get
<1>( ) ;
}
std
::cout
<< "The total weight of all items is " << totalweight
<< " !\n" ;
return 0 ;
}
int findBestPack( const std
::vector
<boost
::tuple
<std
::string
, int , int> > & items
,std
::set
<int> & bestItems
, const int weightlimit
) {
const int n
= items
.size( ) ;
int bestValues
[ n
][ weightlimit
] ;
std
::set
<int> solutionSets
[ n
][ weightlimit
] ;
std
::set
<int> emptyset
;
for ( int i
= 0 ; i
< n
; i
++ ) {
for ( int j
= 0 ; j
< weightlimit
; j
++ ) {
bestValues
[ i
][ j
] = 0 ;
solutionSets
[ i
][ j
] = emptyset
;
}
}
for ( int i
= 0 ; i
< n
; i
++ ) {
for ( int weight
= 0 ; weight
< weightlimit
; weight
++ ) {
if ( i
== 0 )
bestValues
[ i
][ weight
] = 0 ;
else {
int itemweight
= (items
.begin( ) + i
)->get
<1>( ) ;
if ( weight
< itemweight
) {
bestValues
[ i
][ weight
] = bestValues
[ i
- 1 ][ weight
] ;
solutionSets
[ i
][ weight
] = solutionSets
[ i
- 1 ][ weight
] ;
} else {
if ( bestValues
[ i
- 1 ][ weight
- itemweight
] +
(items
.begin( ) + i
)->get
<2>( ) >
bestValues
[ i
- 1 ][ weight
] ) {
bestValues
[ i
][ weight
] =
bestValues
[ i
- 1 ][ weight
- itemweight
] +
(items
.begin( ) + i
)->get
<2>( ) ;
solutionSets
[ i
][ weight
] =
solutionSets
[ i
- 1 ][ weight
- itemweight
] ;
solutionSets
[ i
][ weight
].insert( i
) ;
}
else {
bestValues
[ i
][ weight
] = bestValues
[ i
- 1 ][ weight
] ;
solutionSets
[ i
][ weight
] = solutionSets
[ i
- 1 ][ weight
] ;
}
}
}
}
}
bestItems
.swap( solutionSets
[ n
- 1][ weightlimit
- 1 ] ) ;
return bestValues
[ n
- 1 ][ weightlimit
- 1 ] ;
}
输出
The best value that can be packed in the given knapsack is 1030 !
The following items should be packed in the knapsack:
map
compass
water
sandwich
glucose
banana
suntan creme
waterproof trousers
waterproof overclothes
note-case
sunglasses
socks
The total weight of all items is 396 !
C#
using System
;
using System
.Collections
.Generic
;
namespace Tests_With_Framework_4
{
class Bag : IEnumerable<Bag
.Item
>
{
List
<Item
> items
;
const int MaxWeightAllowed
= 400;
public Bag()
{
items
= new List<Item>();
}
void AddItem(Item i
)
{
if ((TotalWeight
+ i
.Weight
) <= MaxWeightAllowed
)
items
.Add(i
);
}
public void Calculate(List
<Item
> items
)
{
foreach (Item i
in Sorte(items
))
{
AddItem(i
);
}
}
List
<Item
> Sorte(List
<Item
> inputItems
)
{
List
<Item
> choosenItems
= new List<Item>();
for (int i
= 0; i
< inputItems
.Count
; i
++)
{
int j
= -1;
if (i
== 0)
{
choosenItems
.Add(inputItems
[i
]);
}
if (i
> 0)
{
if (!RecursiveF(inputItems
, choosenItems
, i
, choosenItems
.Count
- 1, false, ref j
))
{
choosenItems
.Add(inputItems
[i
]);
}
}
}
return choosenItems
;
}
bool RecursiveF(List
<Item
> knapsackItems
, List
<Item
> choosenItems
, int i
, int lastBound
, bool dec
, ref int indxToAdd
)
{
if (!(lastBound
< 0))
{
if ( knapsackItems
[i
].ResultWV
< choosenItems
[lastBound
].ResultWV
)
{
indxToAdd
= lastBound
;
}
return RecursiveF(knapsackItems
, choosenItems
, i
, lastBound
- 1, true, ref indxToAdd
);
}
if (indxToAdd
> -1)
{
choosenItems
.Insert(indxToAdd
, knapsackItems
[i
]);
return true;
}
return false;
}
#region IEnumerable<Item> Members
IEnumerator
<Item
> IEnumerable
<Item
>.GetEnumerator()
{
foreach (Item i
in items
)
yield return i
;
}
#endregion
#region IEnumerable Members
System.Collections.IEnumerator System
.Collections
.IEnumerable
.GetEnumerator()
{
return items
.GetEnumerator();
}
#endregion
public int TotalWeight
{
get
{
var sum
= 0;
foreach (Item i
in this)
{
sum
+= i
.Weight
;
}
return sum
;
}
}
public class Item
{
public string Name
{ get; set; } public int Weight
{ get; set; } public int Value
{ get; set; } public int ResultWV
{ get { return Weight
-Value
; } }
public override string ToString()
{
return "Name : " + Name
+ " Wieght : " + Weight
+ " Value : " + Value
+ " ResultWV : " + ResultWV
;
}
}
}
class Program
{
static void Main(string[] args
)
{List
<Bag
.Item
> knapsackItems
= new List<Bag.Item>();
knapsackItems
.Add(new Bag.Item() { Name
= "Map", Weight
= 9, Value
= 150 });
knapsackItems
.Add(new Bag.Item() { Name
= "Water", Weight
= 153, Value
= 200 });
knapsackItems
.Add(new Bag.Item() { Name
= "Compass", Weight
= 13, Value
= 35 });
knapsackItems
.Add(new Bag.Item() { Name
= "Sandwitch", Weight
= 50, Value
= 160 });
knapsackItems
.Add(new Bag.Item() { Name
= "Glucose", Weight
= 15, Value
= 60 });
knapsackItems
.Add(new Bag.Item() { Name
= "Tin", Weight
= 68, Value
= 45 });
knapsackItems
.Add(new Bag.Item() { Name
= "Banana", Weight
= 27, Value
= 60 });
knapsackItems
.Add(new Bag.Item() { Name
= "Apple", Weight
= 39, Value
= 40 });
knapsackItems
.Add(new Bag.Item() { Name
= "Cheese", Weight
= 23, Value
= 30 });
knapsackItems
.Add(new Bag.Item() { Name
= "Beer", Weight
= 52, Value
= 10 });
knapsackItems
.Add(new Bag.Item() { Name
= "Suntan Cream", Weight
= 11, Value
= 70 });
knapsackItems
.Add(new Bag.Item() { Name
= "Camera", Weight
= 32, Value
= 30 });
knapsackItems
.Add(new Bag.Item() { Name
= "T-shirt", Weight
= 24, Value
= 15 });
knapsackItems
.Add(new Bag.Item() { Name
= "Trousers", Weight
= 48, Value
= 10 });
knapsackItems
.Add(new Bag.Item() { Name
= "Umbrella", Weight
= 73, Value
= 40 });
knapsackItems
.Add(new Bag.Item() { Name
= "WaterProof Trousers", Weight
= 42, Value
= 70 });
knapsackItems
.Add(new Bag.Item() { Name
= "Note-Case", Weight
= 22, Value
= 80 });
knapsackItems
.Add(new Bag.Item() { Name
= "Sunglasses", Weight
= 7, Value
= 20 });
knapsackItems
.Add(new Bag.Item() { Name
= "Towel", Weight
= 18, Value
= 12 });
knapsackItems
.Add(new Bag.Item() { Name
= "Socks", Weight
= 4, Value
= 50 });
knapsackItems
.Add(new Bag.Item() { Name
= "Book", Weight
= 30, Value
= 10 });
knapsackItems
.Add(new Bag.Item() { Name
= "waterproof overclothes ", Weight
= 43, Value
= 75 });
Bag b
= new Bag();
b
.Calculate(knapsackItems
);
b
.All(x
=> { Console
.WriteLine(x
); return true; });
Console
.WriteLine(b
.Sum(x
=> x
.Weight
));
Console
.ReadKey();
}
}
}
Dart
List solveKnapsack(items, maxWeight) {
int MIN_VALUE=-100;
int N = items.length; // number of items
int W = maxWeight; // maximum weight of knapsack
List profit = new List(N+1);
List weight = new List(N+1);
// generate random instance, items 1..N
for(int n = 1; n<=N; n++) {
profit[n] = items[n-1][2];
weight[n] = items[n-1][1];
}
// opt[n][w] = max profit of packing items 1..n with weight limit w
// sol[n][w] = does opt solution to pack items 1..n with weight limit w include item n?
List<List<int>> opt = new List<List<int>>(N+1);
for (int i=0; i<N+1; i++) {
opt[i] = new List<int>(W+1);
for(int j=0; j<W+1; j++) {
opt[i][j] = MIN_VALUE;
}
}
List<List<bool>> sol = new List<List<bool>>(N+1);
for (int i=0; i<N+1; i++) {
sol[i] = new List<bool>(W+1);
for(int j=0; j<W+1; j++) {
sol[i][j] = false;
}
}
for(int n=1; n<=N; n++) {
for (int w=1; w <= W; w++) {
// don't take item n
int option1 = opt[n-1][w];
// take item n
int option2 = MIN_VALUE;
if (weight[n] <= w) {
option2 = profit[n] + opt[n-1][w - weight[n]];
}
// select better of two options
opt[n][w] = Math.max(option1, option2);
sol[n][w] = (option2 > option1);
}
}
// determine which items to take
List<List> packItems = new List<List>();
List<bool> take = new List(N+1);
for (int n = N, w = W; n > 0; n--) {
if (sol[n][w]) {
take[n] = true;
w = w - weight[n];
packItems.add(items[n-1]);
} else {
take[n] = false;
}
}
return packItems;
}
main() {
List knapsackItems = [];
knapsackItems.add(["map", 9, 150]);
knapsackItems.add(["compass", 13, 35]);
knapsackItems.add(["water", 153, 200]);
knapsackItems.add(["sandwich", 50, 160]);
knapsackItems.add(["glucose", 15, 60]);
knapsackItems.add(["tin", 68, 45]);
knapsackItems.add(["banana", 27, 60]);
knapsackItems.add(["apple", 39, 40]);
knapsackItems.add(["cheese", 23, 30]);
knapsackItems.add(["beer", 52, 10]);
knapsackItems.add(["suntan cream", 11, 70]);
knapsackItems.add(["camera", 32, 30]);
knapsackItems.add(["t-shirt", 24, 15]);
knapsackItems.add(["trousers", 48, 10]);
knapsackItems.add(["umbrella", 73, 40]);
knapsackItems.add(["waterproof trousers", 42, 70]);
knapsackItems.add(["waterproof overclothes", 43, 75]);
knapsackItems.add(["note-case", 22, 80]);
knapsackItems.add(["sunglasses", 7, 20]);
knapsackItems.add(["towel", 18, 12]);
knapsackItems.add(["socks", 4, 50]);
knapsackItems.add(["book", 30, 10]);
int maxWeight = 400;
Stopwatch sw = new Stopwatch.start();
List p = solveKnapsack(knapsackItems, maxWeight);
sw.stop();
int totalWeight = 0;
int totalValue = 0;
print(["item","profit","weight"]);
p.forEach((var i) { print("${i}"); totalWeight+=i[1]; totalValue+=i[2]; });
print("Total Value = ${totalValue}");
print("Total Weight = ${totalWeight}");
print("Elapsed Time = ${sw.elapsedInMs()}ms");
}
Go
package main
import "fmt"
type item
struct {
string
w
, v
int
}
var wants
= []item
{
{"map", 9, 150},
{"compass", 13, 35},
{"water", 153, 200},
{"sandwich", 50, 160},
{"glucose", 15, 60},
{"tin", 68, 45},
{"banana", 27, 60},
{"apple", 39, 40},
{"cheese", 23, 30},
{"beer", 52, 10},
{"suntan cream", 11, 70},
{"camera", 32, 30},
{"T-shirt", 24, 15},
{"trousers", 48, 10},
{"umbrella", 73, 40},
{"waterproof trousers", 42, 70},
{"waterproof overclothes", 43, 75},
{"note-case", 22, 80},
{"sunglasses", 7, 20},
{"towel", 18, 12},
{"socks", 4, 50},
{"book", 30, 10},
}
const maxWt
= 400
func main() {
items
, w
, v
:= m(len(wants
)-1, maxWt
)
fmt
.Println(items
)
fmt
.Println("weight:", w
)
fmt
.Println("value:", v
)
}
func m(i
, w
int) ([]string, int, int) {
if i
< 0 || w
== 0 {
return nil, 0, 0
} else if wants
[i
].w
> w
{
return m(i
-1, w
)
}
i0
, w0
, v0
:= m(i
-1, w
)
i1
, w1
, v1
:= m(i
-1, w
-wants
[i
].w
)
v1
+= wants
[i
].v
if v1
> v0
{
return append(i1
, wants
[i
].string), w1
+ wants
[i
].w
, v1
}
return i0
, w0
, v0
}
Java
package com
.pro
.alg
.test
;
import com
.pro
.alg
.ZeroOneKnapsack
;
import com
.pro
.obj
.Item
;
import java
.util
.*
;
import java
.text
.*
;
public class ZeroOneKnapsackForTourists {
public ZeroOneKnapsackForTourists() {
ZeroOneKnapsack zok
= new ZeroOneKnapsack(400);
zok
.add("map", 9, 150);
zok
.add("compass", 13, 35);
zok
.add("water", 153, 200);
zok
.add("sandwich", 50, 160);
zok
.add("glucose", 15, 60);
zok
.add("tin", 68, 45);
zok
.add("banana", 27, 60);
zok
.add("apple", 39, 40);
zok
.add("cheese", 23, 30);
zok
.add("beer", 52, 10);
zok
.add("suntan cream", 11, 70);
zok
.add("camera", 32, 30);
zok
.add("t-shirt", 24, 15);
zok
.add("trousers", 48, 10);
zok
.add("umbrella", 73, 40);
zok
.add("waterproof trousers", 42, 70);
zok
.add("waterproof overclothes", 43, 75);
zok
.add("note-case", 22, 80);
zok
.add("sunglasses", 7, 20);
zok
.add("towel", 18, 12);
zok
.add("socks", 4, 50);
zok
.add("book", 30, 10);
List
<Item> itemList
= zok
.calcSolution();
if (zok
.isCalculated()) {
NumberFormat nf
= NumberFormat
.getInstance();
System
.out
.println(
"Maximal weight = " +
nf
.format(zok
.getMaxWeight() / 100.0) + " kg"
);
System
.out
.println(
"Total weight of solution = " +
nf
.format(zok
.getSolutionWeight() / 100.0) + " kg"
);
System
.out
.println(
"Total value = " +
zok
.getProfit()
);
System
.out
.println();
System
.out
.println(
"You can carry the following materials " +
"in the knapsack:"
);
for (Item item
: itemList
) {
if (item
.getInKnapsack() == 1) {
System
.out
.format(
"%1$-23s %2$-3s %3$-5s %4$-15s \n",
item
.getName(),
item
.getWeight(), "dag ",
"(value = " + item
.getValue() + ")"
);
}
}
} else {
System
.out
.println(
"The problem is not solved. " +
"Maybe you gave wrong data."
);
}
}
public static void main(String
[] args
) {
new ZeroOneKnapsackForTourists();
}
}
package com
.pro
.alg
;
import com
.pro
.obj
.Item
;
import java
.util
.*
;
public class ZeroOneKnapsack {
protected List
<Item> itemList
= new ArrayList<Item>();
protected int maxWeight
= 0;
protected int solutionWeight
= 0;
protected int profit
= 0;
protected boolean calculated
= false;
public ZeroOneKnapsack() {}
public ZeroOneKnapsack(int _maxWeight
) {
setMaxWeight(_maxWeight
);
}
public ZeroOneKnapsack(List
<Item> _itemList
) {
setItemList(_itemList
);
}
public ZeroOneKnapsack(List
<Item> _itemList
, int _maxWeight
) {
setItemList(_itemList
);
setMaxWeight(_maxWeight
);
}
public List
<Item> calcSolution() {
int n
= itemList
.size();
setInitialStateForCalculation();
if (n
> 0 && maxWeight
> 0) {
List
< List
<Integer> > c
= new ArrayList< List
<Integer> >();
List
<Integer> curr
= new ArrayList<Integer>();
c
.add(curr
);
for (int j
= 0; j
<= maxWeight
; j
++)
curr
.add(0);
for (int i
= 1; i
<= n
; i
++) {
List
<Integer> prev
= curr
;
c
.add(curr
= new ArrayList<Integer>());
for (int j
= 0; j
<= maxWeight
; j
++) {
if (j
> 0) {
int wH
= itemList
.get(i
-1).getWeight();
curr
.add(
(wH
> j
)
?
prev
.get(j
)
:
Math
.max(
prev
.get(j
),
itemList
.get(i
-1).getValue() + prev
.get(j
-wH
)
)
);
} else {
curr
.add(0);
}
}
}
profit
= curr
.get(maxWeight
);
for (int i
= n
, j
= maxWeight
; i
> 0 && j
>= 0; i
--) {
int tempI
= c
.get(i
).get(j
);
int tempI_1
= c
.get(i
-1).get(j
);
if (
(i
== 0 && tempI
> 0)
||
(i
> 0 && tempI
!= tempI_1
)
)
{
Item iH
= itemList
.get(i
-1);
int wH
= iH
.getWeight();
iH
.setInKnapsack(1);
j
-= wH
;
solutionWeight
+= wH
;
}
}
calculated
= true;
}
return itemList
;
}
public void add(String name
, int weight
, int value
) {
if (name
.equals(""))
name
= "" + (itemList
.size() + 1);
itemList
.add(new Item(name
, weight
, value
));
setInitialStateForCalculation();
}
public void add(int weight
, int value
) {
add("", weight
, value
);
}
public void remove(String name
) {
for (Iterator
<Item> it
= itemList
.iterator(); it
.hasNext(); ) {
if (name
.equals(it
.next().getName())) {
it
.remove();
}
}
setInitialStateForCalculation();
}
public void removeAllItems() {
itemList
.clear();
setInitialStateForCalculation();
}
public int getProfit() {
if (!calculated
)
calcSolution();
return profit
;
}
public int getSolutionWeight() {return solutionWeight
;}
public boolean isCalculated() {return calculated
;}
public int getMaxWeight() {return maxWeight
;}
public void setMaxWeight(int _maxWeight
) {
maxWeight
= Math
.max(_maxWeight
, 0);
}
public void setItemList(List
<Item> _itemList
) {
if (_itemList
!= null
) {
itemList
= _itemList
;
for (Item item
: _itemList
) {
item
.checkMembers();
}
}
}
private void setInKnapsackByAll(int inKnapsack
) {
for (Item item
: itemList
)
if (inKnapsack
> 0)
item
.setInKnapsack(1);
else
item
.setInKnapsack(0);
}
protected void setInitialStateForCalculation() {
setInKnapsackByAll(0);
calculated
= false;
profit
= 0;
solutionWeight
= 0;
}
}
package com
.pro
.obj
;
public class Item {
protected String name
= "";
protected int weight
= 0;
protected int value
= 0;
protected int bounding
= 1;
protected int inKnapsack
= 0;
public Item() {}
public Item(Item item
) {
setName(item
.name
);
setWeight(item
.weight
);
setValue(item
.value
);
setBounding(item
.bounding
);
}
public Item(int _weight
, int _value
) {
setWeight(_weight
);
setValue(_value
);
}
public Item(int _weight
, int _value
, int _bounding
) {
setWeight(_weight
);
setValue(_value
);
setBounding(_bounding
);
}
public Item(String _name
, int _weight
, int _value
) {
setName(_name
);
setWeight(_weight
);
setValue(_value
);
}
public Item(String _name
, int _weight
, int _value
, int _bounding
) {
setName(_name
);
setWeight(_weight
);
setValue(_value
);
setBounding(_bounding
);
}
public void setName(String _name
) {name
= _name
;}
public void setWeight(int _weight
) {weight
= Math
.max(_weight
, 0);}
public void setValue(int _value
) {value
= Math
.max(_value
, 0);}
public void setInKnapsack(int _inKnapsack
) {
inKnapsack
= Math
.min(getBounding(), Math
.max(_inKnapsack
, 0));
}
public void setBounding(int _bounding
) {
bounding
= Math
.max(_bounding
, 0);
if (bounding
== 0)
inKnapsack
= 0;
}
public void checkMembers() {
setWeight(weight
);
setValue(value
);
setBounding(bounding
);
setInKnapsack(inKnapsack
);
}
public String
getName() {return name
;}
public int getWeight() {return weight
;}
public int getValue() {return value
;}
public int getInKnapsack() {return inKnapsack
;}
public int getBounding() {return bounding
;}
}
输出
Maximal weight = 4 kg
Total weight of solution = 3,96 kg
Total value = 1030
You can carry te following materials in the knapsack:
map 9 dag (value = 150)
compass 13 dag (value = 35)
water 153 dag (value = 200)
sandwich 50 dag (value = 160)
glucose 15 dag (value = 60)
banana 27 dag (value = 60)
suntan cream 11 dag (value = 70)
waterproof trousers 42 dag (value = 70)
waterproof overclothes 43 dag (value = 75)
note-case 22 dag (value = 80)
sunglasses 7 dag (value = 20)
socks 4 dag (value = 50)
Javascript
portviz
.knapsack
= {};
(function() {
this.combiner = function(items
, weightfn
, valuefn
) {
var _epsilon
= 0.01;
var _p
= _
.max(_
.map(items
,valuefn
));
var _k
= _epsilon
* _p
/ items
.length
;
var _memo
= (function(){
var _mem
= {};
var _key = function(i
, w
) {
return i
+ '::' + w
;
};
return {
get: function(i
, w
) {
return _mem
[_key(i
,w
)];
},
put
: function(i
, w
, r
) {
_mem
[_key(i
,w
)]=r
;
return r
;
}
};
})();
var _m = function(i
, w
) {
i
= Math
.round(i
);
w
= Math
.round(w
);
if (i
< 0 || w
=== 0) {
return {items
: [], totalWeight
: 0, totalValue
: 0};
}
var mm
= _memo
.get(i
,w
);
if (!_
.isUndefined(mm
)) {
return mm
;
}
var item
= items
[i
];
if (weightfn(item
) > w
) {
return _memo
.put(i
, w
, _m(i
-1, w
));
}
var excluded
= _m(i
-1, w
);
var included
= _m(i
-1, w
- weightfn(item
));
if (included
.totalValue
+ Math
.floor(valuefn(item
)/_k
) > excluded
.totalValue
) {
var i1
= included
.items
.slice();
i1
.push(item
);
return _memo
.put(i
, w
,
{items
: i1
,
totalWeight
: included
.totalWeight
+ weightfn(item
),
totalValue
: included
.totalValue
+ Math
.floor(valuefn(item
)/_k
)});
}
return _memo
.put(i
,w
, excluded
);
};
return {
one
: function(maxweight
) {
var scaled
= _m(items
.length
- 1, maxweight
);
return {
items
: scaled
.items
,
totalWeight
: scaled
.totalWeight
,
totalValue
: scaled
.totalValue
* _k
};
},
ef
: function(maxweight
, step
) {
return _
.map(_
.range(0, maxweight
+1, step
), function(weight
) {
var scaled
= _m(items
.length
- 1, weight
);
return {
items
: scaled
.items
,
totalWeight
: scaled
.totalWeight
,
totalValue
: scaled
.totalValue
* _k
};
});
}
};
};
}).apply(portviz
.knapsack
);
var allwants
= [
{name
:"map", weight
:9, value
: 150},
{name
:"compass", weight
:13, value
: 35},
{name
:"water", weight
:153, value
: 200},
{name
:"sandwich", weight
: 50, value
: 160},
{name
:"glucose", weight
:15, value
: 60},
{name
:"tin", weight
:68, value
: 45},
{name
:"banana", weight
:27, value
: 60},
{name
:"apple", weight
:39, value
: 40},
{name
:"cheese", weight
:23, value
: 30},
{name
:"beer", weight
:52, value
: 10},
{name
:"suntan cream", weight
:11, value
: 70},
{name
:"camera", weight
:32, value
: 30},
{name
:"T-shirt", weight
:24, value
: 15},
{name
:"trousers", weight
:48, value
: 10},
{name
:"umbrella", weight
:73, value
: 40},
{name
:"waterproof trousers", weight
:42, value
: 70},
{name
:"waterproof overclothes", weight
:43, value
: 75},
{name
:"note-case", weight
:22, value
: 80},
{name
:"sunglasses", weight
:7, value
: 20},
{name
:"towel", weight
:18, value
: 12},
{name
:"socks", weight
:4, value
: 50},
{name
:"book", weight
:30, value
: 10}
];
var near = function(actual
, expected
, tolerance
) {
if (expected
=== 0 && actual
=== 0) return true;
if (expected
=== 0) {
return Math
.abs(expected
- actual
) / actual
< tolerance
;
}
return Math
.abs(expected
- actual
) / expected
< tolerance
;
};
test("one knapsack", function() {
var combiner
=
portviz
.knapsack
.combiner(allwants
,
function(x
){return x
.weight
;},
function(x
){return x
.value
;});
var oneport
= combiner
.one(400);
ok(near(oneport
.totalValue
, 1030, 0.01), "correct total value");
ok(near(oneport
.totalValue
, 1030, 0.01), "correct total value");
equal(oneport
.totalWeight
, 396, "correct total weight");
});
test("frontier", function() {
var combiner
=
portviz
.knapsack
.combiner(allwants
,
function(x
){return x
.weight
;},
function(x
){return x
.value
;});
var ef
= combiner
.ef(400, 1);
equal(ef
.length
, 401, "401 because it includes the endpoints");
ef
= combiner
.ef(400, 40);
equal(ef
.length
, 11, "11 because it includes the endpoints");
var expectedTotalValue
= [
0,
330,
445,
590,
685,
755,
810,
860,
902,
960,
1030
] ;
_
.each(ef
, function(element
, index
) {
ok(near(element
.totalValue
, expectedTotalValue
[index
], 0.15),
'actual ' + element
.totalValue
+ ' expected ' + expectedTotalValue
[index
]);
});
deepEqual(_
.pluck(ef
, 'totalWeight'), [
0,
39,
74,
118,
158,
200,
236,
266,
316,
354,
396
]);
deepEqual(_
.map(ef
, function(x
){return x
.items
.length
;}), [
0,
4,
6,
7,
9,
10,
10,
12,
14,
11,
12
]);
});