Simulated Annealing - real joy (despair

A few days ago a whim, itTake advantage of language classesEngage in a task list (Gan! Not because I can not find "Los Super Goo task list" $ js $ script $ lin $ _ $ toto $ of the) brain and then a sauce, put the simulated annealing Gonggongzhengzheng write up, and science for a long time saw a lot of foreign video can understand, I'm so south of.

A small topic

FIG: YES \ (n-\) on a weight, each weight based on a long enough rope. Each rope from top to bottom through the hole on the desktop, and then tied together. Figure \ (X \) is common at the knot. Assuming that the rope is perfectly elastic (will not cause energy loss), the table is high enough (and therefore the weight is not down to the ground), and ignore all friction.

X asked knot in the final equilibrium where.

Note: The hole on the desktop than the knot \ (X \) is much smaller, so even a particularly heavy weight, knot \ (X \) can not fall through the hole on the desktop to, at most card in a hole at.

Input Format

The first line of a file positive integer \ (the n-\) \ ((1≤n≤1000) \) , representing the number of weights and holes. The next \ (n-\) lines, each line is an integer of 3: \ (Xi.Yi.Wi \) , represent the coordinates of the i-th and the first hole \ (i \) by weight of a heavy object. $ (- 10000≤x, y≤10000, 0 <w≤1000) $

Output Format

Your program must output two floating-point (after three decimal places), respectively, when the abscissa and the ordinate in the final equilibrium state of X knots. Two numbers separated by a space.

What simulated annealing ah

Facts have proved that see Baidu Encyclopedia will look silly, \ (OI \) annealing and thermal motion of molecules does not matter much.

Think small

We know the coordinates of a number of cities across the country, seeking a route from Beijing makes a path through all the cities and the shortest way to go only once every

This question is if the direct exposure of search words ......
if there are 25 cities, and you \ (PC \) stronger than one second 1e8 times operations, Ning was workin 'count about 4.9 billion years , it frightening
but with simulated annealing, can quickly calculate the answer.

Simulated annealing is used to seek multimodal function of the extreme value of (although usually not reflected multimodal function will need rather they want), set the appropriate parameters can be obtained at a faster rate in the approximate optimal solution , so that the algorithm is not necessarily a perfect score, but you can easily get a high score.

In order to do this the top title of personal experience to explain

(

Let me talk about a few concepts

\ (T \) : initial temperature, is a look at their own feelings and topics set amount, the greater the number, the higher the positive solution of probability, but the longer the time-consuming.

\ (Down \) : the purpose of cooling coefficient, this coefficient is set so that \ (T \) can be reduced to an appropriate speed, so that when \ (T \) when reaching the border we have tried plenty of solutions to the final solution close to the optimum solution. Exponential growth rate is extremely fast, so we can give \ (down \) attached to a small value, usually \ (0.98 - 0.995 \)
messing around, where appropriate, between the more about not accurate, but faster.

\(exp( n )\) :c++一个函数,计算\(e ^ n\),其中\(e\)为自然对数。

\(de\) : 这次得到的解和之前求到的最优解的差值,有点类似于化学里的熵变,用来评价这次的解是否更优。

\(RAND\)_ \(MAX\) (这个为什么这么大):c++能生成的最大的随机数,即32767。

\(rand()\) :c++函数,生成随机数。

怎么退火呢?

举个烂大街的栗子:

贪心算法:兔子朝着比现在高的地方跳去。它找到了不远处的最高山峰。但是这座山不一定是珠穆朗玛峰。这就是贪心,它不能保证局部最优值就是全局最优值。

模拟退火:兔子喝醉了。它随机地跳了很长时间。这期间,它可能走向高处,也可能踏入平地。但是,它渐渐清醒了并朝最高方向跳去。这就是模拟退火。

一张图骗:

可以看到它是逐渐趋近于最优解的

本题为例的伪代码:

int T = 233;
int tempx, tempy, tempans, de;
//下面的x, y, ans为临时最优解
while( T > 1e-15 ){  //T十分接近零
    tempx = x + (rand() * 2 - RAND_MAX) * T;
    tempy = y + (rand() * 2 - RAND_MAX) * T;
    //以本题为例,rand() * 2 - RAND_MAX是一个小套路,这样可以生成从 -32767 到 32767 的随机数,以让坐标点转移到一个随机位置,随着不断降温,T会越来越小,所以坐标点转移的范围也会越来越小,逐渐逼近最优点
    tempans = solve( tempx, tempy )
    //solve是你用来求距离的函数
    de = tempans - ans;
    if( de < 0 ){//是大于还是小于具体问题判断   
        x = tempx;
        y = tempy;
        w = tempw;
    } else if( exp( -de / T ) * RAND_MAX > rand() ){//以一个概率选择是否接受,但是就算是接受,我们也不会用它来更新最优解,因为我们当前的最优解比它优秀。de的正负性具体题目具体分析,也可以两个都试一下,看哪个输出正确样例   
        x = tempx;
        y = tempy;  
    }
    T *= down;//降温
}

题目分析

我最开始想的是受力分析然后搞个合力,最后物体在合力方向上移动,但是一想,合力方向似乎会变,然后就没想法了(俺太弱了\(QWQ\)
看讨论区有人说用质心公式搞???我不太懂,没搞。
最后用模拟退火瞎搞出来的,看题解还有大佬用凸包什么的搞出来了,反正我不会。

然后就模拟退火搞呗,考虑到重力势能是趋近于系统重力势能最小的,所以当绳子的结点静止时,重力势能之和最小,那么我们可以求出在每个点时的重力势能大小,以此来比较当前解和最优解。

AC代码:

#include<bits/stdc++.h>
using namespace std;
#define rint register int
#define down //请自己尝试

int de;
int n;
double ansx, ansy, answ;
struct node{
    int x, y, w;
}a[1050];

inline int read( void ){
    int re = 0, f = 1;
    char ch = getchar();
    while( ch > '9' || ch < '0' ){
        if( ch == '-' ) f = -1;
        ch = getchar();
    }
    while( ch >= '0' && ch <= '9' ){
        re = re * 10 + ch - '0';
        ch = getchar();
    }
    return re * f;
}
inline double init( double x, double y ){
    double re = 0.0, d1, d2;
    for( rint i = 1; i <= n; i++ ){
        d1 = x - a[i].x, d2 = y - a[i].y;
        re += sqrt( d1 * d1 + d2 * d2 ) * a[i].w;
    }
    return re;
}
inline void SA(){
    double T = //请自己尝试
    double de, tw, tx, ty;
    while( T > 1e-15 ){
        //cout << T << endl;
        tx = ansx + ( rand() * 2 - RAND_MAX ) * T;
        ty = ansy + ( rand() * 2 - RAND_MAX ) * T;
        tw = init( tx, ty );
        de = tw - answ;
        if( de < 0 ){
            ansx = tx;
            ansy = ty;
            answ = tw;
        } else if( exp( -de / T ) * RAND_MAX > rand() ){    
            ansx = tx;
            ansy = ty;  
        }
        T *= down;
    }
}
int main( void ){
    n = read();
    for( rint i = 1; i <= n; i++ ){
        a[i].x = read(); a[i].y = read(); a[i].w = read();
        ansx += a[i].x, ansy += a[i].y;
    }
    ansx /= n, ansy /= n;
    answ = init( ansx, ansy );
    //cout << ansx << ' ' << ansy;
    SA();
    SA();
    SA();
    SA();
    SA();
    printf( "%.3lf %.3lf", ansx, ansy );
    return 0;
}

Guess you like

Origin www.cnblogs.com/with6676/p/11695978.html