分享

算法设计与分析 5.2 装载问题

 shaobin0604@163.com 2006-10-07

/********************************************************************
      5.2 装载问题

 问题描述:
 有一批共有 n 个集装箱要装上两艘载重量分别为 c1 和 c2 的轮船,其中
 集装箱 i 的重量为 w[i], 且重量之和小于 (c1 + c2)。装载问题要求确定
 是否存在一个合理的装载方案可将这 n 个集装箱装上这两艘轮船。如果有,
 找出一种装载方案。

 容易证明,如果一个给定的装载问题有解,则采用如下的策略可以得到最优
 装载方案。
 1.首先将第一艘轮船尽可能装满。
 2.将剩余的集装箱装上第二艘轮船。

 将第一艘轮船尽可能的装满等价于选取全体集装箱的子集,使该子集中集装箱
 的重量之和最接近 c1 。因此,等价于一个特殊的 0-1 背包问题。

 因此是一棵子集树。

********************************************************************/
import java.util.*;

public class Loading {

 public static int nn;
 public static int cc;
 public static int bestww;
 public static int[] ww;
 public static int[] xx;
 public static int[] bestxx;


 
 public static int maxLoadingRE(int[] w, int c, int[] bestx) {
  nn = w.length;
  cc = c;
  bestww = 0;
  ww = w;
  bestxx = bestx;
  xx = new int[nn];
  int r = 0;
  for (int i = 0; i < nn; i++) {
      r += ww[i];
  }
  trackback(0, 0, r);
  return bestww;
 }
 
 private static void trackback(int i, int cw, int r) {
  if (i == nn) {//到达叶结点
   for (int j = 0; j < nn; j++) {
       bestxx[j] = xx[j];
   }
   bestww = cw;
   return;
  }
  if (cw + ww[i] <= cc) {
   xx[i] = 0;
   trackback(i + 1, cw + ww[i], r);
  }
  if (r - ww[i] > bestww) {
   xx[i] = 1;
   trackback(i + 1, cw, r - ww[i]);
  }
 }

    public static int maxLoading(int[] w, int c, int[] bestx) {
  int i = 0;      //当前层
  int n = w.length;    //层总数
  int[] x = new int[n];   //x[0, i]为当前选择路径
  Arrays.fill(x, -1);    //初始化为-1,0表示选择,1表示不选
  
  int bestw = 0;     //当前最优装载重量
  int[] cw = new int[n];   //当前载重量
  int[] r = new int[n];   //剩余集装箱容量
  int tor = 0;

  for (int item : w) {
      tor += item;
  }
  r[0] = tor;
  cw[0] = 0;
  //搜索子树
  while (i > -1) {
      do {
          x[i] += 1;
    if (x[i] == 0) {  //选择
        if (cw[i] + w[i] <= c) {
         if (i < n - 1) {
          cw[i + 1] = cw[i] + w[i];
          r[i + 1] = r[i];
         }
            break;
        }
    } else {    //不选
     if (r[i] - w[i] > bestw) {
      if (i < n - 1) {
       r[i + 1] = r[i] - w[i];
       cw[i + 1] = cw[i];
      }
         break;
     }
    }

      } while (x[i] < 2);

   if (x[i] < 2) {
       if (i == n - 1) {

     for (int j = 0; j < n; j++) {
         bestx[j] = x[j];
     }
     if (x[i] == 0) {
      bestw = cw[i] + w[i];   
     } else {
         bestw = cw[i];
     }
     
       } else {
           i++;
     x[i] = -1;
       }
   } else {
       i--;
   }
  }
  return bestw;
 }

 public static void main(String[] args) {
  int[] w = {20, 10, 40};
  int n = w.length;
  int c = 50;
  int[] bestx = new int[n];

  int bestw = maxLoadingRE(w, c, bestx);
  System.out.println("bestw : " + bestw);
  System.out.println(Arrays.toString(bestx));
 }
}

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多