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

📄 agtw.h

📁 Dynamic Programming Code for the TSP
💻 H
字号:
/* Subroutines for dynamic program for the Traveling Salesman Problem *//* www.contrib.andrew.cmu.edu/~neils/tsp/index.html                   *//* Neil Simonetti, May 1998                                           *//* ------------------------------------------------------------------- */void SortPretour (costtype *criterion, nodeXtype *tour, nodeXtype n)/* constructs an initial tour by sorting by the criterion *//* selection sort should be replaced by a better sorting  *//* algorithm in future for large problems */{ costtype earliest;  nodeXtype earliestInx;  signed int c1, c2;  { for (c1 = 1; c1 < n; c1++)    { earliest = inFinity;      for (c2 = 1; c2 < n; c2++)      { if (criterion[c2] < earliest) { earliest = criterion[earliestInx=c2]; }      }      tour[c1]=earliestInx;      criterion[earliestInx]=inFinity;  } }}/* ------------------------------------------------------------------- */signed char CalcKval (costtype *winBegin, costtype *winEnd,		      costtype *servTime, int *kval, signed char k,		      nodeXtype n, costtype *winDepartBound,                      char *compromise)/* construct array of k-values based on time windows */{ signed int c1, c2;  costtype bound;  signed char maxK;  winDepartBound[n]=inFinity;  for (bound = inFinity, c1 = n-1; c1 > -1; c1--)  { bound = winDepartBound[c1] = _min(winBegin[c1]+servTime[c1],bound);  }  kval[0]=maxK=1;  for (c1 = c2 = 1; c1 < n; c1++)  { while (winDepartBound[c2] < winEnd[c1]) {c2++;}    while (winDepartBound[c2-1]>winEnd[c1]) {c2--;}    kval[c1] = _min(k,_max(1,c2-c1));    maxK = _max(maxK,c2-c1);  }  *compromise = (maxK > k);  printf("Maximum k requested was %d.\n",maxK);  if (maxK > k) {printf("  Use this value of k to guarantee optimality.\n");}  maxK=_min(maxK,k);  kval[n]=1;  return (maxK);}/* ------------------------------------------------------------------- */signed char FixKval (costtype *winBegin, costtype *winEnd, costtype *servTime,                      int *kval, signed char k, nodeXtype n, nodeXtype *tour,                      costtype *winDepartBound)/* improve array of k-values by shuffling the tour order */{ signed int c1, c2, swaps, spot, dm1, dm2, bonus, penalty;  costtype bound, dm3, dm4, dm5;  signed char maxK;  swaps = 0;  winDepartBound[n]=inFinity;  for (bound = inFinity, c1 = n-1; c1 > -1; c1--)  { bound = winDepartBound[c1] = _min(winBegin[c1]+servTime[c1],bound);  }  kval[0]=maxK=1;  for (c1 = c2 = 1; c1 < n; c1++)  { while (winDepartBound[c2] < winEnd[c1]) {c2++;}    while (winDepartBound[c2-1]>winEnd[c1]) {c2--;}    kval[c1] = c2-c1;  }  for (c1 = 2; c1 < n-1; c1++)  { if (kval[c1]+1<kval[c1-1]) /* candidate for swap */    { for (spot = c1-1; kval[c1]+c1-spot<kval[spot] && spot>0; spot--);      bonus = kval[++spot];      penalty = 0;      for (c2 = spot-1; c2 > 0; c2--)      { if (kval[c2]==c1-c2) {penalty=c2;}      }      if (bonus-1 > kval[penalty]) /* do the swap */      { swaps = 1;        dm1 = kval[c1]+c1-spot;        dm2 = tour[c1];        dm3 = winBegin[c1];        dm4 = winEnd[c1];        dm5 = servTime[c1];        for (c2=c1; c2>spot; c2--)        { kval[c2]=kval[c2-1]-1;          tour[c2]=tour[c2-1];          winBegin[c2]=winBegin[c2-1];          winEnd[c2]=winEnd[c2-1];          servTime[c2]=servTime[c2-1];        }        kval[spot] = dm1;        tour[spot] = dm2;        winBegin[spot] = dm3;        winEnd[spot] = dm4;        servTime[spot] = dm5;        if (penalty) {kval[penalty] += 1;}      }    }  }  for (bound = inFinity, c1 = n-1; c1 > -1; c1--)  { bound = winDepartBound[c1] = _min(winBegin[c1]+servTime[c1],bound);  }  for (c1 = c2 = 1; c1 < n; c1++)  { while (winDepartBound[c2] < winEnd[c1]) {c2++;}    while (winDepartBound[c2-1]>winEnd[c1]) {c2--;}    kval[c1] = _min(k,c2-c1);    maxK = _max(maxK,c2-c1);  }//  printf("Maximum k requested was %d.\n",maxK);  maxK=_min(maxK,k);  kval[n]=1;  return (swaps);}/* ------------------------------------------------------------------- */signed char FixRvKval (costtype *winBegin, costtype *winEnd, costtype *servTime,                      int *kval, signed char k, nodeXtype n, nodeXtype *tour,                      costtype *winEndBound)/* improve array of "reverse" k-values by shuffling the tour order */{ signed int c1, c2, bonus, penalty, spot, swaps, dm1, dm2;  costtype bound, dm3, dm4, dm5;  signed char maxK;  swaps = 0;  for (bound = 0, c1 = 1; c1 < n; c1++)  { bound = winEndBound[c1] = _max(winEnd[c1],bound);  }  kval[0]=maxK=1;  for (c1 = c2 = 1; c1 < n; c1++)  { while (winEndBound[c2] < winBegin[c1]+servTime[c1]) {c2++;}    while (winEndBound[c2-1]>winBegin[c1]+servTime[c1] && c2>1) {c2--;}    kval[c1] = c1-c2+1;  }  for (c1 = n-2; c1 > 0; c1--)  { if (kval[c1]+1<kval[c1+1]) /* candidate for swap */    { for (spot = c1+1; kval[c1]+spot-c1<kval[spot] && spot<n; spot++);      bonus = kval[--spot];      penalty = 0;      for (c2 = spot+1; c2 < n; c2++)      { if (kval[c2]==c2-c1) {penalty=c2;}      }      if (bonus-1 > kval[penalty]) /* do the swap */      { swaps = 1;        dm1 = kval[c1]+spot-c1;        dm2 = tour[c1];        dm3 = winBegin[c1];        dm4 = winEnd[c1];        dm5 = servTime[c1];        for (c2=c1; c2<spot; c2++)        { kval[c2]=kval[c2+1]-1;          tour[c2]=tour[c2+1];          winBegin[c2]=winBegin[c2+1];          winEnd[c2]=winEnd[c2+1];          servTime[c2]=servTime[c2+1];        }        kval[spot] = dm1;        tour[spot] = dm2;        winBegin[spot] = dm3;        winEnd[spot] = dm4;        servTime[spot] = dm5;        if (penalty) {kval[penalty] += 1;}      }    }  }  for (bound = 0, c1 = 1; c1 < n; c1++)  { bound = winEndBound[c1] = _max(winEnd[c1],bound);  }  for (c1 = c2 = 1; c1 < n; c1++)  { while (winEndBound[c2] < winBegin[c1]+servTime[c1]) {c2++;}    while (winEndBound[c2-1]>winBegin[c1]+servTime[c1] && c2>1) {c2--;}    kval[c1] = _min(k,c1-c2+1);    maxK = _max(maxK,c1-c2+1);  }//  printf("Maximum k requested was %d.\n",maxK);  maxK=_min(maxK,k);  kval[n]=1;  return (swaps);}/* ------------------------------------------------------------------- */nodeXtype BuildSmallTWmatrix (signed char k, char contRule, char maketour,             costtype *winBeginRaw, costtype *winBegin, costtype *winEndRaw,             costtype *winEnd, costtype *servTimeRaw, costtype *servTime,	     costtype *shortMatrix, nodeXtype *tour, nodeXtype *levtour,             costtype targ, nodeXtype n, int *kval, signed char *localK,             long int *shrinkProbs, costtype *addlCost, char *compromise){ nodeXtype c1,c2,levn,z;  signed int c3;  costtype *walkPtr, *winMid, winBtemp, winEtemp;  int probtotal=0, maxcost=0, h, modified, modifcount;  winMid = addlCost;  if (maketour)  { for (c1=0; c1<n; c1++)    { winMid[c1] = (winBeginRaw[c1]+winEndRaw[c1])/2;}    SortPretour(winMid,tour,n);    tour[n]=tour[0];    modified = 1;    /* save time window and service time information relative to tour */    for (c1=0; c1<n; c1++)    { winBegin[c1] = winBeginRaw[tour[c1]];      winEnd[c1] = winEndRaw[tour[c1]];      servTime[c1] = servTimeRaw[tour[c1]];    }    winBegin[n] = winBegin[0];    winEnd[n]   = winEnd[0];    servTime[n] = 0;    /* establish a better order to minimize large k's */    modifcount=0;    while (modified && modifcount<8)    { modified = FixRvKval(winBegin,winEnd,servTime,kval,k,n,tour,winMid);      modified |= FixKval(winBegin, winEnd,servTime,kval,k,n,tour,winMid);      modifcount++;    }  }  else  { for (c1=0; c1<n; c1++)    { winBegin[c1] = winBeginRaw[tour[c1]];      winEnd[c1] = winEndRaw[tour[c1]];      servTime[c1] = servTimeRaw[tour[c1]];    }    winBegin[n] = winBegin[0];    winEnd[n]   = winEnd[0];    servTime[n] = 0;  }//localK[0] = CalcRvKval(winBegin, winEnd, servTime, kval, k, n, winMid);  localK[0] = CalcKval  (winBegin, winEnd, servTime, kval, k, n, winMid,    compromise);  levn = n;  for (c1=0,walkPtr=addlCost;c1<n;c1++,*(walkPtr++)=0);  if (contRule)  { if (targ) /* contracting arcs */    { switch (contRule)      { case 1: case 11:          for (c1=0; c1<n; shrinkProbs[c1++]=1);          probtotal=n;          break;        case 2: case 12:          printf("Not Available\n");exit(1);	  break;        case 3: case 13:          for (c1=0; c1<n; c1++)	  { shrinkProbs[c1] = h = theNorm(tour[c1],tour[c1+1]);	    if (h > maxcost) {maxcost=h;}	  }	  for (c1=0; c1<n; c1++)	  { probtotal+=(shrinkProbs[c1]=maxcost-shrinkProbs[c1]);	  }          break;//      case 4: case 14://        if (random()%k)//	  { for (c1=0; c1<n; c1++)//	    { for (h=0, c3=_max(0,c1+1-k); c3<_min(n,c1+k-1); c3++)//	      { for (c2=0; c2<proxlistsize && tour[c3]!=proxlist[c2]; c2++)//	        { if (c2<proxlistsize) {h++;}}//	      }//            probtotal+=(shrinkProbs[c1]=h);//	    }//	  }//        else /* 1/k chance we shrink nothing *///	  { for (probtotal=1, c1=0; c1<n; shrinkProbs[c1++]=0);//	  }//        break;      }      for (c1=0; c1<n; c1++)      { if (shrinkProbs[c1])        { shrinkProbs[c1] = targ*((shrinkProbs[c1]<<15)/probtotal);      } }      winBtemp=winBeginRaw[tour[0]];      winEtemp=winEndRaw[tour[0]];      for (levn=0,c1=0;c1<n;c1++)      { if ((random()&32767) >= shrinkProbs[c1])        { levtour[levn] = c1;	  winBegin[levn] = winBtemp;          winEnd[levn] = winEtemp;          servTime[levn++] = servTime[tour[c1]];          winBtemp=winBeginRaw[tour[c1+1]];          winEtemp=winEndRaw[tour[c1+1]];        }        else        { addlCost[levn] += theNorm(tour[c1],tour[c1+1])+servTime[tour[c1]];          winBtemp = _max(winBtemp,winBeginRaw[tour[c1+1]]-addlCost[levn]);          winEtemp = _min(winEtemp,winEndRaw[tour[c1+1]]-addlCost[levn]);	}      }      addlCost[0] += addlCost[levn];    }    else    { for (c1=0; c1<n; c1++) {levtour[c1]=c1;addlCost[c1]=0;}    }  }  /* construct short matrix indexed based on order of nodes in tour */  if (targ && levn < n)  { for (c1 = 0; c1 < levn; c1++)    { for (c2 = _max(0,c1-localK[0]+1); c2 < _min(levn+1,c1+2*localK[0]); c2++)      { shortMatrix[c1*(3*localK[0]-1)+c2-c1+localK[0]-1] = addlCost[c1]+	  theNorm(tour[levtour[c1]],tour[(c2)?((z=levtour[c2-1]+1)<n)?z:z-n:0]);    } }  }  else  { for (c1 = 0; c1 < levn; c1++)    { for (c2 = _max(0,c1-localK[0]+1); c2 < _min(levn+1,c1+2*localK[0]); c2++)      { shortMatrix[c1*(3*localK[0]-1)+c2-c1+localK[0]-1] =          theNorm(tour[c1],tour[c2<n?c2:c2-n]);  } } }  return (levn);}/* ------------------------------------------------------------------- */

⌨️ 快捷键说明

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