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

📄 dmfunc.c

📁 《C程序员成长攻略》-黎陡-源代码,书中所有源码
💻 C
字号:
/*---------------------------DMFunc.c-----------------------------------*/
/*-----------算法相关函数----------*/
/*-----------求和--------------*/
float Sigama(float a[],int L)
{  
  /*------求得数组a[]中从下标0到L-1的元素之和。函数返回该和值-----*/
   int i;
   float temp=0;
   for(i=0;i<L;i++)
     temp+=a[i];
   return temp;
}

/*-----------求最大值--------*/
float findMax(float a[],int L)
{ 
  /*求得数组a[]中从下标0到L-1各元素的最大值。函数返回该最大值*/
  int i;
  float temp;
  for(i=0;i<L-1;i++) /*冒泡排序一轮将各元素的最大值交换到a[L-1]中*/
    if(a[i]>a[i+1])
       {  temp=a[i];
	      a[i]=a[i+1];
	      a[i+1]=temp;
       }
  return a[L-1];    /*----返回最大值----*/
}

/*------------求最小值--------*/
float findMin(float a[],int L)
{ 
  int i;
  float temp;
  for(i=0;i<L-1;i++) /*--冒泡排序一轮将各元素的最大值交换到a[L-1]中---*/
    if(a[i]<a[i+1])
       {  
          temp=a[i];
	      a[i]=a[i+1];
	      a[i+1]=temp;
       }
  return a[L-1];
}

/*--------------对各个方案的贴近度和距离进行排序------------------*/
void Taxis(struct Target Tank[],int pNum)
{ /*----在定义的结构struct Target中定义了指示当前方案的贴近度和距离在各个方案中按大小排序所得到的序号TIndex和dIndex。此函数将各方案的TIndex和dIndex分别进行排序,得到其相应的排序号----*/
  int i,j;
  for(i=0;i<pNum;i++)
/*从第一个开始,将第i个和第i+1个进行比较,若i的距离(或贴近度)大,*/
   for(j=i+1;j<pNum;j++)
/* 则i的距离序号(或贴近度序号)加1,否则,i+1的距离序号-*/
   {                        /*-(或贴近度序号)加1-------------*/
    if(Tank[i].d>Tank[j].d)
      Tank[i].dIndex++;
    else 
      Tank[j].dIndex++;
    if(Tank[i].T>Tank[j].T)
      Tank[i].TIndex++;
    else 
      Tank[j].TIndex++;
   }
}

/*-----------获得当前各辆坦克的指标数据---------------------*/
void GetTData()
{
  int i,d=40;
  float x,y;
  for(i=0;i<n;i++)
  {
     x=Tank[i].x;
     y=Tank[i].y;
     Tank[i].distance=sqrt((x-emp.x)*(x-emp.y)+(y-emp.y)*(y-emp.y));
     Tank[i].distance=1-Tank[i].distance/1000;  /*求得距离的指标*/
     switch(Tank[i].color)         /*根据目标颜色确定其攻击力值*/
     {
	 case WHITE:
	      Tank[i].power=0.5;
	      break;
	 case YELLOW:
	      Tank[i].power=0.6;
	      break;
	 case RED:
	      Tank[i].power=0.7;
	      break;
     }
     switch(Tank[i].direction)    /*根据目标当前方向值来定量*/
     {
	 case 1:  /*方向为右时*/  
	     if(Tank[i].x<emp.x-emp.width && Tank[i].y>emp.y-emp.lenth)
/*如果目标位于大本营水平左侧*/
		Tank[i].inva=0.9; 
             else
	     if(Tank[i].x>emp.x+emp.width && Tank[i].y>emp.y-emp.lenth)
/*如果目标位于大本营水平右侧*/
                Tank[i].inva=0.7;
             else
if(Tank[i].y<emp.y-emp.lenth && Tank[i].y>emp.y-emp.lenth-4*Tank[i].r)
/*如果目标位于大本营上沿宽度为二倍坦克直径的水平区域带*/
                Tank[i].inva=0.7;
	     else
                Tank[i].inva=0.5; /*目标位于其他区域*/
             break;
	 case -1: /*方向为左时*/
	     if(Tank[i].x>emp.x+emp.width && Tank[i].y>emp.y-emp.lenth)
/*如果目标位于大本营水平右侧*/
		Tank[i].inva=0.9;
             else
	     if(Tank[i].x<emp.x-emp.width && Tank[i].y>emp.y-emp.lenth)
/*如果目标位于大本营水平左侧*/
                Tank[i].inva=0.7;
             else 
      if(Tank[i].y<emp.y-emp.lenth && Tank[i].y>emp.y-emp.lenth-4*Tank[i].r)
/*如果目标位于大本营上沿宽度为二倍坦克直径的水平区域带*/ 
                Tank[i].inva=0.7;
	     else
		Tank[i].inva=0.5; /*目标位于其他区域*/
	     break;
	 case 2:  /*方向为下时*/
	     if(Tank[i].x<emp.x-emp.width && Tank[i].x>emp.x+emp.width)
/*如果目标位于大本营正上方*/
		Tank[i].inva=0.9;
	     else 
		Tank[i].inva=0.6; /*目标位于其他区域*/
	     break;
	 case -2: /*方向为上时*/
	     if(Tank[i].x<emp.x-emp.width && Tank[i].x>emp.x+emp.width)
/*如果目标位于大本营正上方*/
		Tank[i].inva=0.7; 
	     else
		Tank[i].inva=0.1; /*目标位于其他区域*/
	     break;
	 case 3:  /*方向为右下时*/
      if(Tank[i].x<emp.x-emp.width && Tank[i].y>emp.y-emp.lenth-4*Tank[i].r)
/*如果目标位于从距大本营上沿为二倍坦克直径处到演示框低部的左侧水平带*/
	        Tank[i].inva=0.8;
             else 
	  if(Tank[i].x>emp.x+emp.width && Tank[i].y>emp.y-emp.lenth-4*Tank[i].r)
/*如果目标位于从距大本营上沿为二倍坦克直径处到演示框低部的右侧水平带*/
                Tank[i].inva=0.6;
             else
		Tank[i].inva=0.4; /*目标位于其他区域*/
	     break;
	 case -3: /*方向为左上时*/
      if(Tank[i].x>emp.x+emp.width && Tank[i].y>emp.y-emp.lenth-4*Tank[i].r) 
/*如果目标位于从距大本营上沿为二倍坦克直径处到演示框低部的右侧水平带*/
	        Tank[i].inva=0.8;
             else
	 if(Tank[i].x<emp.x-emp.width && Tank[i].y>emp.y-emp.lenth-4*Tank[i].r)
/*如果目标位于从距大本营上沿为二倍坦克直径处到演示框低部的左侧水平带*/
                Tank[i].inva=0.6;
             else
		Tank[i].inva=0.1; /*目标位于其他区域*/
	     break;
	 case 4:  /*方向为右上时*/
	  if(Tank[i].x<emp.x-emp.width && Tank[i].y>emp.y-emp.lenth-4*Tank[i].r)
/*如果目标位于从距大本营上沿为二倍坦克直径处到演示框低部的左侧水平带*/
	        Tank[i].inva=0.8;
             else 
	  if(Tank[i].x>emp.x+emp.width && Tank[i].y>emp.y-emp.lenth-4*Tank[i].r)
/*如果目标位于从距大本营上沿为二倍坦克直径处到演示框低部的右侧水平带*/
                Tank[i].inva=0.6;
             else
		Tank[i].inva=0.1; /*目标位于其他区域*/
	     break;
	 case -4: /*方向为左下时*/
	  if(Tank[i].x>emp.x+emp.width && Tank[i].y>emp.y-emp.lenth-4*Tank[i].r) 
/*如果目标位于从距大本营上沿为二倍坦克直径处到演示框低部的右侧水平带*/
	        Tank[i].inva=0.8;
             else
	 if(Tank[i].x<emp.x-emp.width && Tank[i].y>emp.y-emp.lenth-4*Tank[i].r)
/*如果目标位于从距大本营上沿为二倍坦克直径处到演示框低部的左侧水平带*/
                Tank[i].inva=0.6;
             else
		Tank[i].inva=0.4; /*目标位于其他区域*/
	     break;
     }
  }
}

/*-----------第一步:构造初始指标判断矩阵----------------------------*/
void FormMatrix()
{ int i,j;
  float temp[mMax][nMax]={{0.3,0.9,0.5,0.9},
			  {0.1,0.8,0.4,0.7},
			  {0.5,0.9,0.6,0.3}};
  GetTData();
  for(j=0;j<n;j++)
  {
   r[0][j]=Tank[j].distance;
   r[1][j]=Tank[j].inva;
   r[2][j]=Tank[j].power;
  }
  /*for(i=0;i<m;i++)
  {  
     for(j=0;j<n;j++)
       cprintf("%8.4f",r[i][j]);
     cprintf("\n");
   }*/
}

/*-----------第二步:构造加熵权的标准化指标矩阵A---------------------*/
void FormEntropyMatrix()
{  
   int i,j;
   float temp=0,k;
   k=1/log(n);
  for(i=0;i<m;i++)
  {
    for(j=0;j<n;j++)
   { 
     if(Sigama(&r[i][0],n)==0)
     f[i][j]=0;
     f[i][j]=r[i][j]/Sigama(&r[i][0],n);
     temp+=f[i][j]*log(f[i][j]);
   }
    H[i]=0-k*temp;
    temp=0;
  }
  for(i=0;i<m;i++)
  Omiga[i]=(1-H[i])/(m-Sigama(&H[0],m));

  for(i=0;i<m;i++)
    for(j=0;j<n;j++)
      A[i][j]=Omiga[i]*r[i][j];

}

/*-----------第三步:找出理想点X[m]----------------*/
void FindPerfectPoint()
{ 
  float a[mMax][nMax];
  int i,j;
  for(i=0;i<m;i++)
    for(j=0;j<n;j++)
      a[i][j]=A[i][j];
  for(i=0;i<m;i++)
    X[i]=findMax(&a[i][0],n);
}

/*-----------第四步:计算被评方案到理想点的距离Tank[j].d-----------------*/
void CalDistance()
{ 
  int i,j;
  float sigama=0;
  for(j=0;j<n;j++)
  {  
     for(i=0;i<m;i++)
     sigama+=(A[i][j]-X[i])*(A[i][j]-X[i]);
     Tank[j].d=sqrt(sigama);
     sigama=0;
   }
}

/*-----------第五步:计算被评方案与理想点的贴近度Tank[j].T---------------*/
void CalCloseDegree()
{  
   int i,j;
   float sigama1=0,sigama2=0;
   for(j=0;j<n;j++)
    { 
      for(i=0;i<m;i++)
      { 
        sigama1+=A[i][j]*X[i];
	    sigama2+=X[i]*X[i];
       }
      Tank[j].T=1-sigama1/sigama2;
      sigama1=0;
      sigama2=0;
    }
}

/*-----------第六步:根据贴近度和距离排序,找出最优目标---------*/
void FindBestT()
{ 
  int i,j,best_flag,second_flag;
  struct Target temp;
  best=0;
  for(i=0;i<n;i++)
  { 
     Tank[i].dIndex=Tank[i].TIndex=1;
     Tank[i].pIndex=1;
  }
  Taxis(&Tank[0],n);/*--------将贴近度和距离排序----------------*/
  for(i=0;i<n;i++)  /*---按贴近度将各方案进行排序--------*/
  { 
     for(j=i+1;j<n;j++)
     { 
        if(Tank[i].TIndex>Tank[j].TIndex)
	    {    
           Tank[i].pIndex++;
	     }
	    else 
          if(Tank[i].TIndex==Tank[j].TIndex)
/*--若贴近度相同则比较距离------*/
	        if(Tank[i].dIndex>Tank[j].dIndex)
		    { 
               Tank[i].pIndex++;
		    }
	       else 
               Tank[j].pIndex++;
	else
       if(Tank[i].TIndex<Tank[j].TIndex)
	     Tank[j].pIndex++;
	}
   }

  for(i=0;i<n;i++)
  {
     if(Tank[i].pIndex==1)
	{
	   best=i;       /*--------找出最优方案,获得其方案序号---------*/
	   best_flag=1;
	   break;
	}
  }
}

/*--------------------------------------------------------------*/
void Arithmetic()
{
    if(n==1)
    {
       best=0;
       return;
    }
    FormMatrix();
    FormEntropyMatrix();
    FindPerfectPoint();
    CalDistance();
    CalCloseDegree();
    FindBestT();
}

⌨️ 快捷键说明

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