模拟退火

来源:互联网 发布:python tile 编辑:程序博客网 时间:2024/06/10 03:44

题目描述:平面上给你n个点,让你求一个点,到这n点的距离和最小。

解题报告:

先写好一个判定函数double judge(pint id),表示id这个点的权值,这里的话,权值就是id到其他所有点的距离和。

随即在给定的范围内生成NUM个点,挑选一个最大的步长T(要求答案点距离随即生成的点小于T)。

下面就开始循环了:

1:对于每一个T,扫描第i个随即生成的点。

2:以这个点为中心,上下左右为T的方框内,随机生成TIM个点(模拟这个点偏移T的距离)。

3:把i点更新为这TIM点中权值最优的。

4:T *= deta,缩小,如果小于给定的MIN跳出,否则继续从1开始。

5:最后从NUM点中选取最优的即可。

代码如下:

#include<iostream>

#include<cstring>

#include<vector>

#include<algorithm>

#include<cmath>

#include<cstdio>

using namespace std;

#define NUM 20 //随机生成点的个数

#define TIM 20 //每个点移动的次数

#define RD 1000 //随即乘生成0~1的,精度为1/RD的小数

#define MIN 0.1 //步长T的最小值,比最后坐标要求的精度小一些

#define deta 0.7 //每次循环步长T的缩小程度

int n; //总点数,复杂度X * NUM * TIM * n; X为T到MIN的循环次数,由deta决定

struct pint

{

double x, y, val;

pint(){}

pint(double x, double y):x(x),y(y){}

}jeo[200], tar[NUM];

double dist(pint a, pint b)

{return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));}

//判定函数

double judge(pint id)

{

double sum = 0;

for(int i = 0; i < n; i++)

sum += dist(id, jeo[i]);

return sum;

}

//获取0~1的小数

double GetDouble()

{return (rand() % (RD + 1)) * 1.0 / RD;}

//获取左下角为a,右上角为b内的随机点

pint GetRand(pint a, pint b)

{

pint tar = pint(a.x + (b.x - a.x) * GetDouble(), a.y + (b.y - a.y) * GetDouble());

tar.val = judge(tar);

return tar;

}

//模拟退火主过程 //MAXT为步长

void jeogia(double MaxT)

{

for(double T = MaxT; T >= MIN; T *= deta)

for(int i = 0; i < NUM; i++) for(int j = 0; j < TIM; j++)

{

pint tmp = GetRand(pint(tar[i].x - T, tar[i].y - T), pint(tar[i].x + T, tar[i].y + T));

if (tmp.val < tar[i].val) tar[i] = tmp;

}

}

int main()

{

while(scanf("%d", &n) != EOF)

{

pint a = pint(100000, 100000), b = pint(-100000, -100000);

for(int i = 0; i < n; i++)

{

scanf("%lf%lf", &jeo[i].x, &jeo[i].y);

a.x = min(a.x, jeo[i].x); a.y = min(a.y, jeo[i].y);

b.x = max(b.x, jeo[i].x); b.y = max(b.y, jeo[i].y);

}

//随机生成NUM个点

for(int i = 0; i < NUM; i++) tar[i] = GetRand(a, b);

//传入步长

jeogia(max(b.y - a.y, b.x - a.x));

double ans = -1;

for(int i = 0; i < NUM; i++)

if (ans < 0 || tar[i].val < ans)

ans = tar[i].val;

printf("%.0f\n", ans);

}

return 0;

}

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 金立手机黑屏了怎么办 金立手机死机了怎么办 促卵泡生成素偏高怎么办 促卵泡成熟素偏高怎么办 促卵泡生成素100怎么办 路虎冷却液过低怎么办 强制险过期4个月怎么办 摩托车5年没年检怎么办 大事故定损不够怎么办 125摩托钥匙丢了怎么办 刺猬上的蜱虫怎么办 被宠物貂咬了怎么办 狗狗细小后咳嗽怎么办 十字绣丝线太滑怎么办 地垫与地面打滑怎么办 强电和水管交叉怎么办 小丫一个黄大怎么办 用友加密狗丢了怎么办 吸费软件扣费怎么办 我接了95515电话怎么办 硬盘没有4k对齐怎么办 梦幻西游鬼区了怎么办 移动4g信号不好怎么办 手机4g信号不好怎么办 家里4g信号不好怎么办 小孩流鼻涕怎么办最简单方法 猫鼻子摔出血了怎么办 让野猫挠出血了怎么办 家养猫咬出血了怎么办 被小猫抓出血了怎么办 猫咪指甲剪多了怎么办 猫咪指甲剪很了怎么办 家里的公猫老叫怎么办 猫生小猫没有奶怎么办 小孩凉了胃呕吐怎么办 母猫配种不配合怎么办 狗狗肚子有硬块怎么办 狗狗身上有硬块怎么办 小猫和大猫打架怎么办 大猫对小猫哈气怎么办 刨宫产后恶露少怎么办