简介
实验需求:统计程序或者某个函数的运行时间
框架
#include <stdio.h>
#include <time.h> //计时必备
int main(){
clock_t start, stop;
double duration; //记录函数运行时间, 单位为秒.
start=clock();
MyFunction();//要进行计时的函数或者程序
stop=clock();
duration=((double)(stop-start))/CLOCKS_PER_SEC;
return 0;
}
Demo
我需要统计下面这个程序跑了多久
程序源代码
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "math.h"
#include "time.h"
#include <unistd.h>
#include <bits/stdc++.h>
#define CITY_NUM 38 //城市数,城市编号是0~CITY_NUM-1
#define POPSIZE 300 //种群个体数
#define MAXVALUE 10000000 //路径最大值上限
#define N 100000//需要根据实际求得的路径值修正
unsigned seed=(unsigned)time(0);
double Hash[CITY_NUM+1];
typedef struct CityPosition
{
double x;
double y;
}CityPosition;
CityPosition CityPos[38]={
{11003.611100,42102.500000},{11108.611100,42373.888900},{11133.333300,42885.833300},{11155.833300,42712.500000},{11183.333300,42933.333300},{11297.500000,42853.333300},{11310.277800,42929.444400},{11416.666700,42983.333300},{11423.888900,43000.277800},{11438.333300,42057.222200},{11461.111100,43252.777800},{11485.555600,43187.222200},{11503.055600,42855.277800},{11511.388900,42106.388900},{11522.222200,42841.944400},{11569.444400,43136.666700},{11583.333300,43150.000000},{11595.000000,43148.055600},{11600.000000,43150.000000},{11690.555600,42686.666700},{11715.833300,41836.111100},{11751.111100,42814.444400},{11770.277800,42651.944400},{11785.277800,42884.444400},{11822.777800,42673.611100},{11846.944400,42660.555600},{11963.055600,43290.555600},{11973.055600,43026.111100},{12058.333300,42195.555600},{12149.444400,42477.500000},{12286.944400,43355.555600},{12300.000000,42433.333300},{12355.833300,43156.388900},{12363.333300,43189.166700},{12372.777800,42711.388900},{12386.666700,43334.722200},{12421.666700,42895.555600},{12645.000000,42973.333300}
};
double CityDistance[CITY_NUM][CITY_NUM];//城市距离词典
typedef struct{
int colony[POPSIZE][CITY_NUM+1];//城市种群,默认出发城市编号为0,则城市编号的最后一个城市还应该为0
double fitness[POPSIZE];// 每个个体的适应值,即1/Distance[POPSIZE]
double Distance[POPSIZE];//每个个体的总路径
int BestRooting[CITY_NUM+1];//最优城市路径序列
double BestFitness;//最优路径适应值
double BestValue;//最优路径长度
int BestNum;
}TSP,*PTSP;
/*计算城市距离词典CityDistance[i][j]*/
void CalculatDist()
{
int i,j;
double temp1,temp2;
for(i=0;i<CITY_NUM;i++){
for(j=0;j<=CITY_NUM;j++){//最后一个城市还应该返回到出发节点
temp1=CityPos[j].x-CityPos[i].x;
temp2=CityPos[j].y-CityPos[i].y;
CityDistance[i][j]=sqrt(temp1*temp1+temp2*temp2);
}
}
}
/*数组复制*/
void copy(int a[],int b[])
{
int i=0;
for(i=0;i<CITY_NUM+1;i++)
{
a[i]=b[i];
}
}
/*用来检查新生成的节点是否在当前群体中,0号节点是默认出发节点和终止节点*/
bool check(TSP &city,int pop,int num,int k)
{
int i;
for(i=0;i<=num;i++){
if(k==city.colony[pop][i])
return true;//新生成节点存在于已经生成的路径中
}
return false;//新生成节点没有存在于已经生成的路径中
}
/****************种群初始化,即为city.colony[i][j]赋值****************/
void InitColony(TSP &city)
{
int i,j,r;
for(i=0;i<POPSIZE;i++){
city.colony[i][0]=0;
city.colony[i][CITY_NUM]=0;
city.BestValue=MAXVALUE;
city.BestFitness=0;//适应值越大越好
}
for(i=0;i<POPSIZE;i++)
{
for(j=1;j<CITY_NUM;j++)
{
r=rand()%(CITY_NUM-1)+1;//产生1~CITY_NUM-1之间的随机数
while(check(city,i,j,r))//随机产生城市序号,即为city.colony[i][j]赋值
{
r=rand()%(CITY_NUM-1)+1;
}
city.colony[i][j]=r;
}
}
}
/*计算适应值,考虑应该在这里面把最优选出来*/
void CalFitness(TSP &city)
{
int i,j;
int start,end;
int Best=0;
for(i=0;i<POPSIZE;i++){//求每个个体的总路径,适应值
city.Distance[i]=0;
for(j=1;j<=CITY_NUM;j++){
start=city.colony[i][j-1];end=city.colony[i][j];
city.Distance[i]=city.Distance[i]+CityDistance[start][end];//city.Distance[i]每个个体的总路径
}
city.fitness[i]=N/city.Distance[i];
if(city.fitness[i]>city.fitness[Best])//选出最大的适应值,即选出所有个体中的最短路径
Best=i;
}
copy(city.BestRooting,city.colony[Best]);//将最优个体拷贝给city.BestRooting
city.BestFitness=city.fitness[Best];
city.BestValue=city.Distance[Best];
city.BestNum=Best;
}
/****************选择算子:轮盘赌法****************/
void Select(TSP &city)
{
int TempColony[POPSIZE][CITY_NUM+1];
int i,j,t;
double s;
double GaiLv[POPSIZE];
double SelectP[POPSIZE+1];
double avg;
double sum=0;
for(i=0;i<POPSIZE;i++)
{
sum+=city.fitness[i];
}
for(i=0;i<POPSIZE;i++)
{
GaiLv[i]=city.fitness[i]/sum;
}
SelectP[0]=0;
for(i=0;i<POPSIZE;i++)
{
SelectP[i+1]=SelectP[i]+GaiLv[i]*RAND_MAX;
}
memcpy(TempColony[0],city.colony[city.BestNum],sizeof(TempColony[0]));//void *memcpy(void *dest, const void *src, size_t n)从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址的起始位置中
for(t=1;t<POPSIZE;t++)
{
double ran = rand() % RAND_MAX + 1;
s= (double) ran / 100.0;
for(i=1;i<POPSIZE;i++)
{
if(SelectP[i]>=s)
break;
}
memcpy(TempColony[t],city.colony[i-1],sizeof(TempColony[t]));
}
for(i=0;i<POPSIZE;i++)
{
memcpy(city.colony[i],TempColony[i],sizeof(TempColony[i]));
}
}
/****************交叉:头尾不变,中间打乱顺序交叉****************/
void Cross(TSP &city,double pc)//交叉概率是pc
{
int i,j,t,l;
int a,b,ca,cb;
int Temp1[CITY_NUM+1],Temp2[CITY_NUM+1];
for(i=0;i<POPSIZE;i++)
{
double s=((double)(rand()%RAND_MAX))/RAND_MAX;
if(s<pc)
{
cb=rand()%POPSIZE;
ca=cb;
if(ca==city.BestNum||cb==city.BestNum)//如果遇到最优则直接进行下次循环
continue;
l=rand()%19+1; //1-19
a=rand()%(CITY_NUM-l)+1; //1-37
memset(Hash,0,sizeof(Hash));//void *memset(void *s, int ch, size_t n);将s中当前位置后面的n个字节 用 ch 替换并返回 s 。
Temp1[0]=Temp1[CITY_NUM]=0;
for(j=1;j<=l;j++)//打乱顺序即随机,选出来的通过Hash标记为1
{
Temp1[j]=city.colony[cb][a+j-1]; //a+L=2~38 20~38
Hash[Temp1[j]]=1;
}
for(t=1;t<CITY_NUM;t++)
{
if(Hash[city.colony[ca][t]]==0)
{
Temp1[j++]=city.colony[ca][t];
Hash[city.colony[ca][t]]=1;
}
}
memcpy(city.colony[ca],Temp1,sizeof(Temp1));
}
}
}
/****************变异****************/
double GetFittness(int a[CITY_NUM+1])
{
int i,start,end;
double Distance=0;
for(i=0;i<CITY_NUM;i++)
{
start=a[i]; end=a[i+1];
Distance+=CityDistance[start][end];
}
return N/Distance;
}
/*对换变异*/
void Mutation(TSP &city,double pm)//变异概率是pm
{
int i,k,m;
int Temp[CITY_NUM+1];
for(k=0;k<POPSIZE;k++)
{
double s=((double)(rand()%RAND_MAX))/RAND_MAX;//随机产生概率0~1间
i=rand()%POPSIZE;//随机产生0~POPSIZE之间的数
if(s<pm&&i!=city.BestNum)//i!=city.BestNum,即保证最优的个体不变异
{
int a,b,t;
a=(rand()%(CITY_NUM-1))+1;
b=(rand()%(CITY_NUM-1))+1;
copy(Temp,city.colony[i]);
if(a>b)//保证让b>=a
{
t=a;
a=b;
b=t;
}
for(m=a;m<(a+b)/2;m++)
{
t=Temp[m];
Temp[m]=Temp[a+b-m];
Temp[a+b-m]=t;
}
if(GetFittness(Temp)<GetFittness(city.colony[i]))
{
a=(rand()%(CITY_NUM-1))+1;
b=(rand()%(CITY_NUM-1))+1;
//copy(Temp,city.colony[i]);
memcpy(Temp,city.colony[i],sizeof(Temp));
if(a>b)
{
t=a;
a=b;
b=t;
}
for(m=a;m<(a+b)/2;m++)
{
t=Temp[m];
Temp[m]=Temp[a+b-m];
Temp[a+b-m]=t;
}
if(GetFittness(Temp)<GetFittness(city.colony[i]))
{
a=(rand()%(CITY_NUM-1))+1;
b=(rand()%(CITY_NUM-1))+1;
//copy(Temp,city.colony[i]);
memcpy(Temp,city.colony[i],sizeof(Temp));
if(a>b)
{
t=a;
a=b;
b=t;
}
for(m=a;m<(a+b)/2;m++)
{
t=Temp[m];
Temp[m]=Temp[a+b-m];
Temp[a+b-m]=t;
}
}
}
memcpy(city.colony[i],Temp,sizeof(Temp));
}
}
}
void OutPut(TSP &city)
{
int i,j;
printf("The best solution : \n"); // 最佳路径为:
for(i=0;i<=CITY_NUM;i++)
printf("%5d",city.BestRooting[i]);
printf("\nThe best :%f\n",(city.BestValue)); //最佳路径值为:
}
int main()
{
TSP city;
double pcross,pmutation;//交叉概率和变异概率
int MaxEpoc;//最大迭代次数
int i;
srand(seed);
MaxEpoc=30000;
pcross=0.5; pmutation=0.05;
CalculatDist();//计算城市距离词典
InitColony(city);//生成初始种群
CalFitness(city);//计算适应值,考虑应该在这里面把最优选出来
for(i=0;i<MaxEpoc;i++)
{
Select(city);//选择(复制):轮盘赌法
Cross(city,pcross);//交叉
Mutation(city,pmutation);//变异
CalFitness(city);//计算适应值
}
OutPut(city);//输出
return 0;
}
原来的输出结果
> & 'd:\Program Files\VsCodeExtensions\ms-vscode.cpptools-1.0.1\debugAdapters\bin\WindowsDebugLauncher.exe' '--stdin=Microsoft-MIEngine-In-gwmw4k4o.kaj' '--stdout=Microsoft-MIEngine-Out-cxvhxnkf.pmt' '--stderr=Microsoft-MIEngine-Error-elsqe2hx.3e3' '--pid=Microsoft-MIEngine-Pid-cs45y1rf.15x' '--dbgExe=D:\ProgramFiles\mingw64\bin\gdb.exe' '--interpreter=mi'
The best solution :
0 9 13 20 28 29 31 34 36 37 32 33 35 30 26
27 23 21 24 25 22 19 14 12 15 17 18 16 10 11
7 8 6 5 4 2 3 1 0
The best :6692.891534
修改main之后的代码
除了main函数改变,其它部分不变(源代码中已经引入time.h)
int main()
{
clock_t start, stop;
double duration; //记录函数运行时间, 单位为秒.
start=clock();
TSP city;
double pcross,pmutation;//交叉概率和变异概率
int MaxEpoc;//最大迭代次数
int i;
srand(seed);
MaxEpoc=30000;
pcross=0.5; pmutation=0.05;
CalculatDist();//计算城市距离词典
InitColony(city);//生成初始种群
CalFitness(city);//计算适应值,考虑应该在这里面把最优选出来
for(i=0;i<MaxEpoc;i++)
{
Select(city);//选择(复制):轮盘赌法
Cross(city,pcross);//交叉
Mutation(city,pmutation);//变异
CalFitness(city);//计算适应值
}
OutPut(city);//输出
stop=clock();
duration=((double)(stop-start))/CLOCKS_PER_SEC;
std::cout<<"Time usage: "<<duration<<"s"<<std::endl;
return 0;
}
结果输出
The best solution :
0 1 3 2 4 5 6 8 7 10 11 16 18 17 15 12 14 19 22 25 24 21 23 27 26 35 30 33 32 37 36 31 34 29 28 20 13 9 0
The best :7280.840812
Time usage: 5.738s