⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 head.h

📁 3DBPP BRANCH AND BOUND
💻 H
📖 第 1 页 / 共 3 页
字号:
}

/* **********************************************************************
   **********************************************************************
			      Lower Bounds
   **********************************************************************
   ********************************************************************** */

/* ======================================================================
			      bound_zero
   ====================================================================== */

/* The continuous bound L_0 */

double bound_zero(solution *a, item *f, item *l)
{
  item *i, *m;
  double sum, lb;
  sum = 0;
  for (i = f, m = l+1; i != m; i++){
	  sum =  i->vol + sum;
  }
//  cout << sum << endl;
//  cout << a->BVOL<<endl;
  lb = sum / (double) a->BVOL;
  return lb;
}


/* ======================================================================
                               rotate_solution
   ====================================================================== */

/* rotates the solution. After 3 rotations we return to original problem */

void rotate_solution(solution *a, item *f, item *l)

{
  register item *i, *m;
  register double w, x;

  for (i = f, m = l+1; i != m; i++) {
    w = i->w; i->w = i->h; i->h = i->d; i->d = w;
    x = i->x; i->x = i->y; i->y = i->z; i->z = x;
  }
}


/* ======================================================================
			       rotate_problem
   ====================================================================== */

/* rotates the dimensions by one step */

void rotate_problem(solution *a, item *f, item *l)
{
  register item *i, *m;
  register double w, x;

  for (i = f, m = l+1; i != m; i++) {
    w = i->w; i->w = i->h; i->h = i->d; i->d = w;
    x = i->x; i->x = i->y; i->y = i->z; i->z = x;
  }
  w = a->W; a->W = a->H; a->H = a->D; a->D = w;
}

/* ======================================================================
			       choose_items
   ====================================================================== */

/* returns a set of items with w > W2 and d > D2. This set is used in */
/* bound_one */ 

// 本函数用以返回 w > W2 and d > D2 的item

void choose_items(solution *a, item *f, item *l, double W2, double D2, 
		  item *fitem, item **litem)
{
  item *i, *k, *m;

  for (i = f, m = l+1, k = fitem; i != m; i++) {
//	  cout<< i->w << " " << i->d << endl;
	  if ((i->w > W2) && (i->d > D2)) { 
		  *k = *i; k++; }
  }
  *litem = k-1;
}


/* ======================================================================
			       find_plist
   ====================================================================== */

/* returns a zero-terimanted list of distinct dimensions */

void find_plist(item *fitem, item *litem, double M, int dim, double *pl)
{
  register item *i, *m;
  register double *k, *j, *l;

  i = fitem; m = litem+1; k = pl;
  switch (dim) {
    case WDIM: for (; i != m; i++) {
		 if (i->w <= M) { *k = i->w; k++; } 
	       } break;
    case HDIM: for (; i != m; i++) {
		 if (i->h <= M) { *k = i->h; k++; } 
	       } break;
    case DDIM: for (; i != m; i++) {
		 if (i->d <= M) { *k = i->d; k++; } 
	       } break;
  }
  if (k == pl) { *k = 0; return; }
  isortincr(pl, k-1);  /* sort the dimensions */ //以上升序列进行单个维度的排序
  for (j = pl+1, l = pl; j != k; j++) { /* remove duplicates */
    if (*j != *l) { l++; *l = *j; } 
  }
  l++; *l = 0;
}


/* ======================================================================
			       bound_one
   ====================================================================== */

/* Derive bound L_1 for a fixed dimension */

double bound_one_x(solution *a, item *f, item *l){
  item *i, *m;
  double H, H2, h;
  double p, j1, j2, j3, j2h, j2hp, j3h;
  double *pp, lb, lb_one, alpha, beta;;
  item *fitem, *litem;
  fitem = new item[MAXITEMS];
  double plist[MAXITEMS];
  if (l == f-1) return 0;
  lb = 0; H = a->H; H2 = H/2;
//  cout << f->w << endl;
  choose_items(a, f, l, a->W/2, a->D/2, fitem, &litem);
  if (litem == fitem-1) { /* empty */return lb; }
  find_plist(a->fitem, a->litem, H2, HDIM, plist);
  for (pp = plist; *pp != 0; pp++) {
    p = *pp;
//	cout << "p:  " <<p<<endl;
	j1 = j2 = j3 = j2h = j2hp = j3h = 0;
    for (i = fitem, m = litem+1; i != m; i++) {
      h = i->h; 
//	  cout << "h " << h <<endl; 
      if (h > H-p) j1++;
      if ((H-p >= h) && (h > H2)) { j2++; j2h += h; j2hp += floor((H-h)/p); }
      if ((H2 >= h) && (h >= p)) { j3++; j3h += h; }
    }
    alpha = ceil((j3h - (j2 * H - j2h)) / H);
//	cout << alpha << endl;
    beta  = ceil((j3 - j2hp) / floor((H/p)));
//  cout << beta << endl;
	if (alpha < 0) alpha = 0;
    if (beta  < 0) beta  = 0;
    lb_one = j1 + j2 + MAXIMUM(alpha, beta);
//	cout << "bound one: " << lb_one <<endl;
    if (lb_one > lb) lb = lb_one;
  }
  return lb;
}

/* Derive bound L_1 as the best of all L_1 bounds for three rotations */

double bound_one(solution *a, item *f, item *l)
{
  int i;
  double lb, lbx;

  lb = 0;
  for (i = WDIM; i <= DDIM; i++) {
    lbx = bound_one_x(a, f, l);
    if (lbx > lb) lb = lbx; 
    rotate_problem(a, f, l);
  } 
  return lb;
}

/* ======================================================================
			       bound_two
   ====================================================================== */

/* Derive bound L_2 for a fixed dimension */

double bound_two_x(solution *a, item *f, item *l)
{
  register item *i, *m;
  register double W, H, D, w, h, d, W2, D2;
  register double p, q, k1h, k23v;
  double hlb1, lb, lb1, lbx, fract;
  double plist[MAXITEMS], qlist[MAXITEMS];
  double *qq, *pp;
  double WD, BVOL;

  /* derive bound_one */
  lb = lb1 = bound_one_x(a, f, l);
  W = a->W; H = a->H; D = a->D; hlb1 = H * lb1; 
  W2 = W/2; D2 = D/2; WD = W*D; BVOL = a->BVOL;

  /* run through all values of p, q */
  find_plist(f, l, W2, WDIM, plist);
  find_plist(f, l, D2, DDIM, qlist);
  for (pp = plist; *pp != 0; pp++) {
    p = *pp;
    for (qq = qlist; *qq != 0; qq++) {
      q = *qq;
      k1h = k23v = 0;
      for (i = f, m = l+1; i != m; i++) {
	w = i->w; h = i->h; d = i->d;
	if ((w > W - p) && (d > D - q)) { k1h += h; continue; }
	if ((w >= p) && (d >= q)) { k23v += i->vol; }
      }
      fract = ceil((k23v - (hlb1 - k1h)*WD) / BVOL);
      if (fract < 0) fract = 0;
      lbx = lb1 + fract;
      if (lbx > lb) lb = lbx;
    }
  }
  return lb;
}


/* Derive bound L_2 as the best of all L_2 bounds for three rotations */

double bound_two(solution *a, item *f, item *l)
{
  int i;
  double lb, lbx;
  lb = 0;
  for (i = WDIM; i <= DDIM; i++) {
    lbx = bound_two_x(a, f, l);
    if (lbx > lb) lb = lbx;
    rotate_problem(a, f, l);
  } 
  return lb;
}

/* **********************************************************************
   **********************************************************************
			    heuristic filling
   **********************************************************************
   ********************************************************************** */

/* ======================================================================
			      onelayer
   ====================================================================== */

/* Fill a layer of depth f->d by arranging the items in a number of */
/* vertical shelfs. The items $i$ packed are assigned coordinates */
/* (i->x, i->y) and the field i->k is set to the argument d (layer no). */

double onelayer(solution *a, item *f, item *l, double d)
{
  int n , t;
  double r; /* remaining width */
  double depth; // mark depth
  double width, height, x;
  item *i, *j, *markstart, *markend;
  markstart = f;
  n = DIF(f,l)+1;
  width = height = x = depth = 0;
  //  qsort(f, DIF(f,m), sizeof(item), (funcptr) hcomp);
  r = a->W;
  for ( i = f ; i != l+1 ; i++ ){
//	  cout << " item no "<< i->no << endl;
	  if ( i->w > r )
		  break;
	  if ( i->w < r ){
		  if ( height + i->h <= a->H ){
			  if ( i == l ){
				  height = 0;
				  markend = i;
				  qsort (markstart,DIF(markstart,markend),sizeof(item),(funcptr)wcomp);
				  for ( j = markstart; j != markend + 1; j++ ){
					  if (j->d > depth) depth = j->d;
			          j->x = x;
			          j->y = height ;
				      j->z = d;
				      j->k = 1;
				      height = height + j->h;
//				      cout <<j->no<<" "<<j->x<<" "<<j->y<<" "<<j->z<<" customer "<< j->customer<< endl;
				  }
			  }
			  height += i->h;
		  }
		  else {
			  markend = i-1;
//			  cout << "markend "<< markend->no<< "height "<< height<<endl;
			  height = 0;
		      qsort (markstart,DIF(markstart,markend),sizeof(item),(funcptr)wcomp);
//			  for ( b = a->fitem ; b!= a->litem+1 ; b++){
//				  cout << b->customer << " " << b->no << " " << b->vol << endl;
//			  }
			  for ( j = markstart; j != markend + 1; j++ ){
				  if (j->d > depth) depth = j->d;
				  j->x = x;
			      j->y = height ;
				  j->z = d;
				  j->k = 1;
				  height = height + j->h;
//				  cout <<j->no<<" "<<j->x<<" "<<j->y<<" "<<j->z<<" customer "<< j->customer<< endl;
			  }
		      x = x + markstart->w;
		      markstart = i;
			  i = i - 1;
		      r = r - x;
			  if ( r>0 ) height = 0;
		  }
	  }
  }

//  for ( f = a->fitem, l = a->litem; f != l+1 ; f++ ){
//	  cout << f->k <<" "<<f->x<<" "<<f->y<<" "<<f->z << " " << f->customer << " " << f->no << endl;
//  }
//  cout <<" depth " << depth <<endl;
  return depth;
}

/* ======================================================================
				  countarea
   ====================================================================== */

/* Select a subset of the items such that the selected items have a total */
/* area of two times the face of a bin (the parameter: barea) */

item *countarea(item *f, item *l, double barea)
{
  item *i;
  double area, d;

  for (area = 0, i = f; i != l+1; i++) {
    d = i->h * i->w;
    area += d;
    if (area > 2*barea) return i-1;
  }
  return l;
}

/* ======================================================================
				  remitems
   ====================================================================== */

/* Remove the items which were chosen for a layer, i.e. where i->k != 0. */
/* The depth of the layer is set equal to the deepest box chosen. */

item *remitems(item *f, item *l)
{
  item *i, *j;
  for (i = f,j = f; j != l+1; ) {
    if (i->k) {
		i++; j++; 
	}
	if (!i->k)
		j++;
  }
  return i;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -