The branch and bound method of the five major algorithms 2 - improving efficiency through pruning

The last blog (Branch and Bound Method of the Five Algorithms) introduced the use of branch and bound method to solve the loading problem. The time and space complexity of the algorithm are both 2^n. This blog considers how to improve the algorithm and improve efficiency.

Before each live node is added, it is necessary to consider whether the current loading weight plus the total weight of the remaining cargo is greater than the current optimal solution. If not, it indicates that the branch cannot produce the optimal solution and can be removed. That is, pruning is performed according to this constraint.

After improvement run w={ 10, 2, 5, 7, 5, 9, 4, 3, 2, 5, 3, 3, 4, 2, 3, 4, 3, 3, 4, 1, 2, 1, 2, 1, 2, 1 } instance, it takes 1838ms, and the algorithm before optimization takes 27776ms, and the efficiency is obviously improved.

code show as below:

package test;
 
import java.util.LinkedList;
 
/**
 * Use branch and bound method to solve loading problem, improved version
 *
 * @author yanghang
 *
 */
public class Fenzhidingjie2 {
 
    private static float[] w = { 10, 2, 5, 7, 5, 9, 4, 3, 2, 5, 3, 3, 4, 2, 3,
            4, 3, 3, 4, 1, 2, 1, 2, 1, 2, 1 }; // Array of container masses
    private static int n = w.length; // number of boxes
    private static float c1 = 50; // first ship's deadweight
    private static float c2 = 50; // second ship's deadweight
 
    private static float bestw; // max load for the first ship
    private static float ew; // current ship's load
    private static LinkedList<Float> mq = new LinkedList<Float>(); // FIFO队列
 
    /**
     * optimal loading value
     *
     * @param c
     */
    public static float maxLoading(float c) {
        mq.addLast(new Float(-1)); // Initialize the node queue, mark the layer
        int i = 0; // layer of E-node
        ew = 0; // current ship's load
        bestw = 0; // current best value
        // The weight of the remaining cargo, used for pruning
        float r = 0;
        for (float f : w) {
            r += f;
        }
        r -= w[0];
 
        while (!mq.isEmpty()) { // search the subset space tree
            // Check if the left child of the E-node, container i can be loaded
            if (ew + w[i] <= c) {
                if (ew + w[i] > bestw) {
                    bestw = ew + w[i]; // update the best value
                }
                addLiveNode(ew + w[i], i); // Container i can be loaded
            }
            // Pruning, the current weight plus the remaining weight is greater than the current optimal value to continue, otherwise the branch cannot produce the optimal solution
            if (ew + r > bestw) {
                addLiveNode(ew, i); // right child is always available, no cargo i is loaded
            }
            ew = (Float) mq.removeFirst(); // remove the next node
 
            if (ew == -1) { // reach the end of the layer
                if (mq.isEmpty()) {
                    return bestw;
                }
                mq.addLast(new Float(-1));
                ew = (Float) mq.removeFirst(); // remove the next node
                i++; // layer of ew
                r -= w[i]; // update remaining weight
            }
        }
        return bestw;
    }
 
    /**
     * Join the team
     *
     * @param wt
     * @for me
     */
    public static void addLiveNode(float wt, int i) {
        if (i == n - 1) { // subscript starts from 0, it is a leaf
            if (wt > bestw) {
                bestw = wt;
            }
        } else { // not a leaf
            mq.addLast(new Float(wt));
        }
    }
 
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        // sum of weights of all boxes
        long start = System.currentTimeMillis();
 
        float s = 0;
        for (float f : w) {
            s += f;
        }
        if (s <= c1 || s <= c2) {
            System.out.println("need only one ship!");
        }
        if (s > c1 + c2) {
            System.out.println("no solution!");
            return;
        }
 
        float bestw = Fenzhidingjie2.maxLoading(c1);
 
        if (s - bestw <= c2) {
            System.out.println("The first ship loading " + bestw);
            System.out.println("The second ship loading " + (s - bestw));
        } else {
            System.out.println("no solution!");
        }
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }
 
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325570408&siteId=291194637