模拟退火

星星还是树

#include <bits/stdc++.h>
using namespace std;
typedef double db;
typedef pair<double, double> pdd;
const int N = 105;
int n;
pdd p[N];
db ans = DBL_MAX;
db my_rand(db l, db r)
{
	return (db)rand() / RAND_MAX * (r - l) + l;
}
db calc(pdd a)
{
	db sum = 0.0;
	
	for (int i = 1; i <= n; ++ i)
	{
		sum = sum + sqrt((a.first - p[i].first) * (a.first - p[i].first) + (a.second - p[i].second) * (a.second - p[i].second));
	}
	ans = min(ans, sum);
	return sum;
}
void simulate_anneal()
{
	pdd a = make_pair(my_rand(0, 1e4), my_rand(0, 1e4));
	for (db T = 1e4; T >= 1e-4; T *= 0.99)
	{
		pdd b = make_pair(my_rand(a.first - T, a.first + T), my_rand(a.second - T, a.second + T));
		db dt = calc(b) - calc(a);
		if(exp(-dt / T) > my_rand(0.0, 1.0)) a = b; 
	}
}
int main()
{
	db start, end;
	start = clock();
	scanf("%d", &n);
	for (int i = 1; i <= n; ++ i) scanf("%lf %lf", &p[i].first, &p[i].second);
	
	while(((db)end - start) / CLOCKS_PER_SEC < 0.8) simulate_anneal(), end = clock();
	printf("%.0lf", ans);
	return 0;
}

保龄球

#include <bits/stdc++.h>
using namespace std;
typedef double db;
#define x first 
#define y second
const int N = 55;
int n, m, ans = 0;
pair<int, int> p[N];
int calc()
{
	int sum = 0;
	for (int i = 1; i <= m; ++ i)
	{
		if(p[i].x == 10) sum += p[i + 1].x + p[i + 1].y;
		else if(p[i].x + p[i].y == 10) sum += p[i + 1].x;
		
		sum += p[i].x + p[i].y;
	}
	ans = max(ans, sum);
	return sum;
}
void simulate_anneal()
{
	for (db T = 1e4; T >= 1e-4; T *= 0.999)
	{
		int a = rand() % (m + 1), b = rand() % (m + 1);
		if(a == 0) a = a + 1;
		if(b == 0) b = b + 1;
		int x = calc();
		swap(p[a], p[b]);
		if(n + (p[n].x == 10) == m)
		{
			int y = calc();
			if(exp(((db)y - x) / T) < (db)rand() / RAND_MAX) swap(p[a], p[b]); 
		}
		else swap(p[a], p[b]);
	}
}
int main()
{
	db start;
	start = clock();
	scanf("%d", &n);
	for (int i = 1; i <= n; ++ i) scanf("%d %d", &p[i].x, &p[i].y);
	if(p[n].x == 10) scanf("%d %d", &p[n + 1].x, &p[n + 1].y), m = n + 1;
	else m = n;
	while(((db)clock() - start) / CLOCKS_PER_SEC <= 0.8) simulate_anneal(); 
	printf("%d", ans);
	return 0;
} 

均分数据

#include <bits/stdc++.h>
using namespace std;
const int N = 25;
int n, m;
typedef double db;
db a[N], b[N], ans = DBL_MAX;
priority_queue<db, vector<db>, greater<db> > q;
db calc()
{
	for (int i = 1; i <= m; ++ i) q.push(a[i]);
	for (int i = m + 1; i <= n; ++ i)
	{
		db num = q.top();
		q.pop();
		q.push(num + a[i]);
	}
	int cnt = 0;
	db sum = 0.0, tot = 0.0;
	while(!q.empty())
	{
		b[++ cnt] = q.top();
		q.pop();
		sum += b[cnt];
	}
	sum = sum / (db)m;
	for (int i = 1; i <= m; ++ i)
	{
		tot = tot + (b[i] - sum) * (b[i] - sum);
	}
	tot = sqrt(tot / (db)m);
	ans = min(ans, tot);
	return tot;
}
void simulate_anneal()
{
	for (db t = 1e4; t >= 1e-4; t *= 0.999)
	{
		int p = rand() % (n + 1), q = rand() % (n + 1);
		if(!p) p ++;
		if(!q) q ++;
		db x = calc();
		swap(a[p], a[q]);
		db y = calc();
		if(exp((x - y) / t) < rand() / RAND_MAX) swap(a[p], a[q]);  
	}
	return ;
}
int main()
{
	scanf("%d %d", &n, &m);
	for (int i = 1; i <= n; ++ i) scanf("%lf", &a[i]);
	db start;
	start = clock();
	while(((db)clock() - start) / CLOCKS_PER_SEC < 0.8) simulate_anneal();
	printf("%.2lf", ans);
}

posted @ 2025-02-13 10:41  Helioca  阅读(23)  评论(0)    收藏  举报
Document