模拟退火合集

poj2420 A Star not a Tree?

题意:给你n个点,求一个点到这n个点距离和最短的点。
思路:典型的费马点问题,点数比较少,可以用退火来做。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>

#define pi acos(-1)
#define maxn 11111
#define maxm 11111
#define INF 0x3F3F3F3F
#define eps 1e-8

#define pb push_back

#define mem(a) memset(a,0,sizeof a)

using namespace std;

/**lyc**/

#define T 100 ///初始温度
#define det 0.98 ///下降速度
int n;

int dx[5] = {0, 1, 0, -1, 0};
int dy[5] = {0, 0, 1, 0, -1};

struct Point {
    double x, y;
};
Point p[maxn];
double dis(Point A, Point B) {
    return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y));
}

double tot(Point A) {
    double ans = 0.0;
    for(int i = 1; i <= n; i++) {
        ans += dis(A, p[i]);
    }
    return ans;
}
double sov() {
    Point s = p[1];
    double t = T;
    double ans = INF;
    while(t > eps) {
        bool fa = 1;
        while(fa) {
            fa = 0;
            Point temp;
            for(int i = 1; i <= 4; i++) {
                temp.x = s.x + dx[i] * t;
                temp.y = s.y + dy[i] * t;
                double DIS = tot(temp);
            //     cout << "*****" << DIS << " " << ans <<endl;
                if(DIS < ans) {
                    s = temp;
                    ans = DIS;
                    fa = 1;
                }
            }
        }
        t *= det;
    }
    return ans;
}

int main() {
      //cout << INF << endl;
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%lf%lf", &p[i].x, &p[i].y);
    }
    double ans = sov();
    printf("%.0f\n", ans);
    return 0;
}

poj2069 Super Star

题意:给你n个点,求一个最小球能包含这n个点
思路:其实就是求一个定点,到n个点距离最大值最小。和上题差不多。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>

#define pi acos(-1)
#define maxn 11111
#define maxm 11111
#define INF 0x3F3F3F3F
#define eps 1e-8

#define pb push_back

#define mem(a) memset(a,0,sizeof a)

using namespace std;

/**lyc**/

#define T 10000 ///初始温度
#define det 0.99 ///下降速度
int n;

int dx[7] = {0, 1, 0, 0, -1, 0, 0};
int dy[7] = {0, 0, 1, 0, 0, -1, 0};
int dz[7] = {0, 0, 0, 1, 0, 0, -1};

struct Point {
    double x, y, z;
};
Point p[maxn];
double dis(Point A, Point B) {
    return sqrt((A.x - B.x) * (A.x - B.x) + (A.y - B.y) * (A.y - B.y) + (A.z - B.z) * (A.z - B.z));
}

double cal(Point A) {
    int k = 0;
    double vk = 0.0;
    for(int i = 1; i <= n; i++) {
        double DIS = dis(A, p[i]);
        if(DIS > vk) {
            k = i;
            vk = DIS;
        }
    }
    return vk;
}

double sov(void) {
    double ans = INF;
    double t = T;
    Point s = p[1];
    while(t > eps) {
        int k = 1;
        for(int i = 1; i <= n; i++) {
            if(dis(s, p[i]) > dis(s, p[k])) {
                k = i;
            }
        }
        double temp = dis(s, p[k]);
        s.x += (p[k].x - s.x) / temp * t;
        s.y += (p[k].y - s.y) / temp * t;
        s.z += (p[k].z - s.z) / temp * t;
        ans = min(temp, ans);
        t *= det;
    }
    return ans;
}

int main() {
    while(scanf("%d", &n) && n != 0) {
        for(int i = 1; i <= n; i++) {
            scanf("%lf%lf%lf", &p[i].x, &p[i].y,&p[i].z);
        }
        double ans = sov();
        printf("%.5f\n", ans);
    }
    return 0;
}

HDU2899 Strange fuction

题意:给你一个函数,求函数极值问题。
思路:典型的问题
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<time.h>

#define pi acos(-1)
#define maxn 11111
#define maxm 11111
#define INF 0x3F3F3F3F
#define eps 1e-8

#define pb push_back

#define mem(a) memset(a,0,sizeof a)

using namespace std;

/**lyc**/


#define T 100
#define det 0.98
double y;

bool pan(double temp) {
    if(temp >= 0.0 && temp <= 100.0) return 1;
    else return 0;
}
double getsum(double x) {
    return 6.0*x*x*x*x*x*x*x + 8.0*x*x*x*x*x*x + 7.0*x*x*x + 5.0*x*x - y*x;
}
double sov() {
    double t = T;
    double x = 0.0;
    double ans = getsum(x);
    while(t > eps) {
        //cout << x << " " << t << " " <<ans << endl;
        bool fa  = 1;
        while(fa) {
            fa = 0;
            double temp = x + t;
            if(pan(temp) && getsum(temp) < ans && fabs(ans - getsum(temp)) > eps ) {
                x = temp;
                ans = getsum(temp);
                fa = 1;
            }
            temp = x - t;
            if(pan(temp) && getsum(temp) < ans && fabs(ans - getsum(temp)) > eps ) {
                x = temp;
                ans = getsum(temp);
                fa = 1;
            }
        }
        t *= det;
    }
    return ans;
}
int main() {
    int kase;
    scanf("%d", &kase);
    while(kase--) {
        scanf("%lf", &y);
        printf("%.4f\n", sov());
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值