【模拟退火】CF2C Commentator problem

简介: 笔记

题目描述


The Olympic Games in Bercouver are in full swing now. Here everyone has their own objectives: sportsmen compete for medals, and sport commentators compete for more convenient positions to give a running commentary. Today the main sport events take place at three round stadiums, and the commentator’s objective is to choose the best point of observation, that is to say the point from where all the three stadiums can be observed. As all the sport competitions are of the same importance, the stadiums should be observed at the same angle. If the number of points meeting the conditions is more than one, the point with the maximum angle of observation is prefered.


Would you, please, help the famous Berland commentator G. Berniev to find the best point of observation. It should be noted, that the stadiums do not hide each other, the commentator can easily see one stadium through the other.


输入格式


The input data consists of three lines, each of them describes the position of one stadium. The lines have the format x,y,r , where ( x,y ) are the coordinates of the stadium’s center  ( -10^3 <= x,y<=10^3 ) is its radius. All the numbers in the input data are integer, stadiums do not have common points, and their centers are not on the same line.


输出格式


Print the coordinates of the required point with five digits after the decimal point. If there is no answer meeting the conditions, the program shouldn’t print anything. The output data should be left blank.


具体思路

题意: 要求找到一个点,使得到三个圆的两切线张角相同,取最大张角的那个点输出,没有则不输出。


既然是模拟退火,那主要的就是两个部分:


估价函数

参数配置

那么对于评估函数的选定为:

1.png2.png

具体实现:

double evaluation(node &A) {
  double t[3], delta[3], res = 0;
  for (int i = 0; i < 3; i++)
    t[i] = distance(A, p[i]) / p[i].r;
  for (int i = 0; i < 3; i++) {
    delta[i] = t[i] - t[(i + 1) % 3];
    res += delta[i] * delta[i];
  }
  return res * 1e9;
}

3.png4.png

不过为了洛谷 AC 时刻的 🎉 还是很值得的。

5.png

那么附上全部代码:


代码实现

众所周知,rand()是个玄学

实验得: 1 / 2 {1 / 2}1/2 的概率通过

#include <bits/stdc++.h>
using namespace std;
const int N = 10;
const double eps = 1e-14;
const double gradient = 0.996;
struct Point {
  double x, y, r;
} p[N];
struct node {
  double x, y;
} nowNode, ansNode;
double MINX = 1e9, MAXX = -1e9, MINY = 1e9, MAXY = 1e9;
double distance(node &A, Point &B) {
  return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));
}
double evaluation(node &A) {
  double t[3], delta[3], res = 0;
  for (int i = 0; i < 3; i++)
    t[i] = distance(A, p[i]) / p[i].r;
  for (int i = 0; i < 3; i++) {
    delta[i] = t[i] - t[(i + 1) % 3];
    res += delta[i] * delta[i];
  }
  return res * 1e9;
}
node groop;
void SA() {
  nowNode = groop;
  double nowDelta = evaluation(nowNode);
  double T = 1e5;
  while(T > eps) {
    // double nowx = nowNode.x + (((rand() << 1) - RAND_MAX) > 0 ? -1 : 1) * T * rand() * 1.0 / RAND_MAX;
    // double nowy = nowNode.y + (((rand() << 1) - RAND_MAX) > 0 ? -1 : 1) * T * rand() * 1.0 / RAND_MAX;
    double nowx = nowNode.x + ((rand() << 1) - RAND_MAX) * T;
    double nowy = nowNode.y + ((rand() << 1) - RAND_MAX) * T;
    if(fabs(nowx) > 1000 || fabs(nowy) > 1000 || \
    nowx < MINX || nowx > MAXX || nowy < MINY || nowy > MAXY) {
      T *= gradient; 
      continue;
    }
    node tmpNode = {nowx, nowy};
    double tmpDelta = evaluation(tmpNode);
    double delta = tmpDelta - nowDelta;
    if(delta < 0) {
      nowNode = tmpNode;
      nowDelta = tmpDelta;
      ansNode = nowNode;
    } else if(exp(-delta / T) * RAND_MAX > 1.0 * rand()) nowNode = tmpNode, nowDelta = tmpDelta;
    T *= gradient;
  }
}
void solve() {
  srand(time(NULL));
  for (int i = 0; i < 3; i++) {
    cin >> p[i].x >> p[i].y >> p[i].r;
    nowNode.x += p[i].x / 3;
    nowNode.y += p[i].y / 3;
    MINX = min(MINX, p[i].x);
    MAXX = max(MAXX, p[i].x);
    MINY = min(MINY, p[i].y);
    MAXY = max(MAXY, p[i].y);
  }
  groop = nowNode;
  for(int i = 0; i < 300; i++) SA();
  if(evaluation(ansNode) < 1e-5) {
      printf("%.5lf %.5lf\n", \
      fabs(ansNode.x) < 1e-5 ? fabs(ansNode.x): ansNode.x, \
      fabs(ansNode.y) < 1e-5 ? fabs(ansNode.y): ansNode.y);
    }
}
int main() {
  solve();  
  return 0;
}
相关文章
|
机器学习/深度学习 算法 数据挖掘
马尔科夫链(Markov Chain, MC)算法详解及Python实现
马尔科夫链(Markov Chain, MC)算法详解及Python实现
7702 1
马尔科夫链(Markov Chain, MC)算法详解及Python实现
|
3月前
|
移动开发 算法 数据挖掘
【博士每天一篇文献-算法】Extending stability through hierarchical clusters in Echo State Networks
本文研究了在回声状态网络(ESN)中引入分层聚类结构对网络稳定性的影响,发现通过调整簇内和簇间的连接性及每个簇的主干单元数量,可以扩展谱半径的稳定范围,从而提高网络的稳定性和性能。
36 2
|
3月前
|
机器学习/深度学习 存储 算法
【博士每天一篇文献-算法】Memory augmented echo state network for time series prediction
本文介绍了一种记忆增强的回声状态网络(MA-ESN),它通过在储层中引入线性记忆模块和非线性映射模块来平衡ESN的记忆能力和非线性映射能力,提高了时间序列预测的性能,并在多个基准数据集上展示了其优越的记忆能力和预测精度。
28 3
【博士每天一篇文献-算法】Memory augmented echo state network for time series prediction
|
3月前
|
机器学习/深度学习 算法
【博士每天一篇文献-算法】Adult neurogenesis acts as a neural regularizer
本文研究了成人神经发生(adult neurogenesis)在大脑学习过程中的作用,发现其作为一种神经调节器能提高学习泛化能力,并通过在卷积神经网络(CNN)中模拟神经发生,证明了其作为正则化手段与传统技术一样有效,甚至在某些方面更优。
26 6
|
6月前
|
数据可视化
R语言马尔可夫链(MARKOV CHAIN, MC)模拟赌徒破产模型GAMBLER’S RUIN PROBLEM可视化
R语言马尔可夫链(MARKOV CHAIN, MC)模拟赌徒破产模型GAMBLER’S RUIN PROBLEM可视化
|
计算机视觉 Python
Ha-NeRF: Hallucinated Neural Radiance Fields in the Wild 代码复现与解读
Ha-NeRF: Hallucinated Neural Radiance Fields in the Wild 代码复现与解读
172 0
|
机器学习/深度学习 传感器 算法
基于Matlab实现CFAR算法(cfar_ac、cfar_go、cfar_so、cfar_os、cfar_tc)
基于Matlab实现CFAR算法(cfar_ac、cfar_go、cfar_so、cfar_os、cfar_tc)
|
存储 机器学习/深度学习 算法
Lec3 基于模型的 CF | 学习笔记
快速学习 Lec3 基于模型的 CF 。
Lec3 基于模型的 CF | 学习笔记
CF1567D. Expression Evaluation Error(思维 贪心)
CF1567D. Expression Evaluation Error(思维 贪心)
59 0
ICPC North Central NA Contest 2018 C . Rational Ratio(结论 模拟 gcd)
ICPC North Central NA Contest 2018 C . Rational Ratio(结论 模拟 gcd)
108 0