在很多信息学竞赛选手看来,很多时候几何题目就是代码量大的代名词,即使对于一些经典问题,庞大的代码量也使很多人望而却步。模拟退火算法思维及编写简单、灵活,可以在一类最远、最近或第k近距离问题中发挥威力。
模拟退火算法介绍
1.1 模拟退火算法的原理
模拟退火算法是一种元启发式(Meta-Heuristics)算法,来源于固体退火原理,将固体加热至充分高的温度,再让其徐徐冷却。加热时,固体内部粒子随温升变为无序状,内能增大,而徐徐冷却时粒子渐趋有序,在每个温度都达到平衡态,最后在常温时达到基态,内能减为最小。根据Metropolis准则,粒子在温度T时趋于平衡的概率为 ,其中E为温度T时的内能,ΔE为其改变量,k为Boltzmann常数。
1.2 模拟退火算法的模型
① 初始化:初始温度T(充分大),初始解状态S(算法迭代的起点), 每次迭代次数L
② for k=1 to L 做③至⑥
③ 产生新解S’
④ 计算增量Δt′=C(S′)-C(S),其中C(S)为评价函数
⑤ 若Δt′<0则接受S’作为新的当前解,否则以概率 接受S’作为新的当前解
⑥ 如果满足终止条件则输出当前解作为最优解,结束程序
⑦ T逐渐减少,然后转②
POJ2420
A Star not a Tree?
Time Limit: 1000MS |
|
Memory Limit: 65536K |
Total Submissions: 1335 |
|
Accepted: 696 |
Description
Luke wants to upgrade his home computer network from 10mbs to 100mbs. His existing network uses 10base2 (coaxial) cables that allow you to connect any number of computers together in a linear arrangement. Luke is particulary proud that he solved a nasty NP-complete problem in order to minimize the total cable length.
Unfortunately, Luke cannot use his existing cabling. The 100mbs system uses 100baseT (twisted pair) cables. Each 100baseT cable connects only two devices: either two network cards or a network card and a hub. (A hub is an electronic device that interconnects several cables.) Luke has a choice: He can buy 2N-2 network cards and connect his N computers together by inserting one or more cards into each computer and connecting them all together. Or he can buy N network cards and a hub and connect each of his N computers to the hub. The first approach would require that Luke configure his operating system to forward network traffic. However, with the installation of Winux 2007.2, Luke discovered that network forwarding no longer worked. He couldn't figure out how to re-enable forwarding, and he had never heard of Prim or Kruskal, so he settled on the second approach: N network cards and a hub.
Luke lives in a loft and so is prepared to run the cables and place the hub anywhere. But he won't move his computers. He wants to minimize the total length of cable he must buy.
Input
The first line of input contains a positive integer N <= 100, the number of computers. N lines follow; each gives the (x,y) coordinates (in mm.) of a computer within the room. All coordinates are integers between 0 and 10,000.
Output
Output consists of one number, the total length of the cable segments, rounded to the nearest mm.
Sample Input
4
0 0
0 10000
10000 10000
10000 0
Sample Output
28284
Source
Waterloo Local 2002.01.26
求一点到多边形各顶点距离和的最小值(费马点)
#include<cstdio> #include<cmath> #define sqr(x) (x)*(x) int n,dir[4][2]={0,1,0,-1,1,0,-1,0}; struct point { double x,y; point() {x=y=0;} point(double a,double b) {x=a;y=b;} }p[105],tmp,ans; double dis(point a,point b) {return sqrt(sqr(a.x-b.x)+sqr(a.y-b.y));} double all_dis(point a) { double s=0; for(int i=0;i<n;i++) s+=dis(p[i],a); return s; } int main() { int i; scanf("%d",&n); for(i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); point st=p[0]; double step=1000,mid=all_dis(st),t; while(step>0.2) { int flag=1; while(flag) { flag=0; for(i=0;i<4;i++) { tmp=point(st.x+step*dir[i][0],st.y+step*dir[i][1]); t=all_dis(tmp); if(t<mid) { mid=t; flag=1; ans=tmp; } } st=ans; } step/=2.; } printf("%d/n",(int)(mid+0.5)*100/100); }
POJ1379
Run Away
Time Limit: 3000MS |
|
Memory Limit: 65536K |
Total Submissions: 2000 |
|
Accepted: 561 |
Description
One of the traps we will encounter in the Pyramid is located in the Large Room. A lot of small holes are drilled into the floor. They look completely harmless at the first sight. But when activated, they start to throw out very hot java, uh ... pardon, lava. Unfortunately, all known paths to the Center Room (where the Sarcophagus is) contain a trigger that activates the trap. The ACM were not able to avoid that. But they have carefully monitored the positions of all the holes. So it is important to find the place in the Large Room that has the maximal distance from all the holes. This place is the safest in the entire room and the archaeologist has to hide there.
Input
The input consists of T test cases. The number of them (T) is given on the first line of the input file. Each test case begins with a line containing three integers X, Y, M separated by space. The numbers satisfy conditions: 1 <= X,Y <=10000, 1 <= M <= 1000. The numbers X and Yindicate the dimensions of the Large Room which has a rectangular shape. The number M stands for the number of holes. Then exactly M lines follow, each containing two integer numbers Ui and Vi (0 <= Ui <= X, 0 <= Vi <= Y) indicating the coordinates of one hole. There may be several holes at the same position.
Output
Print exactly one line for each test case. The line should contain the sentence "The safest point is (P, Q)." where P and Qare the coordinates of the point in the room that has the maximum distance from the nearest hole, rounded to the nearest number with exactly one digit after the decimal point (0.05 rounds up to 0.1).
Sample Input
3
1000 50 1
10 10
100 100 4
10 10
10 90
90 10
90 90
3000 3000 4
1200 85
63 2500
2700 2650
2990 100
Sample Output
The safest point is (1000.0, 50.0).
The safest point is (50.0, 50.0).
The safest point is (1433.0, 1669.8).
Source
Central Europe 1999
#include<cstdio> #define sqr(x) (x)*(x) #define min(x,y) ((x)<(y)?(x):(y)) int n,dir[4][2]={0,1,0,-1,1,0,-1,0}; struct point { double x,y; point() {x=y=0;} point(double a,double b) {x=a;y=b;} }p[1005],ans,tmp,st; double dis(point a) { double s=1e9; for(int i=0;i<n;i++) s=min(s,sqr(a.x-p[i].x)+sqr(a.y-p[i].y)); return s; } int main() { int i,f; double x,y,xx,yy; scanf("%*d"); while(~scanf("%lf%lf%d",&x,&y,&n)) { double step=200,mid=0,t; for(i=0;i<n;i++) scanf("%lf%lf",&p[i].x,&p[i].y); st=p[0]; while(step>0.01) { f=1; while(f) { ans=st; for(f=0,i=0;i<4;i++) { xx=st.x+step*dir[i][0]; yy=st.y+step*dir[i][1]; if(xx<0||yy<0||xx>x||yy>y) continue; tmp=point(xx,yy); t=dis(tmp); if(t>mid) { mid=t; f=1; ans=tmp; } } st=ans; } step*=.8; } printf("The safest point is (%.1f, %.1f)./n",ans.x,ans.y); } }