[HAOI2006] average data simulated annealing

Simulated Annealing series

example 1 [HAOI2006] average data 

https://www.luogu.org/problem/P2503

[Title] Italy

  The number n is divided into m groups, which calculates the variance of the number of each group and m, seeking obtained. Since the points system is arbitrary, we require a minimum variance in these

[Thinking]

  Firstly, given a sequence of calculating the current state is the minimum variance, in accordance with the order of addition, the number of each of a set of minimum and added, and finally calculate the variance.

So the answer is to change to change the order of the sequence. Here I used one of the two numbers are exchanged, if the answer smaller updates, otherwise there is a certain probability reservations, go back and change certain probability

[Code]

#include<cmath>
#include<ctime>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define pf(x) ((x)*(x))
using namespace std;
typedef double real;
const int N=30;
real avg,now,best,sum,a[N],num[N],no[N],be[N];
int n,m;
inline real deal(){
    real fz=0;
    memset(num,0,sizeof num);
    for(int i=1,p=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            if(num[j]<num[p]) p=j;
        }
        num[p]+=no[i];
    }
    for(int i=1;i<=m;i++) fz+=pf(num[i]-avg);
    return sqrt(real(fz)/real(m));

}
int main(){
    srand(time(0));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++) scanf("%lf",a+i),no[i]=be[i]=a[i],sum+=a[i];
    avg=real(sum)/real(m);
    best=deal();
    for(int it=30;it--;){
        now=best;
        for(int i=1;i<=n;i++) no[i]=be[i];
        for(real T=1e5;T>=1e-14;T*=0.97){
            int x=rand()%n+1,y=rand()%n+1;
            for(;x==y;y=rand()%n+1);
            swap(no[x],no[y]);
            real tmp=deal(),E=tmp-now;
            if(tmp<best){
                best=tmp;
                for(int j=1;j<=n;j++) be[j]=no[j];
            }
            if(tmp<now||E/T<real(rand())/real(RAND_MAX))
                now=tmp;
            else 
                swap(no[x],no[y]);
        }
    }
    printf("%.2lf",best);
    return 0;
}

 

 

Classical simulated annealing

Simulated Annealing idea is that if a move would make the answer to become better , we will accept this move; otherwise we certain probability to accept the move.

Sounds metaphysics. According to the set of theoretical physics, we define two things:
- temperature $ (T) $. It gradually decreases with the passage of time.
- Incremental $ (E) $. It describes the benefits of moving once obtained. To move from $ $ $ X X 'as defined increments $ $ f (x') - f (x) $, the greater the increment, '$ X $ move towards greater advantage.

In simulated annealing, if the delta is greater than $ 0 $, then directly accept this move; otherwise accepted by the probability of the following movement:

$$P = \exp(\frac{E}{T})$$

It sounds very metaphysical. However, it was able to obtain accuracy better solution. Pseudo-code as follows:

T = 100.0 ;                // initial temperature 

for ( int  I = 0 ; I < 100 ; I ++ )       // iterations control 
{ 
    the tar = getPos ();            // x is selected from a point around the 
    E = F ( the tar ) - F ( X ); 

    IF ( E  >  EPS )  X = the tar ;       // move directly 
    the else  IF ( exp ( E / T ) >  Random ( 0 , . 1 ))  X = the tar ;      // receiving mobile 

    T = T * 0.99 ;                // cool 
}

Guess you like

Origin www.cnblogs.com/shenben/p/11332985.html