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

📄 dynopt.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                                           */costtype Fiddle (signed char k, nodeXtype n, costtype *shortMatrix,                 signed char *j, signed char *minK, int *kval, int *depth,                 nodeXtype *succs, unsigned long int *succInx,                 nodeXtype *preds, unsigned long int *predInx,                 signed char *predLoc, nodeXtype *posttour,                 costtype *winBegin, costtype *winEnd, costtype *servTime,                 costtype *costsNow, costtype *costsNext, unsigned char *prevs,                 unsigned char *sublists, int worknodes)/* find a better tour, return in posttour.  The ordering in posttour *//* is relative to that in pretour.  The two must be compared to get *//* the absolute tour. *//* the distance of the tour is returned in shortMatrix[0] */{ signed int n1, n2, nn1, nn2;  unsigned long int c1, c2;  costtype *swapper, baseCost, h, h2;  unsigned long int backtracker, offset;  char *w1;  signed char offchar;  costsNow[0]=0;  for (n1=n2=0;n1<n;n1++,n2++)  { if (n2>=worknodes) {n2 = 0;}    for (c1=0;c1<bN[depth[n1+1]];c1++)    { costsNext[c1]=inFinity;    }    for (c1=0;c1<bN[depth[n1]];c1++)    { if (kval[j[c1]+n1] >= minK[c1])      { baseCost=costsNow[c1];        if (_timewindow && baseCost < inFinity) /* check against TW boundaries */        { if (baseCost < winBegin[j[c1]+n1]) {baseCost=winBegin[j[c1]+n1];}          else if (baseCost > winEnd[j[c1]+n1]) {baseCost=inFinity;}          baseCost+=servTime[j[c1]+n1];        }        if (baseCost<inFinity)        { for (c2=succInx[c1];succs[c2]<bN[depth[n1+1]];c2++)          { if ( (h=baseCost+shortMatrix[smINX(j[c1]+n1,j[succs[c2]]+n1+1,k)])                 < costsNext[succs[c2]])            { costsNext[succs[c2]]=h;              if (!_costonly) {prevs[n2*bN[k]+succs[c2]]=predLoc[c1];}            }          }        }      }    }    swapper = costsNext;    costsNext = costsNow;    costsNow = swapper;    if (!_costonly && prevs[n2*bN[k]] > 0)    { backtracker=0;      for (nn2=n2,nn1=n1,c1=0;           (nn1>n1-worknodes && backtracker >= (c1>0));           nn1--,nn2--,c1++)      { if (nn2<0) {nn2+=worknodes;}        offset=prevs[nn2*bN[k]+backtracker];        backtracker=preds[predInx[backtracker]+offset];        sublists[n1*(worknodes+1)+c1]=j[backtracker];      }      sublists[n1*(worknodes+1)+c1]=127;      if (backtracker) {_costonly = 1;}    }    else {sublists[n1*(worknodes+1)]=127;}  }  /* reconstruct tour */  if (!_costonly)  { for (n1=n-1;n1>=0;)    { if (sublists[n1*(worknodes+1)]!=127)      { for (nn1=n1,c1=0;(offchar=sublists[nn1*(worknodes+1)+c1])!=127;c1++)        { posttour[n1] = n1+offchar;          n1--;        }      }      else      { posttour[n1] = n1;        n1--;      }    }  }  else  { posttour[0]=n;  }  if (_timewindow) /* return distance in shortMatrix[0] */  { h = h2 = 0;    for (n1=1;n1<n;n1++)    { h += shortMatrix[smINX(posttour[n1-1],posttour[n1],k)];      h2 = _max(h2+shortMatrix[smINX(posttour[n1-1],posttour[n1],k)],               winBegin[posttour[n1]])         +servTime[posttour[n1]];    }    shortMatrix[0] = (h = h + shortMatrix[smINX(posttour[n-1],n,k)]);    h2 += shortMatrix[smINX(posttour[n-1],n,k)]              +servTime[n];    h = costsNow[0]+servTime[0];  }  else  { h = costsNow[0];  }  return(h);}/* ----------------------------------------------------------------- */#ifdef _shrinkcosttype Fiddlesym (signed char k, nodeXtype n, costtype **shortMatrix,                  signed char *j, signed char *minK, int *kval, int *depth,                  unsigned long int *succs, unsigned long int *succInx,                  unsigned long int *preds, unsigned long int *predInx,                  signed char *predLoc, nodeXtype *posttour, signed char *orientA,                  costtype *costsNow, costtype *costsNext, unsigned char *prevs,                  unsigned char *sublists, int worknodes)/* find a better tour, return in posttour.  The ordering in posttour *//* is relative to that in pretour.  The two must be compared to get *//* the absolute tour. */{ signed int n1, n2, nn1, nn2;  unsigned long int c1, c2, c3;  costtype *swapper, baseCost, h, h2;  unsigned long int backtracker, offset;  char *w1;  signed char offchar;  unsigned char orient;  FILE *myfile;  costsNow[0]=0;  costsNow[bN[k]]=inFinity;  for (n1=0; n1<(n+7)/8; orientA[n1++]=0);  for (n1=n2=0;n1<n;n1++,n2++)  { /*fprintf(stderr,"%3d ",n1);    for (c1=0;c1<1;c1++) {fprintf(stderr,"%d,",costsNow[c1]);}    if (1) {printf("\n");}*/    if (n2>=worknodes) {n2 = 0;}    for (c1=0;c1<bN[depth[n1+1]];c1++)    { costsNext[c1]=costsNext[c1+bN[k]]=inFinity;    }    for (c1=0;c1<bN[depth[n1]];c1++)    { if (kval[j[c1]+n1] >= minK[c1])      {for (c3=0;c3<2;c3++)       {baseCost=costsNow[c1+c3*bN[k]];        if (baseCost<inFinity)        { for (c2=succInx[c1];succs[c2]<bN[depth[n1+1]];c2++)          { if ( (h=baseCost+shortMatrix[2*c3][smINX(j[c1]+n1,j[succs[c2]]+n1+1,k)])                 < costsNext[succs[c2]])            { costsNext[succs[c2]]=h;              if (!_costonly) {prevs[n2*2*bN[k]+succs[c2]]=predLoc[c1]+128*c3;}            }            if ( (h=baseCost+shortMatrix[1+2*c3][smINX(j[c1]+n1,j[succs[c2]]+n1+1,k)])                 < costsNext[bN[k]+succs[c2]])            { costsNext[bN[k]+succs[c2]]=h;              if (!_costonly) {prevs[n2*2*bN[k]+bN[k]+succs[c2]]=predLoc[c1]+128*c3;}            }          }        }      }}    }    swapper = costsNext;    costsNext = costsNow;    costsNow = swapper;    if (!_costonly && prevs[n2*2*bN[k]] > 0)    { orient=backtracker=0;      for (nn2=n2,nn1=n1,c1=0;(nn1>n1-worknodes && backtracker >= (c1>0));nn1--,nn2--,c1++)      { if (nn2<0) {nn2+=worknodes;}        offset=prevs[nn2*2*bN[k]+orient*bN[k]+backtracker];        orient=offset>>7;        offset&=127;        backtracker=preds[predInx[backtracker]+offset];        sublists[n1*(2*worknodes+2)+c1*2]=j[backtracker];        sublists[n1*(2*worknodes+2)+1+c1*2]=orient;      }      sublists[n1*(2*worknodes+2)+c1*2]=127;      if (backtracker) {_costonly = 1;}    }    else {sublists[n1*(2*worknodes+2)]=127;}  }  if (!_costonly)  { for (n1=n-1;n1>=0;)    { if (sublists[n1*(2*worknodes+2)]!=127)      { for (nn1=n1,c1=0;(offchar=sublists[nn1*(2*worknodes+2)+c1*2])!=127;c1++)        { posttour[n1] = n1+offchar;          if (sublists[nn1*(2*worknodes+2)+1+c1*2])          { orientA[n1>>3] |= (1<<(n1&7));          }          n1--;        }      }      else      { posttour[n1] = n1;        n1--;      }    }  }  else  { posttour[0]=n;  }  h = costsNow[0];  return(h);}#endif/* ----------------------------------------------------------------- */#ifdef _twDist#define _packed (bitsforpred > 0)costtype FiddleDual (signed char k, nodeXtype n, costtype *shortMatrix,		  signed char *j, signed char *minK, int *kval,		  int *depth, unsigned long int *succs,		  unsigned long int *succInx, unsigned long int *preds,		  unsigned long int *predInx, signed char *predLoc,		  nodeXtype *posttour, costtype *winBegin, costtype *winEnd,                  costtype *servTime,                  costtype *costsNow, costtype *costsNext, costtype *timeNow,                  costtype *timeNext, unsigned char *prevs,		  unsigned char *sublist, int worknodes,                  char q, char bitsforpred, char *compromise)/* find a better tour, return in posttour.  The ordering in posttour *//* is relative to that in pretour.  The two must be compared to get *//* the absolute tour. */{ signed int n1, n2, nn1, nn2;  unsigned long int c1, c2, c3, c4, dest;  costtype *swapper, basecost, basetime, mycost, mytime, h, h2;  unsigned long int backtracker, backdepth, offset;  char *w1;  signed char offchar;  FILE *myfile;  unsigned char *prevThick, myplace, mythick, maxThick, maxThickTour, stillgoing;  maxThick = maxThickTour = 0;  if (!_packed) {prevThick = prevs+(q*worknodes*bN[k]);}  for (n1=0;n1<q;n1++)  { costsNow[n1]=timeNow[n1]=0;  }  for (n1=n2=0;n1<n;n1++,n2++)  { if (n2>=worknodes) {n2 = 0;}    for (c1=0;c1<bN[depth[n1+1]]*q;c1++)    { costsNext[c1]=timeNext[c1]=inFinity;    }    for (c1=0;c1<bN[depth[n1]];c1++)    { if (kval[j[c1]+n1] >= minK[c1])       { for (c3=0;             (c3<q && (basecost=costsNow[c3+c1*q]+servTime[j[c1]+n1])<inFinity);             c3++)        { basetime=timeNow[c3+c1*q]+servTime[j[c1]+n1];          for (c2=succInx[c1];(dest=succs[c2])<bN[depth[n1+1]];c2++)	  { mycost=basecost+              (h=shortMatrix[_max(0,smINX(j[c1]+n1,j[dest]+n1+1,k))]);            mytime=_max(basetime+h,winBegin[j[dest]+n1+1]);            myplace=predLoc[c1];	    if (_packed) {myplace |= (c3<<bitsforpred);}	    else {mythick=c3;}            if (mytime <= winEnd[j[dest]+n1+1])	    { for (c4=0,stillgoing=1;c4<q && stillgoing;)	      { if (mycost >= costsNext[dest*q+c4] && mytime >= timeNext[dest*q+c4])		  {stillgoing=0;}                else if (mycost >= inFinity)                  {stillgoing=0;}                else if (mycost < costsNext[dest*q+c4])		{                  h = costsNext[dest*q+c4];                  costsNext[dest*q+c4] = mycost;                  mycost = h;                  h = timeNext[dest*q+c4];                  timeNext[dest*q+c4] = mytime;                  mytime = h;                  if (!_costonly)		  { h = prevs[c4*worknodes*bN[k]+n2*bN[k]+dest];                    prevs[c4*worknodes*bN[k]+n2*bN[k]+dest] = myplace;                    myplace = h;                    if (!_packed)		    { h = prevThick[c4*worknodes*bN[k]+n2*bN[k]+dest];                      prevThick[c4*worknodes*bN[k]+n2*bN[k]+dest] = mythick;                      mythick = h;		  } }                }                else {c4++;}              }              maxThick = _max(c4,maxThick);    } } } } }    swapper = costsNext;    costsNext = costsNow;    costsNow = swapper;    swapper = timeNext;    timeNext = timeNow;    timeNow = swapper;    if (!_costonly && (prevs[n2*bN[k]]>0 || (!_packed && prevThick[n2*bN[k]]>0)))    { backtracker=backdepth=0;      for (nn2=n2,nn1=n1,c1=0;(nn1>n1-worknodes && backtracker+backdepth >= (c1>0));nn1--,nn2--,c1++)      {         if (nn2<0) {nn2+=worknodes;}        offset=prevs[backdepth*worknodes*bN[k]+nn2*bN[k]+backtracker];	if (_packed) {backdepth=offset>>(bitsforpred);offset&=((1<<bitsforpred)-1);}	else {backdepth=prevThick[backdepth*worknodes*bN[k]+nn2*bN[k]+backtracker];}        backtracker=preds[predInx[backtracker]+offset];        sublists[n1*(worknodes+1)+c1]=j[backtracker];        maxThickTour=_max(maxThickTour,backdepth);      }      sublists[n1*(worknodes+1)+c1]=127;      if (backtracker || backdepth) {_costonly = 1;}    }    else {sublists[n1*(worknodes+1)]=127;}  }  if (maxThick==q)  { compromise[0]|=1;    printf("q must be larger to guarantee optimality.\n");  }  else  { printf("Maximum Thickness in graph was %d\n",maxThick+1);  }  if (!_costonly)  { for (n1=n-1;n1>=0;)    { if (sublists[n1*(worknodes+1)]!=127)      { for (nn1=n1,c1=0;(offchar=sublists[nn1*(worknodes+1)+c1])!=127;c1++)        { posttour[n1] = n1+offchar;          n1--;        }      }      else      { posttour[n1] = n1;        n1--;      }    }  }  else  { posttour[0]=n;  }//  printf("Maximum Thickness in tour was %d\n",maxThickTour+1);  h = costsNow[0]+servTime[0];  return(h);}#endif

⌨️ 快捷键说明

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