社区讨论
模拟退火,但是不知道是思路正确性的问题还是参数需要微调
P5544[JSOI2016] 炸弹攻击1参与者 2已保存回复 9
讨论操作
快速查看讨论及其快照的属性,并进行相关操作。
- 当前回复
- 9 条
- 当前快照
- 1 份
- 快照标识符
- @lo37bbua
- 此快照首次捕获于
- 2023/10/24 01:58 2 年前
- 此快照最后确认于
- 2023/10/24 01:58 2 年前
思路是:为避免每次模拟退火随机到的点偏离敌人太远,所以每次执行模拟退火随机的第一个点就直接随机敌人
CPP#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <ctime>
#include <cctype>
using namespace std;
#define x first
#define y second
struct Build {double x, y, r;};
struct Enemy {double x, y;};
typedef pair<double, double> PDD;
const int N = 20, M = 1010;
Build buil[N];
Enemy enem[M];
int n, m, R;
int ans;
inline int read()
{
int s = 0, w = 1;
char ch = getchar();
while (!isdigit(ch)) { if (ch == '-') w = -1; ch = getchar();}
while (isdigit(ch)) s = (s << 3) + (s << 1) + ch - '0', ch = getchar();
return s * w;
}
double rand(double l, double r)
{
return (double)rand() / RAND_MAX * (r - l) + l;
}
int calc(PDD p)
{
double t = R;
for (int i = 1; i <= n; ++i)
{
double dx = buil[i].x - p.x;
double dy = buil[i].y - p.y;
double dist = sqrt(dx * dx + dy * dy);
t = min(t, dist - buil[i].r);
}
int cnt = 0;
for (int i = 1; i <= m; ++i)
{
double dx = enem[i].x - p.x;
double dy = enem[i].y - p.y;
double dist = sqrt(dx * dx + dy * dy);
if (dist <= t) ++ cnt;
}
ans = max(ans, cnt);
return cnt;
}
void simulate_anneal()
{
int k = rand() % m + 1;
PDD cur(enem[k].x, enem[k].y);
for (double t = 2500; t > 1e-2 &&
(double)clock() / CLOCKS_PER_SEC <= 0.95; t *= 0.99)
{
PDD np(rand(cur.x - t, cur.x + t), rand(cur.y - t, cur.y + t));
int x = calc(cur), y = calc(np);
int d = y - x;
if (exp(d / t) > rand(0, 1)) cur = np;
}
}
int main()
{
n = read(), m = read(), R = read();
for (int i = 1; i <= n; ++i)
buil[i].x = read(), buil[i].y = read(), buil[i].r = read();
for (int i = 1; i <= m; ++i)
enem[i].x = read(), enem[i].y = read();
while ((double)clock() / CLOCKS_PER_SEC <= 0.95) simulate_anneal();
printf("%d", ans);
return 0;
}
但是把这句话改一下:
CPPif (exp(d / t) > rand(0, 1)) cur = np;
改成:
CPPif (d > 0) cur = np;
(其实就是把模拟退火变成爬山法)
这么说模拟退火的做法是思路没问题,但是参数调的不对吗?
求问dalao,感谢!
回复
共 9 条回复,欢迎继续交流。
正在加载回复...