说三道四技术文摘-感悟人生的经典句子
说三道四 > 文档快照

HELP!一道规划问题的优化!源代码

编辑:说三道四文库 发布时间:2018-07-19 07:38
HTML文档下载 WORD文档下载 PDF文档下载
##include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <LIMITS.H>
#include <time.h>

int in[1000][5];
int person[1000][5];
int tempperson[1000][5];
int group[1000];
int tempgroup[1000];
int daifenzu[1000];
int data[1000][2];


int m,n,p;
int averGMAT;
m=50;n=5;p=10;

int getmark();
void init();
void initperson();
void saveperson();
void initgroup();
void initdaifenzu();

void printFile1();
void printFile2();
void trace();
void swap();
void sort();


void main()
{
time_t endTime2,startTime;
int i,j,r,temp;

    int number;
int loop,summark1,summark2;

    time (&startTime);

    printf("Please waiting........... \n");
    
init(m);
 
    temp=0;
for(i=0;i<m;i++)
{
  temp+=in[i][4];
    }
    averGMAT=temp/m;

srand( (unsigned)time( NULL ) );
    summark1=-1; 

    for(loop=1;loop<=50;loop++)
{
initperson(m);
initgroup(m);
        initdaifenzu(m);

group[0]=rand()%(m-1);
        daifenzu[group[0]]=-1;
for(i=0;i<5;i++)
{
person[0][i]=in[group[0]][i];
}
        for(r=1;r<m;r++)
{
    if((r%p)!=0)
{
for(i=0;i<m;i++)
{
         data[i][0]=INT_MAX;
                 data[i][1]=0;   
}
for(j=0;j<m;j++)
{
  if(daifenzu[j]!=-1)
  {
for(i=0;i<5;i++)
person[r][i]=in[j][i];
data[j][0]=getmark(person,m,n,p);
data[j][1]=j;   
  }   
}
sort (data, 0, m-1);
number=(int)((m-r)*0.4-1);
if(number>0)
{
number=rand()%(number);
}
else
{
number=0;
}
group[r]=data[number][1];
daifenzu[group[r]]=-1;
for(i=0;i<5;i++)
person[r][i]=in[group[r]][i];

}
else
{
  do
  {
    temp=rand()%(m-1);
  }
  while (daifenzu[temp]==-1);
        
  group[r]=temp;
              daifenzu[group[r]]=-1;
      for(i=0;i<5;i++)
  {
       person[r][i]=in[group[r]][i];
  }  
}

}
//至此,得到一个可行解。具体数据保存在person[][],person ID在group[]中

saveperson(m); 
trace(m,n,p);
summark2=getmark(person,m,n,p);
if((summark2<summark1)||(summark1==-1))
{
summark1=summark2;
printFile1(loop,m,n,p);
printFile2(m,n,p);
}

}    
    time (&endTime2);
    printf("\n\nOK!\n");
    printf ("\n共进行了%d遍循环运算",loop-1);
printf (",总耗时 :\t%ld seconds\n", (long)(endTime2-startTime));
    printf("\n\n分组运算结果保存在result.txt文件中!");
}


void init(int m)
{
int i,j;
FILE *fp;
fp=fopen("data.txt","r");
if(fp==NULL)
{
printf("can not open file\n");
return;
}

for(i=0;i<m;i++)
{
for(j=0;j<5;j++)
{
fscanf(fp,"%d",&in[i][j]);
}
}
fclose(fp);

}

void initperson(int m)
{
int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<5;j++)
{
person[i][j]=0;
}
}
}

void saveperson(int m)//共有m个人
{
int i,j;
for(i=0;i<m;i++)
{
for(j=0;j<5;j++)
{
tempperson[i][j]=person[i][j];
}
        tempgroup[i]=group[i];
}
}


void initgroup(int m)
{
int i;
for(i=0;i<m;i++)
{
group[i]=0;
}
}
void initdaifenzu(int m)
{
int i;
for(i=0;i<m;i++)
{
daifenzu[i]=0;
}
}

int getmark(int per[][5],int m,int n,int p)
{
int i,j,num,mark;

mark=0;
for(j=0;j<n;j++)
{
for(num=0,i=j*p;i<(j+1)*p;i++)
{
if(per[i][0]==1)
{
 num++;
}
}
if(num>2)
{
mark+=((num-2)*10);
}
        else if(num<1)
{
mark+=((1-num)*10);


for(num=0,i=j*p;i<(j+1)*p;i++)
{
if(per[i][1]==1)
{
 num++;
}
}
if(num<1)
{
mark+=(1-num)*5;
        }

for(num=0,i=j*p;i<(j+1)*p;i++)
{
if(per[i][2]==1)
{
 num++;
}
}
if(num!=2)
{
mark+=(abs(num-2)*8);
}

for(num=0,i=j*p;i<(j+1)*p;i++)
{
if(per[i][3]==1)
{
 num++;
}
}
if(num<2)
{
mark+=(2-num)*12;
}

for(num=0,i=j*p;i<(j+1)*p;i++)
{
 num+=per[i][4];
}
mark+=(abs(num/p-averGMAT))*1;
}

return mark;
}
void printFile1(int ii,int m,int n,int p)
int i,j;
FILE *fp;
fp=fopen("result.txt","w");
if(fp==NULL)
{
printf("can not ceate file\n");
return;
}
fprintf(fp,"该结果是在%d次求得的!\n\n",ii);
fprintf(fp,"%d个人分成%d个小组,使得总罚金最少的一组可行解是:",m,n);
fprintf(fp,"\nperson id:          person:\n");

for(i=0;i<m;i++){
fprintf(fp," \t%d \t",tempgroup[i]);
    fprintf(fp,"        \t");
for(j=0;j<5;j++)
fprintf(fp," %d ",tempperson[i][j]);
fprintf(fp,"\n");
if((i+1)%p==0) fprintf(fp,"\n");
    }
    fprintf(fp,"\n");
fprintf(fp,"总罚金额是:");
fprintf(fp,"%d",getmark(tempperson,m,n,p));
fclose(fp);
}

void printFile2(int m,int n,int p)
{
int i,j;
FILE *fp;
fp=fopen("result.txt","a");
if(fp==NULL)
{
printf("can not open file\n");
return;
}
    fprintf(fp,"\n\n...........................................\n\n"); 
fprintf(fp,"%d个人分成%d个小组,为使得总罚金最少。优化后的一组解是:",m,n);
fprintf(fp,"\nperson id:          person:\n");

for(i=0;i<m;i++){
fprintf(fp," \t%d \t",group[i]);
    fprintf(fp,"        \t");
for(j=0;j<5;j++)
fprintf(fp," %d ",person[i][j]);
fprintf(fp,"\n");
if((i+1)%p==0) fprintf(fp,"\n");
    }
    fprintf(fp,"\n");
fprintf(fp,"总罚金额是:");
fprintf(fp,"%d",getmark(person,m,n,p));
fclose(fp);
}


void trace(int m,int n,int p)//共m个人分n组,每组p个人
//每一个人都要和其他人交换一次。同组中的交换不影响罚金结果,只会降低效率,
{
int mark1,mark2;
int i,j,sign;

mark1=getmark(person,m,n,p);

for(i=0;i<m;i++)
{
for(j=0;j<m;j++)
{
swap(i,j);
        data[j][0]=getmark(person,m,n,p);
data[j][1]=j;
swap(i,j);
}
      sort(data,0,m-1);
        mark2=data[0][0];
sign=data[0][1];
if(mark2<mark1)
{
mark1=mark2;
swap(i,sign);
}
}
}


void swap (int a, int b)//交换
{
    int temp;
   
temp = group[a];
    group[a] = group[b];
group[b] = temp;

temp = person[a][0];
    person[a][0] = person[b][0];
person[b][0] = temp;
    
temp = person[a][1];
    person[a][1] = person[b][1];
person[b][1] = temp;

temp = person[a][2];
    person[a][2] = person[b][2];
person[b][2] = temp;

temp = person[a][3];
    person[a][3] = person[b][3];
person[b][3] = temp;

temp = person[a][4];
    person[a][4] = person[b][4];
person[b][4] = temp;


}
void sort (int a[][2], int m, int n)
{
 
   int i,j,temp,flag;
   for (i=m; i<n;i++)
   {
flag=1;
        for (j=n-1;j>=i;j--)
{
if(a[j+1][0]<a[j][0])
{
  temp=a[j][0]; 
  a[j][0]=a[j+1][0]; 
  a[j+1][0]=temp; 

  temp=a[j][1]; 
  a[j][1]=a[j+1][1]; 
  a[j+1][1]=temp; 
  flag=0;
}
}
        if(flag==1) return; 
   }
}
太恐怖了,你能否说一下原来的要求?也就是说,解决什么问题?这么长的代码,没有一点目的,叫人家怎么看呢?
题目描述见另一个贴子:

“HELP!一道规划问题的优化! 问题描述(太长了,只好发到2个贴子)”
你的寻优过程,就只是一个贪心而已啊,没有理论支持,你的寻优过程是最优的。

只不过用了50次找最优,造这样看。还不如用遗传算法,或模拟退火算法寻优还好些。

还有你Help什么啊?
这个算法几乎无论是50次还是1次,找到的最优解都是108。
而我已知的一种分组是88
备案号:鲁ICP备13029499号-2 说三道四 www.s3d4.cn 说三道四技术文摘