POJ 1379 Run away & POJ 2420 A star not a Tree [模拟退火] [爬山算法]
2016-10-07 00:24
471 查看
POJ 1379 Run Away
Time Limit: 3000MS Memory Limit: 65536KB 64bit IO Format: %lld & %llu
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
这个是爬山算法,而不是模拟退火!!
求一个点到其他说有点的最小距离最大,精度0.1
这个温度T是用在步长上的,而不是选取的概率。
那么显然每次就会越跳越小,逐渐接近最优解。一开始步长选择半对角线长,这样更精确且省时。
POJ 2420 A star not a Tree
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
用爬山算法是类似的一道题,这个要求费马点。。
和上一道题不一样,此题没有边界范围,所以要用最小的矩形框出一个范围。
此题采用矩形中rand点的方式,上一道题rand角度,当然rand角度也可以。。。
而模拟退火是要按照与温度有关的概率来接受劣点,这样的活可以有一定概率避免得到局部最优解。
这个方法是hzwer的,每次将当前点到n个点的位移加起来,这样相当于按照离散程度来rand,行之有效。
Time Limit: 3000MS Memory Limit: 65536KB 64bit IO Format: %lld & %llu
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
这个是爬山算法,而不是模拟退火!!
求一个点到其他说有点的最小距离最大,精度0.1
这个温度T是用在步长上的,而不是选取的概率。
那么显然每次就会越跳越小,逐渐接近最优解。一开始步长选择半对角线长,这样更精确且省时。
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<vector> #include<queue> #include<stack> #include<map> #include<set> #include<string> #include<iomanip> #include<ctime> #include<climits> #include<cctype> #include<algorithm> #ifdef WIN32 #define AUTO "%I64d" #else #define AUTO "%lld" #endif using namespace std; #define smax(x,tmp) x=max((x),(tmp)) #define smin(x,tmp) x=min((x),(tmp)) #define maxx(x1,x2,x3) max(max(x1,x2),x3) #define minn(x1,x2,x3) min(min(x1,x2),x3) int rnd(int l,int r) { return rand()%(r-l+1)+l; } const double PI = acos(-1.0); const int maxn = 1005; const double T_min = 1e-3; const double eps = 1e-7; const int P = 10000; const double R = 0.9; const int shift = 100; const int rp = 15; const int maxrp = rp + 5; double X,Y; struct Point { double x,y; Point(const int _x = 0,const int _y = 0) { x = _x; y = _y; } bool inside() { return x+eps>0.0 && x-eps<X && y+eps>0.0 && y-eps<Y; } }point[maxn],temp[maxrp]; double best[maxrp]; int n; inline void init() { scanf("%lf%lf%d",&X,&Y,&n); for(int i=1;i<=n;i++) { int x0,y0; scanf("%d%d",&x0,&y0); point[i].x=x0; point[i].y=y0; } } double dist(Point a,Point b) { double t1 = a.x - b.x; double t2 = a.y - b.y; return sqrt(t1*t1+t2*t2); } double calc(Point now) { double ret = 1e100; for(int i=1;i<=n;i++) smin(ret,dist(now,point[i])); return ret; } Point rand_start() { Point ret; ret.x = (double)rnd(0,P)/P*X; ret.y = (double)rnd(0,P)/P*Y; return ret; } Point rand_new(Point now,double T) { double angle = (double)rnd(0,P)/P*2.0*PI; now.x += T*cos(angle); now.y += T*sin(angle); return now; } void work() { temp[1]=Point(0.0,0.0); temp[2]=Point(0.0,Y); temp[3]=Point(X,0.0); temp[4]=Point(X,Y); for(int i=5;i<=rp;i++) temp[i]=rand_start(); for(int i=1;i<=rp;i++) best[i]=calc(temp[i]); double T = sqrt(X*X+Y*Y)/2.0; while(T>T_min) { for(int i=1;i<=rp;i++) { Point last = temp[i]; for(int j=1;j<=shift;j++) { Point now = rand_new(last,T); if(!now.inside()) continue; double tmp = calc(now); if(tmp > best[i]) { best[i] = tmp; temp[i] = now; } } } T *= R; } Point ans; double mx = 0.0; for(int i=1;i<=rp;i++) if(best[i]>mx) { ans = temp[i]; mx = best[i]; } printf("The safest point is (%.1lf, %.1lf).\n",ans.x,ans.y); } int main() { #ifndef ONLINE_JUDGE freopen("fire.in","r",stdin); freopen("fire.out","w",stdout); #endif srand((unsigned)time(NULL)); int cas; scanf("%d",&cas); while(cas--) { init(); work(); } return 0; }
POJ 2420 A star not a Tree
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
用爬山算法是类似的一道题,这个要求费马点。。
和上一道题不一样,此题没有边界范围,所以要用最小的矩形框出一个范围。
此题采用矩形中rand点的方式,上一道题rand角度,当然rand角度也可以。。。
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<vector> #include<queue> #include<stack> #include<map> #include<set> #include<string> #include<iomanip> #include<ctime> #include<climits> #include<cctype> #include<algorithm> #ifdef WIN32 #define AUTO "%I64d" #else #define AUTO "%lld" #endif using namespace std; #define smax(x,tmp) x=max((x),(tmp)) #define smin(x,tmp) x=min((x),(tmp)) #define maxx(x1,x2,x3) max(max(x1,x2),x3) #define minn(x1,x2,x3) min(min(x1,x2),x3) inline int rnd(int l,int r) { return rand()%(r-l+1)+l; } const double PI = acos(-1.0); const double eps = 1e-7; const int maxn = 105; const int P = 10000; const int shift = 100; const int rp = 15; const int maxrp = rp + 3; const double T_min = 0.1; const double R = 0.9; struct Point { double x,y; Point(const double _x = 0,const double _y = 0) { x=_x;y=_y; } }point[maxn],temp[maxn]; double best[maxn]; int n; double min_x,max_x,min_y,max_y; inline double dist(Point a,Point b) { double t1 = a.x - b.x; double t2 = a.y - b.y; return sqrt(t1*t1+t2*t2); } inline double calc(Point now) { double ret = 0.0; for(int i=1;i<=n;i++) ret += dist(now,point[i]); return ret; } void init() { min_x = 1e100 , min_y = 1e100; max_x = -1e100 , max_y = -1e100; scanf("%d",&n); for(int i=1;i<=n;i++) { int x,y; scanf("%d%d",&x,&y); point[i].x=(double)x; point[i].y=(double)y; smin(min_x,point[i].x); smax(max_x,point[i].x); smin(min_y,point[i].y); smax(max_y,point[i].y); } } Point rand_range(Point a,Point b) { double dx = b.x - a.x; double dy = b.y - a.y; dx *= (double)rnd(0,P)/P; dy *= (double)rnd(0,P)/P; return Point(a.x+dx,a.y+dy); } Point rand_angle(Point now,double T) { double angle = (double)rnd(0,P)/P*2.0*PI; now.x += T*cos(angle); now.y += T*sin(angle); return now; } void work() { temp[1]=Point(min_x,min_y); temp[2]=Point(max_x,min_y); temp[3]=Point(min_x,max_y); temp[4]=Point(max_x,max_y); temp[5]=Point((min_x+max_x)/2,(min_y+max_y)/2); for(int i=6;i<=rp;i++) temp[i]=rand_range(temp[1],temp[4]); for(int i=1;i<=rp;i++) best[i]=calc(temp[i]); double T = max(max_x-min_x,max_y-min_y); while(T > T_min) { for(int i=1;i<=rp;i++) { Point last = temp[i]; for(int j=1;j<=shift;j++) { Point now = rand_range(Point(last.x-T,last.y-T),Point(last.x+T,last.y+T)); //Point now = rand_angle(last,T); double tmp = calc(now); if(now.x<min_x-eps||now.x>max_x+eps||now.y<min_y-eps||now.y>max_y+eps) continue; if(tmp<best[i]) { best[i] = tmp; temp[i] = now; } } } T *= R; } double ans = 1e100; for(int i=1;i<=rp;i++) smin(ans,best[i]); printf("%.0lf",ans); } int main() { #ifndef ONLINE_JUDGE freopen("star.in","r",stdin); freopen("star.out","w",stdout); #endif srand((unsigned)time(NULL)); init(); work(); //cout<<endl<<(double)clock()/CLOCKS_PER_SEC<<endl; return 0; }
而模拟退火是要按照与温度有关的概率来接受劣点,这样的活可以有一定概率避免得到局部最优解。
这个方法是hzwer的,每次将当前点到n个点的位移加起来,这样相当于按照离散程度来rand,行之有效。
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<cmath> #include<vector> #include<queue> #include<stack> #include<map> #include<set> #include<string> #include<iomanip> #include<ctime> #include<climits> #include<cctype> #include<algorithm> #ifdef WIN32 #define AUTO "%I64d" #else #define AUTO "%lld" #endif using namespace std; #define smax(x,tmp) x=max((x),(tmp)) #define smin(x,tmp) x=min((x),(tmp)) #define maxx(x1,x2,x3) max(max(x1,x2),x3) #define minn(x1,x2,x3) min(min(x1,x2),x3) const int P = 10000; const int maxn = 105; const int rp = 10; const int maxrp = rp + 5; const double T_min = 0.1; const double R = 0.9; inline int rnd(int l,int r) { return rand()%(r-l+1)+l; } inline double rnd01() { return (double)rnd(0,P)/P; } struct Point { double x,y; Point(const double _x = 0,const double _y = 0) { x=_x; y=_y; } }point[maxn],temp[maxrp]; double best[maxrp]; int n; inline double dist(Point a,Point b) { double t1 = a.x - b.x; double t2 = a.y - b.y; return sqrt(t1*t1+t2*t2); } inline double calc(Point now) { double ret = 0.0; for(int i=1;i<=n;i++) ret += dist(now,point[i]); return ret; } double min_x,max_x,min_y,max_y; double xx,yy; void init() { scanf("%d",&n); for(int i=1;i<=n;i++) { double x,y; scanf("%lf%lf",&x,&y); xx += x; yy += y; smin(min_x,x); smax(max_x,x); smin(min_y,y); smax(max_y,y); point[i] = Point(x,y); } xx /= n; yy /= n; } Point rand_range(Point a,Point b) { double dx = b.x - a.x; double dy = b.y - a.y; dx *= rnd01(); dy *= rnd01(); return Point(a.x+dx,a.y+dy); } void work() { temp[1] = Point(min_x,max_x); temp[2] = Point(max_x,min_y); temp[3] = Point(min_x,max_y); temp[4] = Point(max_x,max_y); temp[5] = Point((min_x+max_x)/2,(min_y+max_y)/2); temp[6] = Point(xx,yy); for(int i=7;i<=rp;i++) temp[i] = rand_range(temp[1],temp[4]); for(int i=1;i<=rp;i++) best[i] = calc(temp[i]); double T = max(max_x-min_x,max_y-min_y); while(T > T_min) { for(int i=1;i<=rp;i++) { double sumx = 0.0 , sumy = 0.0; for(int j=1;j<=n;j++) { sumx += (point[j].x-temp[i].x)/dist(point[j],temp[i]); sumy += (point[j].y-temp[i].y)/dist(point[j],temp[i]); } Point now = Point(temp[i].x+sumx*T,temp[i].y+sumy*T); double tmp = calc(now); if(tmp <= best[i] || exp((best[i]-tmp)/T) > rnd01()) temp[i]=now,best[i]=tmp; } T *= R; } double ans = 1e100; for(int i=1;i<=rp;i++) smin(ans,best[i]); printf("%.0lf",ans); } int main() { #ifndef ONLINE_JUDGE freopen("star.in","r",stdin); freopen("star.out","w",stdout); #endif srand((unsigned)time(NULL)); init(); work(); //cout<<endl<<(double)clock()/CLOCKS_PER_SEC<<endl; return 0; }
相关文章推荐
- poj 2420 A Star not a Tree?(模拟退火求费马点)
- poj 2420 A Star not a Tree? [模拟退火]
- [模拟退火]POJ 2420——A Star not a Tree
- [poj 2420]A Star not a Tree?[模拟退火]
- poj2420 A Star not a Tree?【模拟退火】
- POJ 2420 A Star not a Tree? 费马点 计算几何 模拟退火
- POJ 2420 A Star not a Tree?(计算几何 多边形的费马点 模拟退火)
- poj 2420 A Star not a Tree?(模拟退火求费马点)
- poj 2420 A Star not a Tree? -- 模拟退火
- 【POJ】【P2420】【A Star not a Tree?】【题解】【模拟退火】
- POJ 2420 A Star not a Tree? 爬山算法
- 爬山算法 (poj 2420 A Star not a Tree?)
- poj2420 A Star not a Tree? 爬山算法
- poj 2420 A Star not a Tree?(贪心+求多边形费马点)
- POJ 2420 A Star not a Tree?
- poj 2420 A Star not a Tree?
- 【POJ】【2420】A Star not a Tree?
- [POJ 2420] A Star not a Tree?
- poj 2420 A Star not a Tree?
- POJ 2420 A Star not a Tree? (简单模拟退火)