社区讨论
模拟退火求看❤
P4035[JSOI2008] 球形空间产生器参与者 4已保存回复 11
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 11 条
- 当前快照
- 1 份
- 快照标识符
- @lo19g35m
- 此快照首次捕获于
- 2023/10/22 17:22 2 年前
- 此快照最后确认于
- 2023/11/02 17:24 2 年前
CPP
#include<bits/stdc++.h>
#define int long long
using namespace std;
namespace Testify{
inline int read(){
int f(1),x(0);
char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch^48);
return f*x;
}
inline void WritE(int x){
if(x<0) putchar('-'),x=-x;
if(x>9) WritE(x/10);
putchar(x%10+48);
}
inline void write(int x){
WritE(x);
puts("");
}
inline void Write(int x){
WritE(x);
putchar(' ');
}
}
using namespace Testify;
int n;
mt19937 rd(chrono::high_resolution_clock::now().time_since_epoch().count());
inline int radom(int l,int r){
return rd()%(r-l+1)+l;
}
const int N=12;
double x[N][N],Ans[N],ans,now[N];
inline double energy(){
double sum=0;
for(register int i=1;i<=n+1;i++){
double res=0;
for(register int j=1;j<=n;j++){
res+=(now[j]-x[i][j])*(now[j]-x[i][j]);
}
res=sqrt(res);
sum+=res;
}
return sum;
}
inline void SA(){
double T=1;
while(T>1e-15){
if((double)clock()/CLOCKS_PER_SEC>0.99){
for(register int i=1;i<=n;i++){
printf("%.3lf ",Ans[i]);
}
exit(0);
}
int ra=radom(1,n);
double yuan=now[ra];
IZANA:;
now[ra]=now[ra]+(radom(0,20000)*2-20000)*T;
if(abs(now[ra])>20000){
T*=0.985;
goto IZANA;
}
// cerr<<now[ra]<<endl;
double e=energy();
double delta=e-ans;
if(delta<0){
ans=e;
for(register int i=1;i<=n;i++){
Ans[i]=now[i];
}
}
else if(exp(-delta/T)*RAND_MAX<radom(0,RAND_MAX)){
now[ra]=yuan;
}
T*=0.99995;
}
}
signed main(void){
n=read();
for(register int i=1;i<=n+1;i++){
for(register int j=1;j<=n;j++){
scanf("%lf",&x[i][j]);
}
}
ans=energy();
while(1){
SA();
}
return 0;
}
按正常思路打的,但是一直随机到极大的数,求教教怎么做

回复
共 11 条回复,欢迎继续交流。
正在加载回复...