USACO 5.2 Electric Fences(模拟退火)

学习模拟退火,讲解看这里:http://www.cnblogs.com/heaad/archive/2010/12/20/1911614.html

代码看的山大一个大神的博客:http://3214668848.blog.163.com/blog/static/48764919200991894621558/

代码里就一个随机数,实现模拟退火算法的代码,比较好懂的。。。

 1 /*
 2  ID: cuizhe
 3  LANG: C++
 4  TASK: fence3
 5 */
 6 #include <iostream>
 7 #include <cstdio>
 8 #include <cstring>
 9 #include <queue>
10 #include <map>
11 #include <ctime>
12 #include <cmath>
13 #include <algorithm>
14 using namespace std;
15 struct node
16 {
17     int x1,y1,x2,y2;
18 }p[151];
19 int a[4] = {0,0,1,-1};
20 int b[4] = {1,-1,0,0};
21 int n;
22 double dis(int x1,int y1,int x2,int y2)
23 {
24     return sqrt((x2-x1)*(x2-x1) + (y2-y1)*(y2-y1));
25 }
26 double Cal(int x,int y)
27 {
28     int i;
29     double ans,temp;
30     ans = 0;
31     for(i = 1;i <= n;i ++)
32     {
33         if(p[i].x1 == p[i].x2&&y >= p[i].y1&&y <= p[i].y2)//点到线段中间的点最短的情况
34         temp = fabs(x-p[i].x1);
35         else if(p[i].y1 == p[i].y2&&x >= p[i].x1&&x <= p[i].x2)//点到线段中间的点最短的情况
36         temp = fabs(y-p[i].y1);
37         else
38         temp = min(dis(x,y,p[i].x1,p[i].y1),dis(x,y,p[i].x2,p[i].y2));//点到线段端点
39         ans += temp;
40     }
41     return ans;
42 }
43 int main()
44 {
45     int i,j,T,num,key,tx,ty,u,x,y;
46     double ans,di;
47     freopen("fence3.in","r",stdin);
48     freopen("fence3.out","w",stdout);
49     scanf("%d",&n);
50     srand(time(NULL));
51 
52     for(i = 1;i <= n;i ++)
53     {
54         scanf("%d%d%d%d",&p[i].x1,&p[i].y1,&p[i].x2,&p[i].y2);
55         if(p[i].x1==p[i].x2 && p[i].y1 > p[i].y2)  swap(p[i].y1, p[i].y2);
56         if(p[i].y1==p[i].y2 && p[i].x1 > p[i].x2)  swap(p[i].x1, p[i].x2);
57         p[i].x1 *= 10;
58         p[i].y1 *= 10;
59         p[i].x2 *= 10;
60         p[i].y2 *= 10;
61     }
62     Cal(0,0);
63     T = 40;
64     num = 200;
65     key = 5;
66     ans = 10000000;
67     x = p[1].x1;
68     y = p[1].y1;
69     while(T--)
70     {
71         for(i = 1;i <= num;i ++)
72         {
73             for(j = 0;j < 4;j ++)
74             {
75                 u = rand()%key;
76                 tx = x + u*a[j]*T;//随机跳跃
77                 ty = y + u*b[j]*T;//随机跳跃
78                 if(tx >= 0&&ty >= 0&&tx <= 1000&&ty <= 1000)
79                 {
80                     di = Cal(tx,ty);
81                     if(ans > di)
82                     {
83                         ans = di;
84                         x = tx;
85                         y = ty;
86                     }
87 
88                 }
89             }
90         }
91     }
92     printf("%.1lf %.1lf %.1lf\n",x/10.0,y/10.0,ans/10.0);
93     return 0;
94 }

 



posted @ 2013-05-22 10:48  Naix_x  阅读(200)  评论(0编辑  收藏  举报