模拟退火求调qwq
查看原帖
模拟退火求调qwq
519573
Daniel_yao楼主2023/3/29 17:32
#include <bits/stdc++.h>
#define int long long
#define H 19260817
#define rint register int
#define For(i,l,r) for(rint i=l;i<=r;++i)
#define FOR(i,r,l) for(rint i=r;i>=l;--i)
#define MOD 1000003
#define mod 1000000007
#define inf 1e18 
using namespace std;

inline int read() {
  rint x=0,f=1;char ch=getchar();
  while(ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
  while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
  return x*f;
}

void print(int x){
  if(x<0){putchar('-');x=-x;}
  if(x>9){print(x/10);putchar(x%10+'0');}
  else putchar(x+'0');
  return;
}

const int N = 1e3 + 10;

struct Node {
  double x, y;
} a[N];

int n, cnt, maxy = -inf, Ans[N], Anss[N], k;

bool vis[N];

double ans, anss;

double dis(double a, double b, double c, double d) {
  return sqrt((a-c)*(a-c)+(b-d)*(b-d));
}

void dfs(int x) {
  int ki = -1;
  double mini = inf; 
  For(i,1,n) {
    if(!vis[i] && mini > dis(a[i].x, a[i].y, a[x].x, a[x].y)) {
      ki = i, mini = dis(a[i].x, a[i].y, a[x].x, a[x].y);
    }
  }
  if(ki == -1) return ;
  ans += mini;
  Ans[++cnt] = ki, vis[ki] = 1;
  dfs(ki);
}

void SA() {
  for (double T = 10000, dT = 0.9775; T > 1e-10; T *= dT) {
    int x = rand() % (n-1) + 2, y = rand() % (n-1) + 2; 
    double tmp = anss; 
    tmp = tmp - dis(a[Ans[x-1]].x, a[Ans[x-1]].y, a[Ans[x]].x, a[Ans[x]].y) //由于Ans[x], Ans[y]只对左右两边的距离有影响 
    - dis(a[Ans[x+1]].y, a[Ans[x+1]].y, a[Ans[x]].y, a[Ans[x]].y);
    tmp = tmp - dis(a[Ans[y-1]].x, a[Ans[y-1]].y, a[Ans[y]].x, a[Ans[y]].y) 
    - dis(a[Ans[y+1]].y, a[Ans[y+1]].y, a[Ans[y]].y, a[Ans[y]].y);
    swap(Ans[x], Ans[y]);
    tmp = tmp + dis(a[Ans[x-1]].x, a[Ans[x-1]].y, a[Ans[x]].x, a[Ans[x]].y) 
    + dis(a[Ans[x+1]].y, a[Ans[x+1]].y, a[Ans[x]].y, a[Ans[x]].y);
    tmp = tmp + dis(a[Ans[y-1]].x, a[Ans[y-1]].y, a[Ans[y]].x, a[Ans[y]].y) 
    + dis(a[Ans[y+1]].y, a[Ans[y+1]].y, a[Ans[y]].y, a[Ans[y]].y);
//    cout << "tmp:\n" << tmp << '\n';
    if(tmp < anss) {
      anss = tmp;
      if(ans > tmp) {
        ans = tmp;
        For(i,1,n) Anss[i] = Ans[i]; 
      }
    } else if(exp(-(tmp-anss)/T) * RAND_MAX < rand()) {
      swap(Ans[x], Ans[y]);
    } else {
      anss = tmp;
    }
  }
}

signed main() {
  srand(time(0));
  srand(rand());
  n = read();
  For(i,1,n) {
    cin >> a[i].x >> a[i].y;
    if(maxy < a[i].y) {
      maxy = a[i].y;
      k = i;
    }
  }
  For(i,1,n) {
    a[n+1] = a[i];
  } 
  vis[k] = 1;
  Ans[++cnt] = k;
  dfs(k);//贪心初始化 
  anss = ans;
  For(i,1,n) Anss[i] = Ans[i];
//  cout << "start:" << ans << '\n';
  while ((double)clock() / CLOCKS_PER_SEC < 0.75) SA();
  For(i,1,n) cout << Anss[i] << ' '; 
  return 0;
}
/*
1 3 2 4 5 
1 2 3 4 5
*/
2023/3/29 17:32
加载中...