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

📄 emd.c

📁 earth mover s distance
💻 C
📖 第 1 页 / 共 2 页
字号:
   if (deltaMin == INFINITY)     {       mexErrMsgTxt("emd: Unexpected error in isOptimal.\n");       /*exit(0);*/     }      _EnterX->i = minI;   _EnterX->j = minJ;      /* IF NO NEGATIVE deltaMin, WE FOUND THE OPTIMAL SOLUTION */   return deltaMin >= -EPSILON * _maxC;/*   return deltaMin >= -EPSILON; */}/**********************    newSol**********************/static void newSol(){    int i, j, k;    double xMin;    int steps;    node2_t *Loop[2*MAX_SIG_SIZE1], *CurX, *LeaveX; #if DEBUG_LEVEL > 3    printf("EnterX = (%d,%d)\n", _EnterX->i, _EnterX->j);#endif    /* ENTER THE NEW BASIC VARIABLE */    i = _EnterX->i;    j = _EnterX->j;    _IsX[i][j] = 1;    _EnterX->NextC = _RowsX[i];    _EnterX->NextR = _ColsX[j];    _EnterX->val = 0;    _RowsX[i] = _EnterX;    _ColsX[j] = _EnterX;    /* FIND A CHAIN REACTION */    steps = findLoop(Loop);    /* FIND THE LARGEST VALUE IN THE LOOP */    xMin = INFINITY;    for (k=1; k < steps; k+=2)      {	if (Loop[k]->val < xMin)	  {	    LeaveX = Loop[k];	    xMin = Loop[k]->val;	  }      }    /* UPDATE THE LOOP */    for (k=0; k < steps; k+=2)      {	Loop[k]->val += xMin;	Loop[k+1]->val -= xMin;      }#if DEBUG_LEVEL > 3    printf("LeaveX = (%d,%d)\n", LeaveX->i, LeaveX->j);#endif    /* REMOVE THE LEAVING BASIC VARIABLE */    i = LeaveX->i;    j = LeaveX->j;    _IsX[i][j] = 0;    if (_RowsX[i] == LeaveX)      _RowsX[i] = LeaveX->NextC;    else      for (CurX=_RowsX[i]; CurX != NULL; CurX = CurX->NextC)	if (CurX->NextC == LeaveX)	  {	    CurX->NextC = CurX->NextC->NextC;	    break;	  }    if (_ColsX[j] == LeaveX)      _ColsX[j] = LeaveX->NextR;    else      for (CurX=_ColsX[j]; CurX != NULL; CurX = CurX->NextR)	if (CurX->NextR == LeaveX)	  {	    CurX->NextR = CurX->NextR->NextR;	    break;	  }    /* SET _EnterX TO BE THE NEW EMPTY SLOT */    _EnterX = LeaveX;}/**********************    findLoop**********************/static int findLoop(node2_t **Loop){  int i, steps;  node2_t **CurX, *NewX;  char IsUsed[2*MAX_SIG_SIZE1];    for (i=0; i < _n1+_n2; i++)    IsUsed[i] = 0;  CurX = Loop;  NewX = *CurX = _EnterX;  IsUsed[_EnterX-_X] = 1;  steps = 1;  do    {      if (steps%2 == 1)	{	  /* FIND AN UNUSED X IN THE ROW */	  NewX = _RowsX[NewX->i];	  while (NewX != NULL && IsUsed[NewX-_X])	    NewX = NewX->NextC;	}      else	{	  /* FIND AN UNUSED X IN THE COLUMN, OR THE ENTERING X */	  NewX = _ColsX[NewX->j];	  while (NewX != NULL && IsUsed[NewX-_X] && NewX != _EnterX)	    NewX = NewX->NextR;	  if (NewX == _EnterX)	    break; 	}     if (NewX != NULL)  /* FOUND THE NEXT X */       {	 /* ADD X TO THE LOOP */	 *++CurX = NewX;	 IsUsed[NewX-_X] = 1;	 steps++;#if DEBUG_LEVEL > 3	 printf("steps=%d, NewX=(%d,%d)\n", steps, NewX->i, NewX->j);    #endif       }     else  /* DIDN'T FIND THE NEXT X */       {	 /* BACKTRACK */	 do	   {	     NewX = *CurX;	     do 	       {		 if (steps%2 == 1)		   NewX = NewX->NextR;		 else		   NewX = NewX->NextC;	       } while (NewX != NULL && IsUsed[NewX-_X]);	     	     if (NewX == NULL)	       {		 IsUsed[*CurX-_X] = 0;		 CurX--;		 steps--;	       }	 } while (NewX == NULL && CurX >= Loop);	 #if DEBUG_LEVEL > 3	 printf("BACKTRACKING TO: steps=%d, NewX=(%d,%d)\n",		steps, NewX->i, NewX->j);    #endif           IsUsed[*CurX-_X] = 0;	   *CurX = NewX;	   IsUsed[NewX-_X] = 1;       }         } while(CurX >= Loop);    if (CurX == Loop)    {      mexErrMsgTxt( "emd: Unexpected error in findLoop!\n");      /*exit(1);*/    }#if DEBUG_LEVEL > 3  printf("FOUND LOOP:\n");  for (i=0; i < steps; i++)    printf("%d: (%d,%d)\n", i, Loop[i]->i, Loop[i]->j);#endif  return steps;}/**********************    russel**********************/static void russel(double *S, double *D){  int i, j, found, minI, minJ;  double deltaMin, oldVal, diff;  double Delta[MAX_SIG_SIZE1][MAX_SIG_SIZE1];  node1_t Ur[MAX_SIG_SIZE1], Vr[MAX_SIG_SIZE1];  node1_t uHead, *CurU, *PrevU;  node1_t vHead, *CurV, *PrevV;  node1_t *PrevUMinI, *PrevVMinJ, *Remember;  /* INITIALIZE THE ROWS LIST (Ur), AND THE COLUMNS LIST (Vr) */  uHead.Next = CurU = Ur;  for (i=0; i < _n1; i++)    {      CurU->i = i;      CurU->val = -INFINITY;      CurU->Next = CurU+1;      CurU++;    }  (--CurU)->Next = NULL;    vHead.Next = CurV = Vr;  for (j=0; j < _n2; j++)    {      CurV->i = j;      CurV->val = -INFINITY;      CurV->Next = CurV+1;      CurV++;    }  (--CurV)->Next = NULL;    /* FIND THE MAXIMUM ROW AND COLUMN VALUES (Ur[i] AND Vr[j]) */  for(i=0; i < _n1 ; i++)    for(j=0; j < _n2 ; j++)      {	float v;	v = _C[i][j];	if (Ur[i].val <= v)	  Ur[i].val = v;	if (Vr[j].val <= v)	  Vr[j].val = v;      }    /* COMPUTE THE Delta MATRIX */  for(i=0; i < _n1 ; i++)    for(j=0; j < _n2 ; j++)      Delta[i][j] = _C[i][j] - Ur[i].val - Vr[j].val;  /* FIND THE BASIC VARIABLES */  do    {#if DEBUG_LEVEL > 3      printf("Ur=");      for(CurU = uHead.Next; CurU != NULL; CurU = CurU->Next)	printf("[%d]",CurU-Ur);      printf("\n");      printf("Vr=");      for(CurV = vHead.Next; CurV != NULL; CurV = CurV->Next)	printf("[%d]",CurV-Vr);      printf("\n");      printf("\n\n");#endif       /* FIND THE SMALLEST Delta[i][j] */      found = 0;       deltaMin = INFINITY;            PrevU = &uHead;      for (CurU=uHead.Next; CurU != NULL; CurU=CurU->Next)	{	  int i;	  i = CurU->i;	  PrevV = &vHead;	  for (CurV=vHead.Next; CurV != NULL; CurV=CurV->Next)	    {	      int j;	      j = CurV->i;	      if (deltaMin > Delta[i][j])		{		  deltaMin = Delta[i][j];		  minI = i;		  minJ = j;		  PrevUMinI = PrevU;		  PrevVMinJ = PrevV;		  found = 1;		}	      PrevV = CurV;	    }	  PrevU = CurU;	}            if (! found)	break;      /* ADD X[minI][minJ] TO THE BASIS, AND ADJUST SUPPLIES AND COST */      Remember = PrevUMinI->Next;      addBasicVariable(minI, minJ, S, D, PrevUMinI, PrevVMinJ, &uHead);      /* UPDATE THE NECESSARY Delta[][] */      if (Remember == PrevUMinI->Next)  /* LINE minI WAS DELETED */	{	  for (CurV=vHead.Next; CurV != NULL; CurV=CurV->Next)	    {	      int j;	      j = CurV->i;	      if (CurV->val == _C[minI][j])  /* COLUMN j NEEDS UPDATING */		{		  /* FIND THE NEW MAXIMUM VALUE IN THE COLUMN */		  oldVal = CurV->val;		  CurV->val = -INFINITY;		  for (CurU=uHead.Next; CurU != NULL; CurU=CurU->Next)		    {		      int i;		      i = CurU->i;		      if (CurV->val <= _C[i][j])			CurV->val = _C[i][j];		    }		  		  /* IF NEEDED, ADJUST THE RELEVANT Delta[*][j] */		  diff = oldVal - CurV->val;		  if (fabs(diff) < EPSILON * _maxC)		    for (CurU=uHead.Next; CurU != NULL; CurU=CurU->Next)		      Delta[CurU->i][j] += diff;		}	    }	}      else  /* COLUMN minJ WAS DELETED */	{	  for (CurU=uHead.Next; CurU != NULL; CurU=CurU->Next)	    {	      int i;	      i = CurU->i;	      if (CurU->val == _C[i][minJ])  /* ROW i NEEDS UPDATING */		{		  /* FIND THE NEW MAXIMUM VALUE IN THE ROW */		  oldVal = CurU->val;		  CurU->val = -INFINITY;		  for (CurV=vHead.Next; CurV != NULL; CurV=CurV->Next)		    {		      int j;		      j = CurV->i;		      if(CurU->val <= _C[i][j])			CurU->val = _C[i][j];		    }		  		  /* If NEEDED, ADJUST THE RELEVANT Delta[i][*] */		  diff = oldVal - CurU->val;		  if (fabs(diff) < EPSILON * _maxC)		    for (CurV=vHead.Next; CurV != NULL; CurV=CurV->Next)		      Delta[i][CurV->i] += diff;		}	    }	}    } while (uHead.Next != NULL || vHead.Next != NULL);}/**********************    addBasicVariable**********************/static void addBasicVariable(int minI, int minJ, double *S, double *D, 			     node1_t *PrevUMinI, node1_t *PrevVMinJ,			     node1_t *UHead){  double T;    if (fabs(S[minI]-D[minJ]) <= EPSILON * _maxW)  /* DEGENERATE CASE */    {      T = S[minI];      S[minI] = 0;      D[minJ] -= T;     }  else if (S[minI] < D[minJ])  /* SUPPLY EXHAUSTED */    {      T = S[minI];      S[minI] = 0;      D[minJ] -= T;     }  else  /* DEMAND EXHAUSTED */    {      T = D[minJ];      D[minJ] = 0;       S[minI] -= T;     }  /* X(minI,minJ) IS A BASIC VARIABLE */  _IsX[minI][minJ] = 1;   _EndX->val = T;  _EndX->i = minI;  _EndX->j = minJ;  _EndX->NextC = _RowsX[minI];  _EndX->NextR = _ColsX[minJ];  _RowsX[minI] = _EndX;  _ColsX[minJ] = _EndX;  _EndX++;  /* DELETE SUPPLY ROW ONLY IF THE EMPTY, AND IF NOT LAST ROW */  if (S[minI] == 0 && UHead->Next->Next != NULL)    PrevUMinI->Next = PrevUMinI->Next->Next;  /* REMOVE ROW FROM LIST */  else    PrevVMinJ->Next = PrevVMinJ->Next->Next;  /* REMOVE COLUMN FROM LIST */}/**********************    printSolution**********************/static void printSolution(){  node2_t *P;  double totalCost;  totalCost = 0;#if DEBUG_LEVEL > 2  printf("SIG1\tSIG2\tFLOW\tCOST\n");#endif  for(P=_X; P < _EndX; P++)    if (P != _EnterX && _IsX[P->i][P->j])      {#if DEBUG_LEVEL > 2	printf("%d\t%d\t%f\t%f\n", P->i, P->j, P->val, _C[P->i][P->j]);#endif	totalCost += (double)P->val * _C[P->i][P->j];      }  printf("COST = %f\n", totalCost);}

⌨️ 快捷键说明

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