一、遗传算法的基本描述
遗传算法(Genetic Algorithm,GA)是通过模拟自然界生物进化过程来求解优化问题的一类自组织、自适应的人工智能技术。它主要基于达尔文的自然进化论和孟德尔的遗传变异理论。多数遗传算法的应用是处理一个由许多个体组成的群体,其中每个个体表示问题的一个潜在解。对个体存在一个评估函数来评判其对环境的适应度。为反映适者生存的思想,算法中设计一个选择机制,使得适应度好的个体有更多的机会生存。在种群的进化过程中,主要存在两种类型的遗传算子:杂交和变异。这些算子作用于个体对应的染色体,产生新的染色体,从而构成下一代种群中的个体。该过程不断进行,直到找到满足精度要求的解,或者达到设定的进化代数。显然,这样的思想适合于现实世界中的一大类问题,因而具有广泛的应用价值。遗传算法的每一次进化过程中的,各个体之间的操作大多可以并列进行,因此,一个非常自然的想法就是将遗传算法并行化,以提高计算速度。
二、遗传算法的并行化
串行遗传算法的主要流程如下图所示。在每一次进化过程中,总是找出种群中的最优解与最差解,并将最优解保存,将本次最差解用上次保存的最优解替换,这样保证了各次进化的最优解的适应度不会降低,从而增快收敛的速度。
我们可以将串行算法改进为并行算法。将整个种群分成p个子种群,每一子种群由一个单一的进程负责,各进程独立地完成串行遗传算法的整个过程。
三、算法设计
任务一:实现随机---已传输替换
原来的代码完成的是,每个工作进程传一个本地随机个体出去,然后接收一个外来个体,替换一个随机的个体,简称随机——随机,现在需要将其改为:随机送出去一个——已经送出的那个被送来的替换。对于此项修改要求,主要在于子进程的替换语句,将原来用来随机选取替换者的语句删除,因为上面送出语句已经保存了ipass即送出值的下标,因此直接使用即可将该内容进行替换。
if (rand() % 1000 / 1000 < (1 - SPAD) || fabs(SPAD - SPAD0) < 0.00000001)
{
//不再随机获取,而是直接替换
dis_p[ipass] = tempdis;
for (j1 = 0; j1 < xCity; j1++)
colony[ipass][j1] = tempcol[j1];
}
运行结果如下:
本项任务完整代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include "mpi.h"
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <iostream>
using namespace std;
#define NPROC 16 //进程数量(主从各一个宏定义)
#define N_COLONY 100 // N_COLONY>=xColony300
#define CITY 431
#define TWOGRP 20 //组间交换和漫游比例是19:1这个问题值得考虑修改?!!实际是20:1!!
#define GRPSCALE 8 //组的规模
#define grpnum (NPROC/GRPSCALE) //组的个数
double sumTemp, sumbest;
int xColony = N_COLONY; //个体数
int xCity = CITY; //城市数量
double edgeSpeed = 5000; //临界速度
double PROBAB1 = 0.02; //变异概率
double PROBAB2 = 0.05; //映射概率 //0.04(80) 0.03(50) 0.015(80) 0.05(50)
long Ni, NOCHANGE = 200000; //最大停止改变代数
long loopcounter = 0;
long MAXGEN = 1000000; //5
long INTERVAL = 5000;
int colony[N_COLONY][CITY]; //所有个体的染色体
double cityXY[CITY][2]; //城市坐标
double city_dis[CITY][CITY]; //城市间距离
double dis_p[N_COLONY]; //所有个体的评估值
double tempdis; //传回的个体的评估值
int tempcol[CITY]; //传回的个体的染色体
double speed;
int temp[CITY];
int ibest, iworst;
int ipass;
clock_t timeStart, timeNow, timeTemp;
char filepath[100], filepath2[100];
void initm();
void init();
int position(int* tmp, int C);
void invert(int pos_start, int pos_end);
void printBest(long GenNum, long Ni);
void tempTest(int i);
void mapped();
void LastCP();
double path(int tmp[], int k1, int k2);
double SPAD_compute();
int** mat = NULL;
int** matlocalbest = NULL;
//mpiexec -n 17 TSP.exe
int main(int argc, char* argv[])
{
mat = (int**)malloc(sizeof(int*) * CITY);
matlocalbest = (int**)malloc(sizeof(int*) * CITY);
for (int i = 0; i < CITY; ++i) {
mat[i] = (int*)malloc(sizeof(int) * CITY);
matlocalbest[i] = (int*)malloc(sizeof(int) * CITY);
}
int mytid, numprocs;
MPI_Status status;
int sign = 1, i, i1, j1;
double result;
double data[NPROC], dt; //存放交换适应值的数组
double* ptrdata[NPROC]; //指针
double tempdata;
int chrom[NPROC][CITY]; //存储所有进程的交换标本的数组
int* ptrchrom[NPROC]; //指针
int tempchr[CITY];
int j, k, m, x; //用于交换,m用来做记录组别的变量
int times = 0;//times是提交的次数
double best = 0.0;
FILE* fpme;
double t, probab1 = PROBAB1, probab2 = PROBAB2;
register int C1, js, ks, pos_C, pos_C1;
int k1, k2, l1, l2, pos_flag;
register double disChange;
static int is = 0;
char mname[30];
int r;
FILE* fppp;
float SPAD0 = 1.0, SPAD = 1.0; //aveSPAD;
MPI_Init(&argc, &argv); /*程序初始化*/
MPI_Comm_rank(MPI_COMM_WORLD, &mytid);/**//*得到当前进程号*/
MPI_Get_processor_name(mname, &r);
srand((unsigned)time(NULL) + mytid);
strcpy_s(filepath, "E:\\gr431.tsp");
//strcpy_s(filepath, argv[1]);
if (mytid == 0) //主进程
{
//strcpy(filepath2, argv[2]);
strcpy(filepath2, "E:\\结果.txt");
//初始化指针数组
for (i = 0; i < NPROC; i++)
{
ptrdata[i] = &data[i];
ptrchrom[i] = chrom[i];
}
//初始化指针数组
//cout << mytid << endl;
initm();
for (i = 1; i <= NPROC; i++) {
MPI_Send(cityXY, CITY * 2, MPI_DOUBLE, i, 99, MPI_COMM_WORLD);
}
cout << "初始数据接收完成" << endl;
}
else
{
MPI_Recv(cityXY, CITY * 2, MPI_DOUBLE, 0, 99, MPI_COMM_WORLD, &status);
cout << to_string(mytid) + "接收初始数据" << endl;
init();
}
//以上初始化
for (loopcounter = 0; loopcounter <= MAXGEN; loopcounter++) {
if (loopcounter % INTERVAL == 0 && loopcounter != 0) {
times++;
}
if (mytid == 0) {
if (loopcounter % INTERVAL == 0 && loopcounter != 0) {
cout << endl;
cout << "Time(s)=" << times << "代数是" << loopcounter << endl;
//第二次交流
//收
cout << "0号进程接收到:";
for (i = 1; i <= NPROC; i++)
{
MPI_Recv(&data[i - 1], 1, MPI_DOUBLE, i, 99, MPI_COMM_WORLD, &status);
MPI_Recv(chrom[i - 1], CITY, MPI_INT, i, 99, MPI_COMM_WORLD, &status);
cout << data[i - 1] << " ";
//cout << to_string(loopcounter / INTERVAL)+" " + to_string(i) << endl;
}
best = data[0];
for (i = 1; i < NPROC; i++) //获取本次提交最好的个体
{
if (data[i] < best)
best = data[i];
}
cout << endl;
cout << "最好个体:" << best << endl;
//迁移交换
for (m = 0; m < grpnum; m++) { //指针数组顺推交换
tempdata = *ptrdata[GRPSCALE * m]; //tempdata暂留ptrdata每组最后一个数据
for (k = 0; k < CITY; k++) //tempchr暂留ptrchrom每组最后一个数据
tempchr[k] = ptrchrom[GRPSCALE * m][k];
for (j = GRPSCALE * m; j < GRPSCALE + GRPSCALE * m - 1; j++) { //除本组最后一个数据之外,其他全部前移一位
*ptrdata[j] = *ptrdata[j + 1];
for (k = 0; k < CITY; k++)
ptrchrom[j][k] = ptrchrom[j + 1][k];
}
*ptrdata[GRPSCALE + GRPSCALE * m - 1] = tempdata; //本组的最后一个数据等于0号数据
for (k = 0; k < CITY; k++)
ptrchrom[GRPSCALE + GRPSCALE * m - 1][k] = tempchr[k];
}
//发
for (i = 1; i <= NPROC; i++) { //原本来自2号进程的数据发送至1号,如此类推,原本来自1号进程的数据发送至16号
MPI_Send(&data[i - 1], 1, MPI_DOUBLE, i, 99, MPI_COMM_WORLD);
MPI_Send(chrom[i - 1], CITY, MPI_INT, i, 99, MPI_COMM_WORLD);
//printf("I send %f to %d\n",data[i],i+1);
}
}
}
else//子进程程序
{
iworst = 0; //用于存放最差个体
ibest = 0; //用于存放最好个体
if (loopcounter % INTERVAL == 0 && loopcounter != 0) {
//发
ipass = rand() % xColony; //天选之子(送出)
MPI_Send(&dis_p[ipass], 1, MPI_DOUBLE, 0, 99, MPI_COMM_WORLD);
MPI_Send(colony[ipass], CITY, MPI_INT, 0, 99, MPI_COMM_WORLD);
//收
//在这里把主进程的内容要回 这里是每次迁移都要做的接受主进程
MPI_Recv(&tempdis, 1, MPI_DOUBLE, 0, 99, MPI_COMM_WORLD, &status);
MPI_Recv(tempcol, CITY, MPI_INT, 0, 99, MPI_COMM_WORLD, &status);
SPAD0 = SPAD;
SPAD = SPAD_compute();
//MPI_Send(&SPAD,1,MPI_DOUBLE,0,99,MPI_COMM_WORLD);
if (rand() % 1000 / 1000 < (1 - SPAD) || fabs(SPAD - SPAD0) < 0.00000001)
{
//不再随机获取,直接替换
dis_p[ipass] = tempdis;
for (j1 = 0; j1 < xCity; j1++)
colony[ipass][j1] = tempcol[j1];
}
}
//第二次交流
for (js = 0; js < xCity; js++)
temp[js] = colony[is][js];
disChange = 0; pos_flag = 0;
pos_C = rand() % xCity;
for (;;) {
if ((rand() * 1.0 / RAND_MAX) < probab1) { //内变异算子
do pos_C1 = rand() % xCity; while (pos_C1 == pos_C);
C1 = colony[is][pos_C1];
}
else {
do js = rand() % xColony; while (js == is);
ks = position(colony[js], temp[pos_C]);
C1 = colony[js][(ks + 1) % xCity];
pos_C1 = position(temp, C1);
}
if (speed > edgeSpeed && pos_C1 < pos_C + 2)
break;
if ((pos_C + 1) % xCity == pos_C1 || (pos_C - 1 + xCity) % xCity == pos_C1)
break;
k1 = temp[pos_C]; k2 = temp[(pos_C + 1) % xCity];
l1 = temp[pos_C1]; l2 = temp[(pos_C1 + 1) % xCity];
disChange += city_dis[k1][l1] + city_dis[k2][l2] - city_dis[k1][k2] - city_dis[l1][l2];
invert(pos_C, pos_C1);
pos_flag++;
if (pos_flag > xCity - 1)
break;
pos_C++;
if (pos_C >= xCity)
pos_C = 0;
if (speed < edgeSpeed && disChange < 0) { //每有改变就计算
dis_p[is] += disChange; disChange = 0;
tempTest(is);
}
}
if (speed >= edgeSpeed && disChange < 0) { dis_p[is] += disChange; disChange = 0; tempTest(is); } /speed>=1500 &&
is++;
if (is >= xColony) {
Ni++;
is = 0;
//loopcounter++;
//check(); //此处增加一个函数,完成第一个功能,正确!!!!
probab1 = PROBAB1 * (1 - loopcounter * 0.5 / MAXGEN); //内逆转概率逐渐减小
if ((rand() * 1.0 / RAND_MAX < probab2)) // speed<edgeSpeed &&
{
mapped();
probab2 = PROBAB2 * (loopcounter * 2.0 / MAXGEN + 1); //部分交换概率逐渐增大
}
}
}//while(loopcounter++<=MAXGEN);
}
cout << to_string(mytid) + "号进程完成交流" << endl;
if (mytid == 0)
{
fpme = fopen(filepath2, "a");
fprintf(fpme, "This is a result of %d:%lf\n", CITY, best);
fclose(fpme);
}
for (i = 0; i < CITY; i++) {
free(mat[i]);
free(matlocalbest[i]);
}
free(mat);
free(matlocalbest);
MPI_Finalize();
return 0;
}
double SPAD_compute()
{
int ibest2 = 0;
int xx, yy, zz;
//int mat[CITY][CITY], matlocalbest[CITY][CITY];
int best_i, count_of_1;
float D[N_COLONY], STD, lD[N_COLONY], lSTD;
for (xx = 0; xx < N_COLONY; xx++)
{
if (dis_p[ibest2] > dis_p[xx])
ibest2 = xx;
}
for (xx = 0; xx < xCity; xx++)
for (yy = 0; yy < xCity; yy++)
matlocalbest[xx][yy] = 0;
for (xx = 0; xx < xCity; xx++) //本地最好解之邻接矩阵建立
{
matlocalbest[colony[ibest2][xx]][colony[ibest2][(xx + 1) % xCity]] = 1;
}
lSTD = 0;
for (zz = 0; zz < N_COLONY; zz++)
{
for (xx = 0; xx < CITY; xx++) //ci chu gui 0
{
for (yy = 0; yy < CITY; yy++)
mat[xx][yy] = 0;
}
for (xx = 0; xx < xCity; xx++)
{
mat[colony[zz][xx]][colony[zz][(xx + 1) % xCity]] = 1; //全部解矩阵建立
}
count_of_1 = 0;
for (xx = 0; xx < xCity; xx++)
{
for (yy = 0; yy < xCity; yy++)
{
if (matlocalbest[xx][yy] == 1 && mat[xx][yy] == 1)
{
break;
}
}
if (yy < xCity)
count_of_1++;
}
lD[zz] = 1.0 * (xCity - count_of_1) / xCity; //求出了一个个体与本地最好个体的差异
lSTD += lD[zz]; //累加差异
}
return lSTD / N_COLONY;
}
void invert(int pos_start, int pos_end)
{
int j, k, t;
if (pos_start < pos_end)
{
j = pos_start + 1; k = pos_end;
for (; j <= k; j++, k--)
{
t = temp[j]; temp[j] = temp[k]; temp[k] = t;
}
}
else
{
if (xCity - 1 - pos_start <= pos_end + 1)
{
j = pos_end; k = pos_start + 1;
for (; k < xCity; j--, k++)
{
t = temp[j]; temp[j] = temp[k]; temp[k] = t;
}
k = 0;
for (; k <= j; k++, j--)
{
t = temp[j]; temp[j] = temp[k]; temp[k] = t;
}
}
else
{
j = pos_end; k = pos_start + 1;
for (; j >= 0; j--, k++)
{
t = temp[j]; temp[j] = temp[k]; temp[k] = t;
}
j = xCity - 1;
for (; k <= j; k++, j--)
{
t = temp[j]; temp[j] = temp[k]; temp[k] = t;
}
}
}
}
int position(int* tmp, int C)
{
int j;
for (j = 0; j < xCity; j++)
if (*(tmp + j) == C)break;
return(j);
}
void tempTest(int i)
{
int j; double dt;
for (j = 0; j < xCity; j++)colony[i][j] = temp[j];
if ((int)sumbest > (int)dis_p[i])
{
sumbest = dis_p[i]; ibest = i; Ni = 0;
timeNow = clock();
dt = (double)(timeNow - timeTemp) / CLOCKS_PER_SEC;;
if (dt > 0.1)
{
speed = (sumTemp - sumbest) / dt;
sumTemp = sumbest;
timeTemp = timeNow;
}
//printf("\n%f %4.2f %10.1f",sumbest,(double)(timeNow-timeStart)/CLOCKS_PER_SEC,speed);
}
}
void printBest(long GenNum, long Ni)
{
int i;
printf("\n CITY %d\t\tN_COLONY %d", CITY, N_COLONY);
printf("\n maxGen %d\t\ttime %4.2f seconds", MAXGEN, (double)(timeNow - timeStart) / CLOCKS_PER_SEC);
printf("\n GenNum %d\t\tNo change %Ld\n\n", GenNum, Ni);
for (i = 0; i < xCity; i++)
{
if (i % 10 == 0 && i != 0) { printf("\n"); }
printf("%5d", colony[ibest][i] + 1);
}
printf("\n\n");
}
void mapped()
{
int start, end, i, j, k, kt, t, disPlace, kDC, kC;
double temp_dis = 0;
i = rand() % xColony;
j = rand() % xColony;
if (i == j)return;
if (dis_p[i] < dis_p[j])
{
t = i; i = j; j = t;
}
for (k = 0; k < xCity; k++)temp[k] = colony[i][k];
start = rand() % xCity;
end = (start + rand() % 180 + 20) % xCity; //rand()%xCity;
kt = position(temp, colony[j][start]); //部分映射一二位同
disPlace = kt - start;
if (temp[(kt + 1) % xCity] == colony[j][(start + 1) % xCity])
{
if (start < end)
for (k = start; k <= end; k++)
{
kDC = (k + disPlace) % xCity;
if (temp[kDC] == colony[j][k])continue;
t = position(temp, colony[j][k]);
temp[t] = temp[kDC];
temp[kDC] = colony[j][k];
}
else
for (k = start; k <= xCity + end; k++)
{
kDC = (k + disPlace) % xCity; kC = k % xCity;
if (temp[kDC] == colony[j][kC])continue;
t = position(temp, colony[j][kC]);
temp[t] = temp[kDC];
temp[kDC] = colony[j][kC];
}
}
else
{
if (temp[(kt - 1 + xCity) % xCity] == colony[j][(start + 1) % xCity])
{
if (start < end)
for (k = kt = start; k <= end; k++, kt--)
{
kDC = (kt + xCity + disPlace) % xCity;
if (temp[kDC] == colony[j][k])continue;
t = position(temp, colony[j][k]);
temp[t] = temp[kDC];
temp[kDC] = colony[j][k];
}
else
for (k = kt = start; k <= end + xCity; k++, kt--)
{
kDC = (kt + xCity + disPlace) % xCity; kC = k % xCity;
if (temp[kDC] == colony[j][kC])continue;
t = position(temp, colony[j][kC]);
temp[t] = temp[kDC];
temp[kDC] = colony[j][kC];
}
}
else return;
}
/*
start=rand()%xCity; end=rand()%xCity; //部分映射找第一位同
if(start>end){t=start;start=end;end=t;}
disPlace=position(temp,colony[j][start])-start;
for(k=start;k<=end;k++)
{ if(temp[(k+disPlace)%xCity]==colony[j][k])continue;
t=position(temp,colony[j][k]);
temp[t]=temp[(k+disPlace)%xCity];
temp[(k+disPlace)%xCity]=colony[j][k];
}
start=rand()%(xCity/2); //部分映射
end=rand()%(xCity/2)+xCity/2;
for(k=start;k<=end;k++)
{ if(temp[k]==colony[j][k])continue;
t=position(temp,colony[j][k]);
temp[t]=temp[k];
temp[k]=colony[j][k];
}
*/
for (j = 0; j < xCity - 1; j++)
temp_dis = temp_dis + city_dis[temp[j]][temp[j + 1]];
temp_dis = temp_dis + city_dis[temp[0]][temp[xCity - 1]];
dis_p[i] = temp_dis;
/*********/
tempTest(i);
}
void LastCP()
{
int i, k, j1, j2, k1, k2, turn, length, sign[CITY]; double dc, temp_dis = 0, change = 0;
printf("+");
for (k = 0; k < xCity; k++)temp[k] = colony[ibest][k];
for (turn = 0; turn < xCity / 10; turn++) //可改
{
for (k1 = 0; k1 < xCity - 1; k1 += rand() % 4 + 1) // rand()%9+1可改
{
for (i = 1; i < xColony; i++)
{
if (i == ibest)continue;
for (k = 0; k < xCity; k++)sign[k] = 0;
j1 = position(colony[i], temp[k1]);
k2 = k1; j2 = j1;
for (length = 0; length < xCity / 2; length++) // 70 xCity/3+10可改
{
k2 = (++k2) % xCity; j2 = (++j2) % xCity;
sign[temp[k2]] = 1;
if (temp[k2] == colony[i][j2] && length > 1)break; // 5 xCity/10可改
}
if (temp[k2] != colony[i][j2])continue;
k = j1;
do k = (k + 1) % xCity;
while (sign[colony[i][k]] == 1);
if ((j1 < j2 && k < j2) || (j1 > j2 && (k > j1 || k < j2)))continue;
temp_dis = path(temp, k1, k2);
dc = path(colony[i], j1, j2);
if (temp_dis > dc)
{
for (k = 1; k <= length; k++)
temp[(k1 + k) % xCity] = colony[i][(j1 + k) % xCity];
change += dc - temp_dis;
}
}
}
}
if (change < 0)
{
for (k = 0; k < xCity; k++)colony[ibest][k] = temp[k];
dis_p[ibest] += change;
sumbest = dis_p[ibest];
printf("\n%f O K !!!", sumbest);
}
}
double path(int tmp[], int k1, int k2)
{
int j, t1, t2; double temp_dis = 0;
if (k2 > k1)
for (j = k1; j < k2; j++)
temp_dis += city_dis[tmp[j]][tmp[j + 1]];
else
for (j = k1; j < k2 + xCity; j++)
{
t1 = j % xCity; t2 = (j + 1) % xCity;
temp_dis += city_dis[tmp[t1]][tmp[t2]];
}
return temp_dis;
}
// 读取城市坐标
void initm() {
int i;
FILE* fp;
float ffff, eeee;
if ((fp = fopen(filepath, "r")) == NULL) {
MPI_Finalize();
exit(0);
}
//printf("hello");
fscanf(fp, "%d", &xCity);
for (i = 0; i < xCity; i++) /* init cityXY[][] */
{
fscanf(fp, "%*d%f%f", &ffff, &eeee);
//printf("\nffff=%f eeee=%f", ffff, eeee);
cityXY[i][0] = ffff;
cityXY[i][1] = eeee;
}
fclose(fp);
cout << "读取成功" << endl;
}
// 初始化一个种群的染色体
void init() {
int i, j, t, sign, mod, array[CITY];
double d;
for (i = 0; i < xCity; i++) {
for (j = 0; j < xCity; j++) {
if (j > i) {
d = (cityXY[i][0] - cityXY[j][0]) * (cityXY[i][0] - cityXY[j][0]) * 1.0 +
(cityXY[i][1] - cityXY[j][1]) * (cityXY[i][1] - cityXY[j][1]) * 1.0;
city_dis[i][j] = (int)(sqrt(d) + 0.5);
continue;
}
if (j == i) {
city_dis[i][j] = 0;
continue;
}
if (j < i)
city_dis[i][j] = city_dis[j][i];
}
}
mod = xCity;
for (i = 0; i < xCity; i++)
array[i] = i; // init colony[][]
for (i = 0; i < xColony; i++, mod = xCity) {
for (j = 0; j < xCity; j++) {
sign = rand() % mod;
colony[i][j] = array[sign];
t = array[mod - 1];
array[mod - 1] = array[sign];
array[sign] = t;
mod--;
if (mod == 1) colony[i][++j] = array[0];
}
//for (j = 0; j < xCity; j++) {
// printf("%d ", colony[i][j]);
//}
//printf("\n");
}
for (i = 0; i < xColony; i++) { /* init dis_p[] */
dis_p[i] = 0;
for (j = 0; j < xCity - 1; j++)
dis_p[i] = dis_p[i] + city_dis[*(*(colony + i) + j)][*(*(colony + i) + j + 1)];
dis_p[i] = dis_p[i] + city_dis[**(colony + i)][*(*(colony + i) + xCity - 1)];
}
ibest = 0; sumbest = dis_p[0]; /* init ibest & sumbest */
sumTemp = sumbest * 5;
speed = 100000000;
loopcounter = 0; Ni = 0; /* initialize GunNum & Ni */
//printf("init success!!!\n");
}
任务二:实现最好---最坏替换
各进程在每一次进化过程中,均分别保留各自的局部最优解,用来在下一次进化中替换局部最差的个体。各进程均完成所预定的进化迭代后,最后对各进程的局部最优解进行归约,从而得到整个算法的全局最优解。
else//子进程程序
{
iworst = 0; //用于存放最差个体
ibest = 0; //用于存放最好个体
if (loopcounter % INTERVAL == 0 && loopcounter != 0) {
//发
double best = 0;
for (int p = 0; p < 100; p++)
{
if (best > dis_p[p])
{
best = dis_p[p]; //选出群体中最好的个体
ibest = p;
}
}
MPI_Send(&dis_p[ibest], 1, MPI_DOUBLE, 0, 99, MPI_COMM_WORLD); //将最好个体发送出去
MPI_Send(colony[ibest], CITY, MPI_INT, 0, 99, MPI_COMM_WORLD);
//收
//在这里把主进程的内容要回 这里是每次迁移都要做的接受主进程
MPI_Recv(&tempdis, 1, MPI_DOUBLE, 0, 99, MPI_COMM_WORLD, &status);
MPI_Recv(tempcol, CITY, MPI_INT, 0, 99, MPI_COMM_WORLD, &status);
SPAD0 = SPAD;
SPAD = SPAD_compute();
//MPI_Send(&SPAD,1,MPI_DOUBLE,0,99,MPI_COMM_WORLD);
if (rand() % 1000 / 1000 < (1 - SPAD) || fabs(SPAD - SPAD0) < 0.00000001)
{
double worst = 0;
for (int p = 0; p < 100; p++)
{
if (worst < dis_p[p])
{
worst = dis_p[p]; //该群体中最差的个体选出来
worst = p;
}
}
dis_p[iworst] = tempdis; //将最差的个体替换
for (j1 = 0; j1 < xCity; j1++)
colony[iworst][j1] = tempcol[j1];
}
}
运行结果如下:
任务三:将“地主+长工”模式改为“富农+长工”模式
原先的主进程只负责数据的发送和回收,并不负责计算;要修改为主进程不仅进行数据的送出和收回,还要进行计算。
//第二次交流
//收
for (i = 1; i < NPROC; i++) //修改处 ,将<=改为<
{
MPI_Recv(&data[i], 1, MPI_DOUBLE, i, 99, MPI_COMM_WORLD, &status); //修改处,data[i-1]改为i,1号进程接受data[1]
MPI_Recv(chrom[i], CITY, MPI_INT, i, 99, MPI_COMM_WORLD, &status); //修改处,chrom[i-1]改为i,1号进程接受chrom[1]
运行结果如下:
该任务完整代码如下:
#define _CRT_SECURE_NO_WARNINGS
#include "mpi.h"
#include <math.h>
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <iostream>
using namespace std;
#define NPROC 16 //进程数量(主从各一个宏定义)
#define N_COLONY 100 // N_COLONY>=xColony300
#define CITY 431
#define TWOGRP 20 //组间交换和漫游比例是19:1这个问题值得考虑修改?!!实际是20:1!!
#define GRPSCALE 8 //组的规模
#define grpnum (NPROC/GRPSCALE) //组的个数
double sumTemp, sumbest;
int xColony = N_COLONY; //个体数
int xCity = CITY; //城市数量
double edgeSpeed = 5000; //临界速度
double PROBAB1 = 0.02; //变异概率
double PROBAB2 = 0.05; //映射概率 //0.04(80) 0.03(50) 0.015(80) 0.05(50)
long Ni, NOCHANGE = 200000; //最大停止改变代数
long loopcounter = 0;
long MAXGEN = 1000000; //5
long INTERVAL = 5000;
int colony[N_COLONY][CITY]; //所有个体的染色体
double cityXY[CITY][2]; //城市坐标
double city_dis[CITY][CITY]; //城市间距离
double dis_p[N_COLONY]; //所有个体的评估值
double tempdis; //传回的个体的评估值
int tempcol[CITY]; //传回的个体的染色体
double speed;
int temp[CITY];
int ibest, iworst;
int ipass;
clock_t timeStart, timeNow, timeTemp;
char filepath[100], filepath2[100];
void initm();
void init();
int position(int* tmp, int C);
void invert(int pos_start, int pos_end);
void printBest(long GenNum, long Ni);
void tempTest(int i);
void mapped();
void LastCP();
double path(int tmp[], int k1, int k2);
double SPAD_compute();
int** mat = NULL;
int** matlocalbest = NULL;
int main(int argc, char* argv[])
{
mat = (int**)malloc(sizeof(int*) * CITY);
matlocalbest = (int**)malloc(sizeof(int*) * CITY);
for (int i = 0; i < CITY; ++i) {
mat[i] = (int*)malloc(sizeof(int) * CITY);
matlocalbest[i] = (int*)malloc(sizeof(int) * CITY);
}
int mytid, numprocs;
MPI_Status status;
int sign = 1, i, i1, j1;
double result;
double data[NPROC], dt; //存放交换适应值的数组
double* ptrdata[NPROC]; //指针
double tempdata;
int chrom[NPROC][CITY]; //存储所有进程的交换标本的数组
int* ptrchrom[NPROC]; //指针
int tempchr[CITY];
int j, k, m, x; //用于交换,m用来做记录组别的变量
int times = 0;//times是提交的次数
double best = 0.0;
FILE* fpme;
double t, probab1 = PROBAB1, probab2 = PROBAB2;
register int C1, js, ks, pos_C, pos_C1;
int k1, k2, l1, l2, pos_flag;
register double disChange;
static int is = 0;
char mname[30];
int r;
FILE* fppp;
float SPAD0 = 1.0, SPAD = 1.0; //aveSPAD;
MPI_Init(&argc, &argv); /*程序初始化*/
MPI_Comm_rank(MPI_COMM_WORLD, &mytid);/*得到当前进程号*/
MPI_Get_processor_name(mname, &r);
srand((unsigned)time(NULL) + mytid);
strcpy_s(filepath, "E:\\gr431.tsp");
//strcpy_s(filepath, argv[1]);
if (mytid == 0) //主进程
{
//strcpy(filepath2, argv[2]);
strcpy(filepath2, "E:\\结果.txt");
//初始化指针数组
for (i = 0; i < NPROC; i++)
{
ptrdata[i] = &data[i];
ptrchrom[i] = chrom[i];
}
//初始化指针数组
initm();
for (i = 1; i < NPROC; i++) {
//修改处,将<=变为< 给剩下的15个进程分配数据
MPI_Send(cityXY, CITY * 2, MPI_DOUBLE, i, 99, MPI_COMM_WORLD);
}
init(); //给0号进程初始化一个种群
data[0] = dis_p[ipass];
for (int i = 0; i < xCity; i++)
{
chrom[0][i] = colony[ipass][i];
}
cout << "初始数据接收完成" << endl;
}
else
{
MPI_Recv(cityXY, CITY * 2, MPI_DOUBLE, 0, 99, MPI_COMM_WORLD, &status); //其他进程接收来自
cout << to_string(mytid) + "接收初始数据" << endl;
init();
}
//以上初始化
for (loopcounter = 0; loopcounter <= MAXGEN; loopcounter++) {
if (loopcounter % INTERVAL == 0 && loopcounter != 0) {
times++;
}
if (mytid == 0) {
if (loopcounter % INTERVAL == 0 && loopcounter != 0) {
cout << endl;
/*iworst = 0; //用于存放最差个体
ibest = 0; //用于存放最好个体*/
ipass = rand() % xColony;
double temp_disp = dis_p[ipass];
int* temp_col = colony[ipass];
//发
cout << "Time(s)=" << times << "代数是" << loopcounter << endl;
//第二次交流
//收
for (i = 1; i < NPROC; i++) //修改处 将<=改为<
{
MPI_Recv(&data[i], 1, MPI_DOUBLE, i, 99, MPI_COMM_WORLD, &status); //修改处,data[i-1]改为i,1号进程接受data[1]
MPI_Recv(chrom[i], CITY, MPI_INT, i, 99, MPI_COMM_WORLD, &status); //修改处,如上
if (i == 1)
{
SPAD0 = SPAD;
SPAD = SPAD_compute();
if (rand() % 1000 / 1000 < (1 - SPAD) || fabs(SPAD - SPAD0) < 0.00000001)
{
dis_p[ipass] = data[i];
for (j1 = 0; j1 < xCity; j1++)
colony[ipass][j1] = chrom[i][j1];
}
for (js = 0; js < xCity; js++)
temp[js] = colony[is][js];
disChange = 0; pos_flag = 0;
pos_C = rand() % xCity;
for (;;) {
if ((rand() * 1.0 / RAND_MAX) < probab1) { //内变异算子
do pos_C1 = rand() % xCity; while (pos_C1 == pos_C);
C1 = colony[is][pos_C1];
}
else {
do js = rand() % xColony; while (js == is);
ks = position(colony[js], temp[pos_C]);
C1 = colony[js][(ks + 1) % xCity];
pos_C1 = position(temp, C1);
}
if (speed > edgeSpeed && pos_C1 < pos_C + 2)
break;
if ((pos_C + 1) % xCity == pos_C1 || (pos_C - 1 + xCity) % xCity == pos_C1)
break;
k1 = temp[pos_C]; k2 = temp[(pos_C + 1) % xCity];
l1 = temp[pos_C1]; l2 = temp[(pos_C1 + 1) % xCity];
disChange += city_dis[k1][l1] + city_dis[k2][l2] - city_dis[k1][k2] - city_dis[l1][l2];
invert(pos_C, pos_C1);
pos_flag++;
if (pos_flag > xCity - 1)
break;
pos_C++;
if (pos_C >= xCity)
pos_C = 0;
if (speed < edgeSpeed && disChange < 0) { //每有改变就计算
dis_p[is] += disChange; disChange = 0;
tempTest(is);
}
}
if (speed >= edgeSpeed && disChange < 0) { dis_p[is] += disChange; disChange = 0; tempTest(is); } /speed>=1500 &&
is++;
if (is >= xColony) {
Ni++;
is = 0;
//loopcounter++;
//check(); //此处增加一个函数,完成第一个功能,正确!!!!
probab1 = PROBAB1 * (1 - loopcounter * 0.5 / MAXGEN); //内逆转概率逐渐减小
if ((rand() * 1.0 / RAND_MAX < probab2)) // speed<edgeSpeed &&
{
mapped();
probab2 = PROBAB2 * (loopcounter * 2.0 / MAXGEN + 1); //部分交换概率逐渐增大
}
}
}
}
best = data[0];
cout << "0号进程中的数据:";
cout << data[0] << " ";
for (i = 1; i < NPROC; i++) //获取本次提交最好的个体
{
cout << data[i] << " ";
}
for (i = 1; i < NPROC; i++) //获取本次提交最好的个体
{
if (data[i] < best)
best = data[i];
}
cout << endl;
cout << "最好个体:" << best << endl;
//迁移交换
for (m = 0; m < grpnum; m++) { //指针数组顺推交换
tempdata = *ptrdata[GRPSCALE * m]; //tempdata暂留ptrdata每组最后一个数据
for (k = 0; k < CITY; k++) //tempchr暂留ptrchrom每组最后一个数据
tempchr[k] = ptrchrom[GRPSCALE * m][k];
for (j = GRPSCALE * m; j < GRPSCALE + GRPSCALE * m - 1; j++) { //除本组最后一个数据之外,其他全部前移一位
*ptrdata[j] = *ptrdata[j + 1];
for (k = 0; k < CITY; k++)
ptrchrom[j][k] = ptrchrom[j + 1][k];
}
*ptrdata[GRPSCALE + GRPSCALE * m - 1] = tempdata; //本组的最后一个数据等于0号数据
for (k = 0; k < CITY; k++)
ptrchrom[GRPSCALE + GRPSCALE * m - 1][k] = tempchr[k];
}
//发
for (i = 1; i < NPROC; i++) { //原本来自2号进程的数据发送至1号,如此类推,原本来自0号进程的数据发送至15号
if (i == NPROC - 1)
{
MPI_Send(&temp_disp, 1, MPI_DOUBLE, i, 99, MPI_COMM_WORLD);
MPI_Send(temp_col, CITY, MPI_INT, i, 99, MPI_COMM_WORLD);
continue;
}
MPI_Send(&data[i], 1, MPI_DOUBLE, i, 99, MPI_COMM_WORLD);
MPI_Send(chrom[i], CITY, MPI_INT, i, 99, MPI_COMM_WORLD);
}
}
}
else//子进程程序
{
iworst = 0; //用于存放最差个体
ibest = INT_MAX; //用于存放最好个体
if (loopcounter % INTERVAL == 0 && loopcounter != 0) {
ipass = rand() % xColony; //生成一个随机数
MPI_Send(&dis_p[ipass], 1, MPI_DOUBLE, 0, 99, MPI_COMM_WORLD); //将随机个体发送出去
MPI_Send(colony[ipass], CITY, MPI_INT, 0, 99, MPI_COMM_WORLD);
//收
//在这里把主进程的内容要回 这里是每次迁移都要做的接受主进程
MPI_Recv(&tempdis, 1, MPI_DOUBLE, 0, 99, MPI_COMM_WORLD, &status);
MPI_Recv(tempcol, CITY, MPI_INT, 0, 99, MPI_COMM_WORLD, &status);
SPAD0 = SPAD;
SPAD = SPAD_compute();
if (rand() % 1000 / 1000 < (1 - SPAD) || fabs(SPAD - SPAD0) < 0.00000001)
{
dis_p[ipass] = tempdis; //将群体中随机的个体替换
for (j1 = 0; j1 < xCity; j1++)
colony[ipass][j1] = tempcol[j1];
}
}
//第二次交流
for (js = 0; js < xCity; js++)
temp[js] = colony[is][js];
disChange = 0; pos_flag = 0;
pos_C = rand() % xCity;
for (;;) {
if ((rand() * 1.0 / RAND_MAX) < probab1) { //内变异算子
do pos_C1 = rand() % xCity; while (pos_C1 == pos_C);
C1 = colony[is][pos_C1];
}
else {
do js = rand() % xColony; while (js == is);
ks = position(colony[js], temp[pos_C]);
C1 = colony[js][(ks + 1) % xCity];
pos_C1 = position(temp, C1);
}
if (speed > edgeSpeed && pos_C1 < pos_C + 2)
break;
if ((pos_C + 1) % xCity == pos_C1 || (pos_C - 1 + xCity) % xCity == pos_C1)
break;
k1 = temp[pos_C]; k2 = temp[(pos_C + 1) % xCity];
l1 = temp[pos_C1]; l2 = temp[(pos_C1 + 1) % xCity];
disChange += city_dis[k1][l1] + city_dis[k2][l2] - city_dis[k1][k2] - city_dis[l1][l2];
invert(pos_C, pos_C1);
pos_flag++;
if (pos_flag > xCity - 1)
break;
pos_C++;
if (pos_C >= xCity)
pos_C = 0;
if (speed < edgeSpeed && disChange < 0) { //每有改变就计算
dis_p[is] += disChange; disChange = 0;
tempTest(is);
}
}
if (speed >= edgeSpeed && disChange < 0) { dis_p[is] += disChange; disChange = 0; tempTest(is); } /speed>=1500 &&
is++;
if (is >= xColony) {
Ni++;
is = 0;
probab1 = PROBAB1 * (1 - loopcounter * 0.5 / MAXGEN); //内逆转概率逐渐减小
if ((rand() * 1.0 / RAND_MAX < probab2)) // speed<edgeSpeed &&
{
mapped();
probab2 = PROBAB2 * (loopcounter * 2.0 / MAXGEN + 1); //部分交换概率逐渐增大
}
}
}
}
cout << to_string(mytid) + "号进程完成交流" << endl;
if (mytid == 0)
{
fpme = fopen(filepath2, "a");
fprintf(fpme, "富农-长工模式下 %d个城市的结果:%lf\n", CITY, best);
fclose(fpme);
}
for (i = 0; i < CITY; i++) {
free(mat[i]);
free(matlocalbest[i]);
}
free(mat);
free(matlocalbest);
MPI_Finalize();
return 0;
}
double SPAD_compute()
{
int ibest2 = 0;
int xx, yy, zz;
//int mat[CITY][CITY], matlocalbest[CITY][CITY];
int best_i, count_of_1;
float D[N_COLONY], STD, lD[N_COLONY], lSTD;
for (xx = 0; xx < N_COLONY; xx++)
{
if (dis_p[ibest2] > dis_p[xx])
ibest2 = xx;
}
for (xx = 0; xx < xCity; xx++)
for (yy = 0; yy < xCity; yy++)
matlocalbest[xx][yy] = 0;
for (xx = 0; xx < xCity; xx++) //本地最好解之邻接矩阵建立
{
matlocalbest[colony[ibest2][xx]][colony[ibest2][(xx + 1) % xCity]] = 1;
}
lSTD = 0;
for (zz = 0; zz < N_COLONY; zz++)
{
for (xx = 0; xx < CITY; xx++) //ci chu gui 0
{
for (yy = 0; yy < CITY; yy++)
mat[xx][yy] = 0;
}
for (xx = 0; xx < xCity; xx++)
{
mat[colony[zz][xx]][colony[zz][(xx + 1) % xCity]] = 1; //全部解矩阵建立
}
count_of_1 = 0;
for (xx = 0; xx < xCity; xx++)
{
for (yy = 0; yy < xCity; yy++)
{
if (matlocalbest[xx][yy] == 1 && mat[xx][yy] == 1)
{
break;
}
}
if (yy < xCity)
count_of_1++;
}
lD[zz] = 1.0 * (xCity - count_of_1) / xCity; //求出了一个个体与本地最好个体的差异
lSTD += lD[zz]; //累加差异
}
return lSTD / N_COLONY;
}
void invert(int pos_start, int pos_end)
{
int j, k, t;
if (pos_start < pos_end)
{
j = pos_start + 1; k = pos_end;
for (; j <= k; j++, k--)
{
t = temp[j]; temp[j] = temp[k]; temp[k] = t;
}
}
else
{
if (xCity - 1 - pos_start <= pos_end + 1)
{
j = pos_end; k = pos_start + 1;
for (; k < xCity; j--, k++)
{
t = temp[j]; temp[j] = temp[k]; temp[k] = t;
}
k = 0;
for (; k <= j; k++, j--)
{
t = temp[j]; temp[j] = temp[k]; temp[k] = t;
}
}
else
{
j = pos_end; k = pos_start + 1;
for (; j >= 0; j--, k++)
{
t = temp[j]; temp[j] = temp[k]; temp[k] = t;
}
j = xCity - 1;
for (; k <= j; k++, j--)
{
t = temp[j]; temp[j] = temp[k]; temp[k] = t;
}
}
}
}
int position(int* tmp, int C)
{
int j;
for (j = 0; j < xCity; j++)
if (*(tmp + j) == C)break;
return(j);
}
void tempTest(int i)
{
int j; double dt;
for (j = 0; j < xCity; j++)colony[i][j] = temp[j];
if ((int)sumbest > (int)dis_p[i])
{
sumbest = dis_p[i]; ibest = i; Ni = 0;
timeNow = clock();
dt = (double)(timeNow - timeTemp) / CLOCKS_PER_SEC;;
if (dt > 0.1)
{
speed = (sumTemp - sumbest) / dt;
sumTemp = sumbest;
timeTemp = timeNow;
}
//printf("\n%f %4.2f %10.1f",sumbest,(double)(timeNow-timeStart)/CLOCKS_PER_SEC,speed);
}
}
void printBest(long GenNum, long Ni)
{
int i;
printf("\n CITY %d\t\tN_COLONY %d", CITY, N_COLONY);
printf("\n maxGen %d\t\ttime %4.2f seconds", MAXGEN, (double)(timeNow - timeStart) / CLOCKS_PER_SEC);
printf("\n GenNum %d\t\tNo change %Ld\n\n", GenNum, Ni);
for (i = 0; i < xCity; i++)
{
if (i % 10 == 0 && i != 0) { printf("\n"); }
printf("%5d", colony[ibest][i] + 1);
}
printf("\n\n");
}
void mapped()
{
int start, end, i, j, k, kt, t, disPlace, kDC, kC;
double temp_dis = 0;
i = rand() % xColony;
j = rand() % xColony;
if (i == j)return;
if (dis_p[i] < dis_p[j])
{
t = i; i = j; j = t;
}
for (k = 0; k < xCity; k++)temp[k] = colony[i][k];
start = rand() % xCity;
end = (start + rand() % 180 + 20) % xCity; //rand()%xCity;
kt = position(temp, colony[j][start]); //部分映射一二位同
disPlace = kt - start;
if (temp[(kt + 1) % xCity] == colony[j][(start + 1) % xCity])
{
if (start < end)
for (k = start; k <= end; k++)
{
kDC = (k + disPlace) % xCity;
if (temp[kDC] == colony[j][k])continue;
t = position(temp, colony[j][k]);
temp[t] = temp[kDC];
temp[kDC] = colony[j][k];
}
else
for (k = start; k <= xCity + end; k++)
{
kDC = (k + disPlace) % xCity; kC = k % xCity;
if (temp[kDC] == colony[j][kC])continue;
t = position(temp, colony[j][kC]);
temp[t] = temp[kDC];
temp[kDC] = colony[j][kC];
}
}
else
{
if (temp[(kt - 1 + xCity) % xCity] == colony[j][(start + 1) % xCity])
{
if (start < end)
for (k = kt = start; k <= end; k++, kt--)
{
kDC = (kt + xCity + disPlace) % xCity;
if (temp[kDC] == colony[j][k])continue;
t = position(temp, colony[j][k]);
temp[t] = temp[kDC];
temp[kDC] = colony[j][k];
}
else
for (k = kt = start; k <= end + xCity; k++, kt--)
{
kDC = (kt + xCity + disPlace) % xCity; kC = k % xCity;
if (temp[kDC] == colony[j][kC])continue;
t = position(temp, colony[j][kC]);
temp[t] = temp[kDC];
temp[kDC] = colony[j][kC];
}
}
else return;
}
for (j = 0; j < xCity - 1; j++)
temp_dis = temp_dis + city_dis[temp[j]][temp[j + 1]];
temp_dis = temp_dis + city_dis[temp[0]][temp[xCity - 1]];
dis_p[i] = temp_dis;
/*********/
tempTest(i);
}
void LastCP()
{
int i, k, j1, j2, k1, k2, turn, length, sign[CITY]; double dc, temp_dis = 0, change = 0;
printf("+");
for (k = 0; k < xCity; k++)temp[k] = colony[ibest][k];
for (turn = 0; turn < xCity / 10; turn++) //可改
{
for (k1 = 0; k1 < xCity - 1; k1 += rand() % 4 + 1) // rand()%9+1可改
{
for (i = 1; i < xColony; i++)
{
if (i == ibest)continue;
for (k = 0; k < xCity; k++)sign[k] = 0;
j1 = position(colony[i], temp[k1]);
k2 = k1; j2 = j1;
for (length = 0; length < xCity / 2; length++) // 70 xCity/3+10可改
{
k2 = (++k2) % xCity; j2 = (++j2) % xCity;
sign[temp[k2]] = 1;
if (temp[k2] == colony[i][j2] && length > 1)break; // 5 xCity/10可改
}
if (temp[k2] != colony[i][j2])continue;
k = j1;
do k = (k + 1) % xCity;
while (sign[colony[i][k]] == 1);
if ((j1 < j2 && k < j2) || (j1 > j2 && (k > j1 || k < j2)))continue;
temp_dis = path(temp, k1, k2);
dc = path(colony[i], j1, j2);
if (temp_dis > dc)
{
for (k = 1; k <= length; k++)
temp[(k1 + k) % xCity] = colony[i][(j1 + k) % xCity];
change += dc - temp_dis;
}
}
}
}
if (change < 0)
{
for (k = 0; k < xCity; k++)colony[ibest][k] = temp[k];
dis_p[ibest] += change;
sumbest = dis_p[ibest];
printf("\n%f O K !!!", sumbest);
}
}
double path(int tmp[], int k1, int k2)
{
int j, t1, t2; double temp_dis = 0;
if (k2 > k1)
for (j = k1; j < k2; j++)
temp_dis += city_dis[tmp[j]][tmp[j + 1]];
else
for (j = k1; j < k2 + xCity; j++)
{
t1 = j % xCity; t2 = (j + 1) % xCity;
temp_dis += city_dis[tmp[t1]][tmp[t2]];
}
return temp_dis;
}
// 读取城市坐标
void initm() {
int i;
FILE* fp;
float ffff, eeee;
if ((fp = fopen(filepath, "r")) == NULL) {
MPI_Finalize();
exit(0);
}
//printf("hello");
fscanf(fp, "%d", &xCity);
for (i = 0; i < xCity; i++) /* init cityXY[][] */
{
fscanf(fp, "%*d%f%f", &ffff, &eeee);
//printf("\nffff=%f eeee=%f", ffff, eeee);
cityXY[i][0] = ffff;
cityXY[i][1] = eeee;
}
fclose(fp);
cout << "读取成功" << endl;
}
// 初始化一个种群的染色体
void init() {
int i, j, t, sign, mod, array[CITY];
double d;
for (i = 0; i < xCity; i++) {
for (j = 0; j < xCity; j++) {
if (j > i) {
d = (cityXY[i][0] - cityXY[j][0]) * (cityXY[i][0] - cityXY[j][0]) * 1.0 +
(cityXY[i][1] - cityXY[j][1]) * (cityXY[i][1] - cityXY[j][1]) * 1.0;
city_dis[i][j] = (int)(sqrt(d) + 0.5);
continue;
}
if (j == i) {
city_dis[i][j] = 0;
continue;
}
if (j < i)
city_dis[i][j] = city_dis[j][i];
}
}
mod = xCity;
for (i = 0; i < xCity; i++)
array[i] = i; // init colony[][]
for (i = 0; i < xColony; i++, mod = xCity) {
for (j = 0; j < xCity; j++) {
sign = rand() % mod;
colony[i][j] = array[sign];
t = array[mod - 1];
array[mod - 1] = array[sign];
array[sign] = t;
mod--;
if (mod == 1) colony[i][++j] = array[0];
}
}
for (i = 0; i < xColony; i++) { /* init dis_p[] */
dis_p[i] = 0;
for (j = 0; j < xCity - 1; j++)
dis_p[i] = dis_p[i] + city_dis[*(*(colony + i) + j)][*(*(colony + i) + j + 1)];
dis_p[i] = dis_p[i] + city_dis[**(colony + i)][*(*(colony + i) + xCity - 1)];
}
ibest = 0; sumbest = dis_p[0]; /* init ibest & sumbest */
sumTemp = sumbest * 5;
speed = 100000000;
loopcounter = 0; Ni = 0; /* initialize GunNum & Ni */
//printf("init success!!!\n");
}