Task: Knapsack problem_Unbounded




Go: package main

import "fmt"

type Item struct {
	Name           string
	Value          int
	Weight, Volume float64
}

type Result struct {
	Counts []int
	Sum    int
}

func min(a, b int) int {
	if a < b {
		return a
	}
	return b
}

func Knapsack(items []Item, weight, volume float64) (best Result) {
	if len(items) == 0 {
		return
	}
	n := len(items) - 1
	maxCount := min(int(weight/items[n].Weight), int(volume/items[n].Volume))
	for count := 0; count <= maxCount; count++ {
		sol := Knapsack(items[:n],
			weight-float64(count)*items[n].Weight,
			volume-float64(count)*items[n].Volume)
		sol.Sum += items[n].Value * count
		if sol.Sum > best.Sum {
			sol.Counts = append(sol.Counts, count)
			best = sol
		}
	}
	return
}

func main() {
	items := []Item{
		{"Panacea", 3000, 0.3, 0.025},
		{"Ichor", 1800, 0.2, 0.015},
		{"Gold", 2500, 2.0, 0.002},
	}
	var sumCount, sumValue int
	var sumWeight, sumVolume float64

	result := Knapsack(items, 25, 0.25)

	for i := range result.Counts {
		fmt.Printf("%-8s x%3d  -> Weight: %4.1f  Volume: %5.3f  Value: %6d\n",
			items[i].Name, result.Counts[i], items[i].Weight*float64(result.Counts[i]),
			items[i].Volume*float64(result.Counts[i]), items[i].Value*result.Counts[i])

		sumCount += result.Counts[i]
		sumValue += items[i].Value * result.Counts[i]
		sumWeight += items[i].Weight * float64(result.Counts[i])
		sumVolume += items[i].Volume * float64(result.Counts[i])
	}

	fmt.Printf("TOTAL (%3d items) Weight: %4.1f  Volume: %5.3f  Value: %6d\n",
		sumCount, sumWeight, sumVolume, sumValue)
}


Java: package hu.pj.alg;

import hu.pj.obj.Item;
import java.text.*;

public class UnboundedKnapsack {

    protected Item []  items = {
                               new Item("panacea", 3000,  0.3, 0.025),
                               new Item("ichor"  , 1800,  0.2, 0.015),
                               new Item("gold"   , 2500,  2.0, 0.002)
                               };
    protected final int    n = items.length; 
    protected Item      sack = new Item("sack"   ,    0, 25.0, 0.250);
    protected Item      best = new Item("best"   ,    0,  0.0, 0.000);
    protected int  []  maxIt = new int [n];  
    protected int  []    iIt = new int [n];  
    protected int  [] bestAm = new int [n];  

    public UnboundedKnapsack() {
        
        for (int i = 0; i < n; i++) {
            maxIt [i] = Math.min(
                           (int)(sack.getWeight() / items[i].getWeight()),
                           (int)(sack.getVolume() / items[i].getVolume())
                        );
        } 

        
        calcWithRecursion(0);

        
        NumberFormat nf = NumberFormat.getInstance();
        System.out.println("Maximum value achievable is: " + best.getValue());
        System.out.print("This is achieved by carrying (one solution): ");
        for (int i = 0; i < n; i++) {
            System.out.print(bestAm[i] + " " + items[i].getName() + ", ");
        }
        System.out.println();
        System.out.println("The weight to carry is: " + nf.format(best.getWeight()) +
                           "   and the volume used is: " + nf.format(best.getVolume())
                          );

    }

    
    
    public void calcWithRecursion(int item) {
        for (int i = 0; i <= maxIt[item]; i++) {
            iIt[item] = i;
            if (item < n-1) {
                calcWithRecursion(item+1);
            } else {
                int    currVal = 0;   
                double currWei = 0.0; 
                double currVol = 0.0; 
                for (int j = 0; j < n; j++) {
                    currVal += iIt[j] * items[j].getValue();
                    currWei += iIt[j] * items[j].getWeight();
                    currVol += iIt[j] * items[j].getVolume();
                }

                if (currVal > best.getValue()
                    &&
                    currWei <= sack.getWeight()
                    &&
                    currVol <= sack.getVolume()
                )
                {
                    best.setValue (currVal);
                    best.setWeight(currWei);
                    best.setVolume(currVol);
                    for (int j = 0; j < n; j++) bestAm[j] = iIt[j];
                } 
            } 
        } 
    } 

    
    public static void main(String[] args) {
        new UnboundedKnapsack();
    } 

}