#include #include using namespace std; long double ENG(int x1,int y1, int x2, int y2,int t){//エネルギー計算 座標と定数を入力 long double uq= sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); return uq*uq*t; } long SCORE(long double s){ return (long)(1000000000/(1000+sqrt(s))); } static uint32_t randxor(){//ランダム数(int) static uint32_t x = 123456789; static uint32_t y = 362436069; static uint32_t z = 521288629; static uint32_t w = 88675123; uint32_t t = x ^ (x << 11); x = y; y = z; z = w; return w = (w ^ (w >> 19)) ^ (t ^ (t >> 8)); } static double rand01(){//ランダム数(0.0以上1.0未満の小数) return(randxor()+0.5)*(1.0/UINT_MAX); } double timelmt_1=200,timelmt_2=950; double gettime; chrono::system_clock::time_point time_now; chrono::system_clock::time_point time_start = chrono::system_clock::now(); double start_temp_1=500, start_temp_2=5, end_temp=0.001,temp; int main(){ int n,m; cin>>n>>m; vectora(n),b(n); for(int i=0; i>a[i]>>b[i]; } vector>eng(100,vector(100)),eng_t; vector>>eng_sr(100,vector>(100)); for(int i=0;i<100;i++){ for(int j=0;j<100;j++){ if(i!=j) eng[i][j]=ENG(a[i],b[i],a[j],b[j],25); else eng[i][j]=1000000000001; eng_sr[i][j]=make_pair(eng[i][j],j); } sort(eng_sr[i].begin(),eng_sr[i].end());//eng_srのみエネルギーを昇順に並べ替え } vectorc,c_best,d,d_best;//ロボてりーの位置 最初は均等に置く c.push_back(250),d.push_back(250); c.push_back(250),d.push_back(500); c.push_back(250),d.push_back(750); c.push_back(500),d.push_back(250); c.push_back(500),d.push_back(750); c.push_back(750),d.push_back(250); c.push_back(750),d.push_back(500); c.push_back(750),d.push_back(750); vectortr,tr_best;//惑星を回る順番 bitset<100>visited; int now=0; visited[now]=true; tr.push_back(0); while(true){//一番近い惑星に行く bool jdg=false; for(int i=0; i<99; i++){ if(!(visited[eng_sr[now][i].second])){ int next=eng_sr[now][i].second; tr.push_back(next); now=next; visited[next]=true; jdg=true; break; } } if(!jdg)break; } tr.push_back(0); long double eng_sum=0;//消費エネルギー総和 for(int i=0; i<100; i++){ eng_sum+=eng[tr[i]][tr[i+1]]; } long score,score_t,score_best; score=SCORE(eng_sum); score_best=score; tr_best=tr; int cnt1=0,cnt1_rec=0; int cnt2=0,cnt2_rec=0; while(gettime(time_now-time_start).count(); temp=start_temp_1+(end_temp-start_temp_1)*gettime/timelmt_1; } int A=randxor()%99+1, B=randxor()%99+1; int na=tr[A-1],a=tr[A],an=tr[A+1]; int nb=tr[B-1],b=tr[B],bn=tr[B+1]; long double eng_m=eng[na][a]+eng[a][an]+eng[nb][b]+eng[b][bn]; long double eng_p=eng[na][b]+eng[b][an]+eng[nb][a]+eng[a][bn]; int score_r=SCORE(eng_sum-eng_m+eng_p); double prob=exp((score_r-score)/temp); double rnd_d=rand01(); //cout<rnd_d){ tr[A]=b,tr[B]=a; eng_sum=eng_sum-eng_m+eng_p; score=score_r; if(score>score_best){ tr_best=tr; score_best=score; } cnt1_rec++; } cnt1++; } score=score_best; bitset<100>check,check_best; mapst,st_best; //ステーション位置 while(gettime(time_now-time_start).count(); temp=start_temp_2+(end_temp-start_temp_2)*(gettime/(timelmt_2-timelmt_1)); } eng_t=eng; bitset<100>check_t;//この惑星からステーションに行くか mapst_t;//この惑星から行くステーションの番号 vectorc_t=c, d_t=d; int rnd_st=randxor()%8, rnd_dis=randxor()%5+1,rnd_dir=randxor()%4; if(rnd_dir==0) c_t[rnd_st]=min(1000,c[rnd_st]+rnd_dis); else if(rnd_dir==1) c_t[rnd_st]=max(0,c[rnd_st]-rnd_dis); else if(rnd_dir==2) d_t[rnd_st]=min(1000,d[rnd_st]+rnd_dis); else d_t[rnd_st]=max(0,d[rnd_st]-rnd_dis); for(int j=0; j<100; j++){//すべての惑星間のルートについて int w1=tr_best[j],w2=tr_best[j+1];//惑星w1からw2へのルートについて調べる for(int i=0; i<8; i++){//すべてのステーションについて long double eng_b=eng_t[w1][w2];//惑星w1→惑星w2のエネルギー(test値,他のステーション経由の最小値と比較) //惑星w1→ステーションi→惑星w2のエネルギー long double eng_c=ENG(a[w1],b[w1],c_t[i],d_t[i],5)+ENG(c_t[i],d_t[i],a[w2],b[w2],5); if(eng_b>eng_c){//ステーションiを経由した方がエネルギーが少ないなら(他のステーションとも比べる) eng_t[w1][w2]=eng_c;//w1-w2のエネルギー(test)を変更する check_t[w1]=true;//w1の次はステーション st_t[w1]=i;//w1から行くステーションはi } }//惑星間の全ルート }//全ステーション eng_sum=0;//消費エネルギー総和をtest値で計算しなおす for(int i=0; i<100; i++){ eng_sum+=eng_t[tr_best[i]][tr_best[i+1]]; } score_t=SCORE(eng_sum);//scoreを計算しなおす double prob=exp((score_t-score)/temp); double rnd_d=rand01(); if(prob>rnd_d){ score=score_t; check=check_t; st=st_t; c=c_t; d=d_t; cnt2_rec++; /* cout<<"rec score "<score_best){//best更新なら score_best=score; check_best=check; st_best=st; c_best=c; d_best=d; } cnt2++; } for(int i=0; i<8; i++){ cout<