-1

Im trying out and algorithm i found on google books http://books.google.ee/books?id=DAorddWEgl0C&printsec=frontcover&source=gbs_ge_summary_r&cad=0#v=onepage&q&f=false that solves a knapsack problem. I have built a similar one for my own project but the program keeps running without returning a knapsack integer.

In other words, im supposed to get 90 in System.out.println(knapsack(n,maxW)); but my code doesn't return any result.

Here is the code i've written:

public class Algoritmid3 {

public static int[] weight;
public static int[] value;
public static int maxW = 16;
public static int n;

public static class Node {
    int level;
    int weight;
    int profit;
    double bound;
}

public static class NodeComparator implements Comparator {
    @Override
    public int compare(Object o1, Object o2) {
        Node n1 = (Node) o1;
        Node n2 = (Node) o2;
        if (n1.bound < n2.bound) {
            return 1;
        }
        if (n1.bound > n2.bound) {
            return -1;
        }
        else {
            return 0;
        }
    }
}

public static double bound(Node a) {
    int j, k;
    int totalWeight;
    double result;
    if (a.weight >= maxW) {
        return 0;
    }
    else {
        result = a.profit;
        j = a.level + 1;
        totalWeight = a.weight;
        while (j <= n && totalWeight + weight[j] <= maxW) {
            totalWeight += weight[j];
            result += value[j];
            j++;
        }
        k = j;
        if (k <= n) {
            result += ((maxW - totalWeight) * (value[k] / weight[k]));
        }
        return result;
    }

}


public static void main(String[] args) {
    maxW = 16;
    n = 5;
    weight = new int[5];
    value = new int[5];
    weight[0] = 2;
    value[0] = 40;
    weight[1] = 5;
    value[1] = 30;
    weight[2] = 10;
    value[2] = 50;
    weight[3] = 15;
    value[3] = 60;
    weight[4] = 5;
    value[4] = 5;

    System.out.println(knapsack(n,maxW));
}

public static int knapsack(int n, int maxWeight) {
    NodeComparator nc = new NodeComparator();
    PriorityQueue pq = new PriorityQueue(n, nc);
    Node u, v;
    int maxprofit = 0;
    v = new Node();
    u = new Node();
    v.level = 0;
    v.profit = 0;
    v.weight = 0;
    v.bound = bound(v);
    pq.add(v);
    while (!(pq.isEmpty())) {
        pq.remove(v);
        if (v.bound > maxprofit) {
            u.level = v.level + 1;
            u.weight  = v.weight + weight[u.level];
            u.profit = v.profit + value[u.level];

            if (u.weight <= maxW && u.profit > maxprofit) {
                maxprofit = u.profit;
            }
            u.bound = bound(u);
            if (u.bound > maxprofit) {
                pq.add(u);
            }
            u.weight = v.weight;
            u.profit = v.profit;
            u.bound = bound(u);
            if (u.bound > maxprofit) {
                pq.add(u);
            }
        }
    }
    return maxprofit;
}
}
Evald
  • 122
  • 10
  • I had it running for 53 minutes previously and it still had no result. It seems to be in endless loop, yet it is not supposed to be. – Evald Dec 04 '14 at 00:33
  • Pretty sure this isn't your main problem, since if it was you'd be hitting segfaults, but inside your `else` in `bound(..)`, if `j=n` then `weight[j]` is undefined. You need `while (j – chrisb2244 Dec 04 '14 at 00:49
  • Apply normal debugging techniques. In this case: print each step of the operation, follow along by hand, observe when it does something wrong, fix wrong thing. – Dwayne Towell Dec 04 '14 at 02:22
  • I have done as you suggested Dwayne, it turns out that my while loop in knapsack keeps adding more and more Nodes to priority queue, however it is supposed to end up having 0 elements in it. I will try to figure out why. – Evald Dec 04 '14 at 03:10

1 Answers1

1

Similar question with same code is already asked in StackOverflow

But this solution is not memory efficient.

Find below your corrected code.

public class Algoritmid3 {

public static int[] weight;
public static int[] value;
public static int maxW = 16;
public static int n;

public static class Node {
    int level;
    int weight;
    int profit;
    double bound;
}

public static class NodeComparator implements Comparator {
    @Override
    public int compare(Object o1, Object o2) {
        Node n1 = (Node) o1;
        Node n2 = (Node) o2;
        if (n1.bound < n2.bound) {
            return 1;
        }
        if (n1.bound > n2.bound) {
            return -1;
        } else {
            return 0;
        }
    }
}

public static double bound(Node a) {
    int j = 0, k;
    int totalWeight;
    double result;
    if (a.weight >= maxW) {
        return 0;
    } else {
        result = a.profit;
        // j = a.level + 1;
        if (a.level < weight.length) {
            j = a.level + 1;
        }
        totalWeight = a.weight;
        // while (j <= n && totalWeight + weight[j] <= maxW) {
        while (j < n && totalWeight + weight[j] <= maxW) {
            totalWeight += weight[j];
            result += value[j];
            j++;
        }
        k = j;
        // if (k <= n) {
        if (k < n) {
            result += ((maxW - totalWeight) * (value[k] / weight[k]));
        }
        return result;
    }

}

public static void main(String[] args) {
    maxW = 16;
    n = 5;
    weight = new int[5];
    value = new int[5];
    weight[0] = 2;
    value[0] = 40;
    weight[1] = 5;
    value[1] = 30;
    weight[2] = 10;
    value[2] = 50;
    weight[3] = 15;
    value[3] = 60;
    weight[4] = 5;
    value[4] = 5;

    System.out.println(knapsack(n, maxW));
}

public static int knapsack(int n, int maxWeight) {
    NodeComparator nc = new NodeComparator();
    PriorityQueue pq = new PriorityQueue(n, nc);
    Node u, v;
    int maxprofit = 0;
    v = new Node();
    u = new Node();
    v.level = -1;
    v.profit = 0;
    v.weight = 0;
    v.bound = bound(v);
    pq.add(v);
    while (!(pq.isEmpty())) {
        // pq.remove(v);
        // Remove head of the queue
        v = (Node) pq.poll();
        u = new Node();
        if (v.bound > maxprofit) {
            u.level = v.level + 1;
            u.weight = v.weight + weight[u.level];
            u.profit = v.profit + value[u.level];

            if (u.weight <= maxW && u.profit > maxprofit) {
                maxprofit = u.profit;
            }
            u.bound = bound(u);
            if (u.bound > maxprofit) {
                pq.add(u);
            }
            // >> IZMO
            u = new Node();
            u.level = v.level + 1;
            // << IZMO
            u.weight = v.weight;
            u.profit = v.profit;
            u.bound = bound(u);
            if (u.bound > maxprofit) {
                pq.add(u);
            }
        }
    }
    return maxprofit;
}

}

Community
  • 1
  • 1
Chetan Naik
  • 53
  • 1
  • 5
  • Thanks! Now it works fine. The only problem is that my knapsack algorithm does not find the best solution for what i have in main class, int knapsack returns 80, however the best value is 90 (item 1 + item 3), i will try to figure out the problem now. – Evald Dec 04 '14 at 10:37
  • Hey, it's working fine for me. I get the value 90 as expected. – Chetan Naik Dec 05 '14 at 01:53
  • Thank you, it works as expected now. I did not change anything and it worked as expected the next day(i'm not sure if i changed anything or it did not compile correctly). – Evald Dec 06 '14 at 16:33