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 }