玄关,刚学模拟退火1ms
查看原帖
玄关,刚学模拟退火1ms
749175
114514xxx楼主2024/10/1 17:28

为什么概率那块常数对精度影响那么大?

无常数,提交记录

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+25;
struct node{
	long double x,y,w;
}a[N];
int n;
double ax,ay,aw;
double Rand() { 
	return (long double)(rand())/RAND_MAX; 
}
long double get_enegry(long double x,long double y){
	long double r=0;
	for(int i=1;i<=n;i++){
		long double dx=a[i].x-x;
		long double dy=a[i].y-y;
		r+=sqrt(dx*dx+dy*dy)*a[i].w;
	}
	return r;
}
void SimulateAnneal(){
	long double t=1e18+25;
	while(t>1e-18){
		long double dx=ax+(Rand()-0.5)*t;
		long double dy=ay+(Rand()-0.5)*t;
		long double dw=get_enegry(dx,dy);
		long double delta=aw-dw;
		//cout<<delta<<endl;
		if(delta>0){
			ax=dx;
			ay=dy;
			aw=dw;
		}else if(exp(delta/t)>Rand()){
			ax=dx;
			ay=dy;
			aw=dw;
		}
		t*=0.999;
	}
}
signed main(){
	srand(time(0));
    srand(rand());
	std::ios::sync_with_stdio(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i].x>>a[i].y>>a[i].w;	
		ax+=a[i].x;
		ay+=a[i].y;	
	}
	ax/=n;
	ay/=n;
	aw=get_enegry(ax,ay);
	SimulateAnneal();
	SimulateAnneal();
	SimulateAnneal();
	printf("%.3lf %.3lf",ax,ay);
}

有常数,提交记录

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+25;
struct node{
	long double x,y,w;
}a[N];
int n;
double ax,ay,aw;
double Rand() { 
	return (long double)(rand())/RAND_MAX; 
}
long double get_enegry(long double x,long double y){
	long double r=0;
	for(int i=1;i<=n;i++){
		long double dx=a[i].x-x;
		long double dy=a[i].y-y;
		r+=sqrt(dx*dx+dy*dy)*a[i].w;
	}
	return r;
}
void SimulateAnneal(){
	long double t=1e18+25;
	while(t>1e-18){
		long double dx=ax+(Rand()-0.5)*t;
		long double dy=ay+(Rand()-0.5)*t;
		long double dw=get_enegry(dx,dy);
		long double delta=aw-dw;
		//cout<<delta<<endl;
		if(delta>0){
			ax=dx;
			ay=dy;
			aw=dw;
		}else if(exp(delta/t)/2.0467>Rand()){
			ax=dx;
			ay=dy;
			aw=dw;
		}
		t*=0.999;
	}
}
signed main(){
	srand(time(0));
    srand(rand());
	std::ios::sync_with_stdio(0);
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i].x>>a[i].y>>a[i].w;	
		ax+=a[i].x;
		ay+=a[i].y;	
	}
	ax/=n;
	ay/=n;
	aw=get_enegry(ax,ay);
	SimulateAnneal();
	SimulateAnneal();
	SimulateAnneal();
	printf("%.3lf %.3lf",ax,ay);
}
2024/10/1 17:28
加载中...