#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<time.h>
#include<math.h>
#include<iostream>
using namespace std
;
#define M 10
#define N 31
#define T 10000
#define EARTH_RADIUS 6378.137
#define PI acos(-1)
int bestOne
[N
];
int bestDistance
=100000;
int bestT
;
int t
;
int oldPopulation
[M
][N
];
int newPopulation
[M
][N
];
int fit
[M
];
double lfit
[M
];
double pCorss
=0.8;
double pMutate
=0.1;
double city_pos
[N
][2] =
{
{103.73, 36.03},{101.74, 36.56},{104.06, 30.67},{114.48, 38.03},
{102.73, 25.04},{106.71, 26.57},{114.31, 30.52},{113.65, 34.76},
{117.00, 36.65},{118.78, 32.04},{117.27, 31.86},{120.19, 30.26},
{115.89, 28.68},{119.30, 26.08},{113.23, 23.16},{113.00, 28.21},
{110.35, 20.02},{123.38, 41.80},{125.35, 43.88},{126.63, 45.75},
{112.53, 37.87},{108.95, 34.27},{87.68, 43.77}, {116.46, 39.92},
{121.48, 31.22},{106.54, 29.59},{117.20, 39.13},{111.65, 40.82},
{108.33, 22.84},{91.11, 29.97}, {106.27, 38.47}
};
string city_name
[N
]={
"兰州","西宁","成都","石家庄","昆明","贵阳","武汉","郑州","济南","南京",
"合肥","杭州","南昌","福州","广州","长沙","海口","沈阳","长春","哈尔滨",
"太原","西安","乌鲁木齐","北京","上海","重庆","天津","呼和浩特","南宁","拉萨",
"银川"
};
double rad(double d
)
{
return d
* PI
/ 180.0;
}
void copyGh(int k
, int kk
) {
int i
;
for (i
= 0; i
< N
; i
++) {
newPopulation
[k
][i
] = oldPopulation
[kk
][i
];
}
}
double getDistance(double lat1
, double lng1
, double lat2
, double lng2
)
{
double radLat1
= rad(lat1
);
double radLat2
= rad(lat2
);
double a
= radLat1
- radLat2
;
double b
= rad(lng1
) - rad(lng2
);
double s
= 2 * asin(sqrt(pow(sin(a
/2),2) + cos(radLat1
)*cos(radLat2
)*pow(sin(b
/2),2)));
s
= s
* EARTH_RADIUS
;
s
= round(s
* 10000) / 10000;
return s
;
}
/将路径作为种群适应度返回
double pathLen(int * arry
){
double path
= 0;
int first_city
= arry
[0];
for(int i
=0;i
<N
-1;i
++)
{
int this_city
= arry
[i
];
int next_city
= arry
[i
+1];
double dis
= getDistance(city_pos
[this_city
][0],city_pos
[this_city
][1],
city_pos
[next_city
][0],city_pos
[next_city
][1]);
path
+= dis
;
}
int last_city
= arry
[N
-1];
double last_dis
= getDistance(city_pos
[first_city
][0],city_pos
[first_city
][1],
city_pos
[last_city
][0],city_pos
[last_city
][1]);
path
= path
+ last_dis
;
return path
;
}
void init(){
int i
,j
,k
;
for(i
=0;i
<M
;i
++){
double r1
= ((double)rand())/(RAND_MAX
+1.0);
int pos1
= (int)(N
*r1
);
int j
;
oldPopulation
[i
][0]=pos1
;
for(j
=1;j
<N
;){
double r2
= ((double)rand())/(RAND_MAX
+1.0);
int pos2
= (int)(N
*r2
);
oldPopulation
[i
][j
]=pos2
;
for(k
=0;k
<j
;++k
){
if(oldPopulation
[i
][k
]==oldPopulation
[i
][j
])
break;
}
if(j
==k
)
j
++;
}
}
}
void countLRate(){
double sumRate
=0;
for(int k
=0;k
<M
;k
++){
sumRate
+=fit
[k
];
}
lfit
[0]=(double)(fit
[0]/sumRate
);
for(int k
=1;k
<M
;k
++){
lfit
[k
]=(double)(fit
[k
]/sumRate
+lfit
[k
-1]);
}
}
void variation(int k
)
{
double r1
= ((double)rand())/(RAND_MAX
+1.0);
double r2
= ((double)rand())/(RAND_MAX
+1.0);
int pos1
= (int)(N
*r1
);
int pos2
= (int)(N
*r2
);
while(pos1
==pos2
){
r1
= ((double)rand())/(RAND_MAX
+1.0);
pos1
= (int)(N
*r1
);
}
int temp
= newPopulation
[k
][pos1
];
newPopulation
[k
][pos1
] = newPopulation
[k
][pos2
];
newPopulation
[k
][pos2
] = temp
;
}
void selectBest(){
int k
, i
, maxid
;
int maxevaluation
;
maxid
= 0;
maxevaluation
= fit
[0];
for (k
= 1; k
< M
; k
++) {
if (maxevaluation
> fit
[k
]) {
maxevaluation
= fit
[k
];
maxid
= k
;
}
}
if (bestDistance
> maxevaluation
) {
bestDistance
= maxevaluation
;
bestT
= t
;
for (i
= 0; i
< N
; i
++) {
bestOne
[i
] = oldPopulation
[maxid
][i
];
}
}
copyGh(0, maxid
);
}
void selectChild(){
int k
, i
, selectId
;
double ran1
;
for (k
= 1; k
< M
; k
++) {
ran1
= ((double)rand())/(RAND_MAX
+1.0);
for (i
= 0; i
< M
; i
++) {
if (ran1
<= lfit
[i
]) {
break;
}
}
selectId
= i
;
copyGh(k
, selectId
);
}
}
bool hasElement(int* a
, int b
) {
int len
= sizeof(a
) / sizeof(a
[0]);
for (int i
= 0; i
< len
; i
++) {
if (a
[i
] == b
) {
return true;
}
}
return false;
}
void orderCrossover(int k1
, int k2
) {
int child1
[N
];
int child2
[N
];
double r1
= ((double)rand())/(RAND_MAX
+1.0);
double r2
= ((double)rand())/(RAND_MAX
+1.0);
int ran1
= (int)(r1
*N
);
int ran2
= (int)(r2
*N
);
while (ran1
== ran2
) {
r2
= ((double)rand())/(RAND_MAX
+1.0);
ran2
= (int)(r2
*N
);
}
if (ran1
> ran2
) {
int temp
= ran1
;
ran1
= ran2
;
ran2
= temp
;
}
for (int i
= ran1
; i
<= ran2
; i
++) {
child1
[i
] = newPopulation
[k1
][i
];
child2
[i
] = newPopulation
[k2
][i
];
}
for (int i
= 0; i
< N
; i
++) {
if (i
>= ran1
&& i
<= ran2
) {
continue;
}
for (int j
= 0; j
< N
; j
++) {
if (!hasElement(child1
, newPopulation
[k2
][j
])) {
child1
[i
] = newPopulation
[k2
][j
];
break;
}
}
}
for (int i
= 0; i
< N
; i
++) {
if (i
>= ran1
&& i
<= ran2
) {
continue;
}
for (int j
= 0; j
< N
; j
++) {
if (!hasElement(child2
, newPopulation
[k1
][j
])) {
child2
[i
] = newPopulation
[k1
][j
];
break;
}
}
}
}
void evolution() {
int k
;
selectBest();
selectChild();
double r
;
for (k
= 0; k
< M
; k
= k
+ 2) {
r
= ((double)rand())/(RAND_MAX
+1.0);
if (r
< pCorss
) {
orderCrossover(k
, k
+ 1);
} else {
r
= ((double)rand())/(RAND_MAX
+1.0);
if (r
< pMutate
) {
variation(k
);
}
r
= ((double)rand())/(RAND_MAX
+1.0);
if (r
< pMutate
) {
variation(k
+ 1);
}
}
}
}
int main(){
srand((unsigned)time(NULL));
time_t start
,finish
;
start
= clock();
int k
,i
;
init();
countLRate();
cout
<<"初代种群: ";
for (k
= 0; k
< M
; k
++) {
for (i
= 0; i
< N
; i
++) {
cout
<<oldPopulation
[k
][i
]<<" ";
}
cout
<<endl
;
}
for (t
= 0; t
< T
; t
++) {
evolution();
for (k
= 0; k
< M
; k
++) {
for (i
= 0; i
< N
; i
++) {
oldPopulation
[k
][i
] = newPopulation
[k
][i
];
}
}
for (k
= 0; k
< M
; k
++) {
fit
[k
] = pathLen(oldPopulation
[k
]);
}
countLRate();
}
cout
<<"末代种群: ";
for (k
= 0; k
< M
; k
++) {
for (i
= 0; i
< N
; i
++) {
cout
<<oldPopulation
[k
][i
]<<" ";
}
cout
<<endl
;
}
cout
<<bestDistance
<<endl
;
cout
<<"最佳个体: ";
for (i
= 0; i
< N
; i
++) {
cout
<<bestOne
[i
]<<" ";
}
cout
<<endl
;
finish
=clock();
cout
<<"花费时间: ";
cout
<<(finish
-start
)*1000<<"ms";
return 0;
}
转载请注明原文地址: https://lol.8miu.com/read-16582.html