Country Meow (模拟退火)

模拟退火:

  • 核心就是通过局部最优,然后随机跳出这个局部,找下一个最优解
  • 通过物理的那个思想
  • 核心元素:  T=2000,(一般2000-5000) rate=0.996, limt 最低T,更具题目来看(在满足题目条件的情况下,多次循环)

代码:

void th()
{
    node ans;
    ans.x=0;ans.y=0;ans.z=0;
     ANS=get(ans); 
    while(T>lmt)
    {
      node t;
      t.x=ans.x+((rand()<<1)-RAND_MAX)*T;
      t.y=ans.y+((rand()<<1)-RAND_MAX)*T;
      t.z=ans.z+((rand()<<1)-RAND_MAX)*T;
      double tmp=get(t);
      // 上面是 计算下一个步的 函数值. 
      double de=tmp-ANS; // 和当前的最优答案比较,更新 
      if(de<0)     // 比他优化,就更新 
      {      
          ANS=tmp;
          ans=t;
      }
      else if(exp((-de)/T)*RAND_MAX>rand()) ans=t; // 不然就随机看是否跳出跳出这个范围,进行更新, 然后 要保证()/T 是负数(通过是否加负号的方式) 
      T*=rate; // 退火 
    }
}
View Code

好好看看那个2个 关于随机的代码, srand(time(0)),和 rand(),记得写.

题目: 大意, 求一个球包裹所有点的最小半径

2022—暑假1 - Virtual Judge (vjudge.net)

本题代码:

#include <bits/stdc++.h>
using namespace std;
#define M 100005
#define ri register int 

int n,m;
struct node {
    double x;
    double y;
    double z;
}p[M];
double T=2000;
double rate=0.996;
double lmt=1e-300;
double gg(node a,node b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y)+(a.z-b.z)*(a.z-b.z));
}
double get(node a)
{
    double mx=0;
    for(ri i=1;i<=n;i++)
    {
        mx=max(mx,gg(a,p[i]));
    }
    return mx;
}
double ANS;
void th()
{
    node ans;
    ans.x=0;ans.y=0;ans.z=0;
     ANS=get(ans); 
    while(T>lmt)
    {
      node t;
      t.x=ans.x+((rand()<<1)-RAND_MAX)*T;
      t.y=ans.y+((rand()<<1)-RAND_MAX)*T;
      t.z=ans.z+((rand()<<1)-RAND_MAX)*T;
      double tmp=get(t);
      // 上面是 计算下一个步的 函数值. 
      double de=tmp-ANS; // 和当前的最优答案比较,更新 
      if(de<0)     // 比他优化,就更新 
      {      
          ANS=tmp;
          ans=t;
      }
      else if(exp((-de)/T)*RAND_MAX>rand()) ans=t; // 不然就随机看是否跳出跳出这个范围,进行更新, 然后 要保证()/T 是负数(通过是否加负号的方式) 
      T*=rate; // 退火 
    }
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);cout.tie(0);
    
    srand(time(0));
    rand();
    cin>>n;
    for(ri i=1;i<=n;i++) 
    cin>>p[i].x>>p[i].y>>p[i].z;
    th();
    cout<<ANS;
    
}
View Code

 

posted @ 2022-07-11 10:41  VxiaohuanV  阅读(24)  评论(0编辑  收藏  举报