C++版本
遗传算法、模拟退火、蚁群算法、Hopfield神经网络、禁忌搜索,部分思路参考网络或者Paper。
//遗传算法解决TSP问题,35s
# include
using namespace std;
typedef long long LL;
const int times = 3000;//遗传代数
const int chrom = 34; //染色体长度
const int num = 380; //染色体数量
int pc = 80, pm = 6;
int tmp[num+3];
double mp[chrom+3][chrom+3]={0}; //图
int vis[chrom+3], cur;
double fitness[num+3], INF = 1e13;
vectorg[num+3], neb[chrom+3], nb[chrom+3];
vectordebug[times+3];
double debug2[times+3];
struct node{
double x, y;
}point[chrom+3];
double dis(int u, int v){
double x = point[u].x-point[v].x;
double y = point[u].y-point[v].y;
return sqrt(x*x+y*y);
}
void init_map(){//初始化边的情况
for(int i=0; iid;
for(int i=0; ix){//计算染色体的距离
double res = mp[x[0]][x[chrom-1]];
for(int i=0; i fitness[y];
}
void selection(){//选自算子
for(int i=0; i core(int flag, vectorneb[]){
memset(vis, 0, sizeof(vis));
for(int i=0; ians;
vector >best;
ans.push_back(g[flag][0]);
for(int i=0; i get_best(){
double min_dis = 1e9;
int min_id = 0;
for(int i=0; i x){
min_dis = x;
min_id = i;
}
}
return {min_dis,min_id};
}
void crosscover(){
for(int i=0; itmp1 = core(i, neb);
vectortmp2 = core(num-i-1, neb);
vector > >best;
best.push_back({cal_distance(g[i]), g[i]});
best.push_back({cal_distance(g[num-i-1]), g[num-i-1]});
best.push_back({cal_distance(tmp1), tmp1});
best.push_back({cal_distance(tmp2), tmp2});
sort(best.begin(), best.end());
g[i] = best[0].second;
g[num-i-1] = best[1].second;
}
}
}
void mutation(){
int gai = pm;
if(cur >= times*3/4) gai = pm*5;
for(int i=0; i y) swap(x, y);
for(int j=0; x+j<=(x+y>>1); ++j){
swap(g[i][x+j], g[i][y-j]);
}
}
}
}
int main(){
//freopen("a.txt", "r", stdin);
//freopen("2.txt", "w", stdout);
srand(time(0));
init_map();
encoding();
for(int i=0; iit = get_best();
debug[i] = g[it.second];
debug2[i] = it.first;
crosscover();
mutation();
}
printf("%f\n",debug2[times-1]);
return 0;
}
//模拟退火算法,2.6s
# include
using namespace std;
const int num = 34;
double T0 = 18000;
double T1 = 1e-9;
double r = 0.98;
int len = 1000;
double mp[num+3][num+3];
struct node{
double x, y;
}point[num+3];
double dis(int u, int v){
double x = point[u].x-point[v].x;
double y = point[u].y-point[v].y;
return sqrt(x*x+y*y);
}
void init_map(){//初始化边的情况
for(int i=0; ix){//计算染色体的距离
double res = mp[x[0]][x[num-1]];
for(int i=0; i&v){
int x = rand()%num;
int y = rand()%num;
while(y == x) y = rand()%num;
for(int i=0; i+x<=(x+y>>1); ++i)
swap(v[i+x], v[y-i]);
}
int main(){
//freopen("a.txt", "r", stdin);
//reopen("3.txt", "w", stdout);
srand(time(0));
vectorans;
init_map();
int icount = 0, cnt = 0;
for(int i=0; i T1){
for(int i=0; itmp = ans;
change(tmp);
double pre = cal_distance(ans);//前
double cur = cal_distance(tmp);//后
if(cur < pre || exp(-(cur-pre)/T0) > ((double)rand())/RAND_MAX){
ans = tmp;
}
}
++icount;
T0 *= r;
}
printf("run %d %d times\n",icount,cnt);
printf("%f\n",cal_distance(ans));
for(int i:ans) printf("%d ",i);
return 0;
}
//蚂蚁群算法TSP,33s
# include
using namespace std;
const int N = 34;
const int M = 700;
double mp[N+3][N+3];
double phe[N+3][N+3];
double phe2[N+3][N+3];
double rate = 0.5;
double Q = 1000;
int path[M+3][N+3]={0};
int alpha = 1;
int beta = 4;
int times = 700;
bool vis[N+3];
struct node{
double x,y;
}point[N+3];
double dis(int u, int v){
double x = point[u].x-point[v].x;
double y = point[u].y-point[v].y;
return sqrt(x*x+y*y);
}
void init_map(){//初始化边的情况
for(int i=0; i 0){
double zhuan = rand()*1.0/RAND_MAX * POB;
for(int k=0; k
//Hopfield神经网络求解TSP,20s
# include
using namespace std;
const int N = 34;
double A = 10000,D = 75, U0 = 0.001, C = N*N;
double mp[N+3][N+3];
double U[(N+3)*(N+3)];
double V[(N+3)*(N+3)];
int id[N+3]={0};
double rnd(){//返回[-1,1]的随机浮点数
return 1.0*rand()/RAND_MAX*2-1;
}
struct node{
double x,y;
}point[N+3];
double dis(int u, int v){
double x = point[u].x-point[v].x;
double y = point[u].y-point[v].y;
return sqrt(x*x+y*y);
}
void init(){//初始化边的情况
for(int i=0; i > check_V(){
sets;
vectorg;
double imax[N+3]={0};
for(int i=0; ibb;
double tmp = 0, ans = 1e18;
int times = 80000;
while(times--){
update_U();
update_V();
auto it = check_V();
if(it.first < ans){
ans = it.first;
bb = it.second;
}
}
printf("%f\n",ans);
for(int i:bb) printf("%d ",i);
return 0;
}
//禁忌搜索,18s
# include
using namespace std;
const int N = 34;
const double inf = 1e18;
double mp[N+3][N+3];
int times = 8000;
int len = 12;
vector >jinji;
map,bool>Hash;
struct node{
double x, y;
}point[N+3];
double dis(int u, int v){
double x = point[u].x-point[v].x;
double y = point[u].y-point[v].y;
return sqrt(x*x+y*y);
}
void init(){
for(int i=0; ig){
double res = 0;
for(int i=0; ig){
if(Hash[g]) return;
jinji.push_back(g);
if(jinji.size() > len){
vectortmp = *jinji.begin();
Hash[tmp]= false;
jinji.erase(jinji.begin());
}
}
int main(){
//freopen("a.txt", "r", stdin);
//freopen("6.txt", "w", stdout);
srand(time(0));
init();
vectorans;
for(int i=0; it_ans, t_ans2;
for(int i=0; i<400; ++i){
vectorbase = ans;
int x = rand()%N, y = rand()%N;
if(x > y) swap(x, y);
for(int j=0; j<=(y-x>>1); ++j) swap(base[j], base[y-j]);
double tmp = cal(base);
if(tmp < t_val){
t_val = tmp;
t_ans = base;
}
else if(!Hash[base] && tmp < t_val2){
t_val2 = tmp;
t_ans = base;
}
}
if(t_val != inf){
ans = t_ans;
ans_val = t_val;
}
else if(t_val2 != inf){
ans = t_ans2;
ans_val = t_val2;
}
update(ans);
}
printf("%f\n",ans_val);
for(int i:ans) printf("%d ",i);
return 0;
}