Backtracking - Loading Problems

Problem Description:

    There are a total of n cargoes to be loaded on two ships with weights c1 and c2 respectively, where the weight of cargo i is Wi, and:

                             

    Request to determine if there is a reasonable loading scheme to load the cargo on both ships.


Take strategies:      
 (1) First fill the first ship as much as possible;
 (2) Load the remaining containers on the second ship. Filling the first ship as full as possible is equivalent to choosing a subset of the total container in
     which the sum of the container weights is the closest. It follows that the loading problem is equivalent to the following special 0-1 knapsack problem:

                            

Bound function:

    Define a CW to represent the weight of reaching the current node O. If CW>C1, it means that the subtree rooted at O ​​cannot produce a feasible solution and avoid moving.

defect:

    The right child of a feasible node is always feasible.

Algorithm improvements:

    If the right subtree of the current node cannot contain a better solution than the current optimal solution, it does not move to the right subtree.

    Let bestW be the current optimal solution, and Z be a node in the i-th layer of the solution space tree.

Improved bound function:

    Let r be the weight of the remaining container, when CW+r<=bestW, there is no need to search the right subtree of Z.


Not much to say, go directly to the code:

    

package set;
public class Loading {
	static int n;//Number of containers
	static int[] w;//Container weight array
	static int c;//The weight of the first ship
	static int cw;//Currently loaded weight
	static int bestw;//The weight of the current optimal load
	static int r;//The weight of the remaining container
	
	static int[] x;//The current solution, record the path from the root to the current node
	static int[] bestx;//Record the current optimal solution
	
	
	public static int MaxLoading(int[] ww,int cc) {
		//Initialize the data members, the array subscript starts from 1
		n = ww.length - 1;
		w = ww;
		c = cc;
		cw = 0;
		bestw = 0;
		x = new int[n+1];
		bestx = new int[n+1];
		
		//Initialize r, that is, the remaining maximum weight
		for(int i =1;i<=n;i++) {
			r += w[i];
		}
		
		//Calculate the optimal load
		backtrack(1);
		return bestw;
	}
	
	// backtracking algorithm
	public static void backtrack(int t) {
		if(t>n) {//reach the leaf node
			if(cw>bestw) {
				for(int i=1;i<=n;i++) {
					bestx[i] = x[i];
				}
				bestw = cw;
			}
			return;
		}
		
		r -= w[t];
		if(cw + w[t] <= c) {//Search the left subtree
			x[t] = 1;
			cw += w[t];
			backtrack(t+1);
			cw -= w[t];//Backtrack
		}
		
		if(cw + r>bestw) {
			x[t] = 0;//Search the right subtree
			backtrack(t+1);
		}
		
		r += w[t];//Restore the scene
		
	}
	/*
	 * If the right subtree of the current node cannot contain a better solution than the current optimal solution, do not move to the right subtree!
	Let bestw be the current optimal solution, and Z be a node in the i-th layer of the solution space tree
		is the weight of the remaining container; when cw+r<=bestw, there is no need to search the right subtree of Z:
		Current load capacity cw + weight of remaining containers r Current optimal load capacity bestw
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		int[] ww = {0,20,30,60,40,40};
		int c1 = 100;
		int c2 = 100;
		int n = ww.length - 1;
		
		MaxLoading(ww,c1);
		int weight2 = 0;//Save the possible weight of the second ship
		for(int i=1;i<=n;i++) {
			weight2 += ww[i]*(1-bestx[i]);//The value of bestx[i] can only be 0 or 1
			
		}
		if(weight2>c2) {
			System.out.println("无解");
		}
		else {
			System.out.println("The weight of the first ship loaded: " + bestw);
			System.out.println("The weight of the second ship's cargo: " + weight2);
			
			// Loading of the first ship
			for(int i = 1;i<=n;i++) {
				if(bestx[i] == 1) {
					System.out.println("The first" + i + "pieces of goods loaded into the first ship");	
				}
			}
			
			// Loading of the second ship
			for(int i = 1;i<=n;i++) {
				if(bestx[i] == 0) {
					System.out.println("The first" + i + "pieces of goods loaded into the second ship");
					
				}
			}
			
		}
		
	}

}

operation result:

    



Guess you like

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