poj1379+POJ2420+hdu3932(最短距离+费马点+模拟淬火算法)
来源:互联网 发布:去世的著名网络作者 编辑:程序博客网 时间:2024/04/29 08:58
原创作品,出自 “晓风残月xj” 博客,欢迎转载,转载时请务必注明出处(http://blog.csdn.net/xiaofengcanyuexj)。
由于各种原因,可能存在诸多不足,欢迎斧正!
Description
Input
Output
Sample Input
31000 50 110 10100 100 410 1010 9090 1090 903000 3000 41200 8563 25002700 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
题解:
昨天在网上浏览博客,无意看见有个ACMer交了这题并注明模拟淬火算法,由于在人工智能课上老师提到过这类演化算法-模拟淬火算法。感慨ACM在线OJ还能用模拟淬火算法这类概率算法,于是眼前一亮,有登上好久没有刷题的POJ了,看了道题。
题意是要求到给定n个点的最小距离最大的点,且点限定在给定矩形内。要是一维的,直接三分找极值即可;在平面上就不太好处理了。且这样的点可能不只一个,到底取谁都要考虑。前人提供了模拟淬火算法,直接搞定了。大致步骤如下:
1、随机选取一个合适的控制条件T作为开始
2、随机选取P个起始点,作为可行解
3、分别依据内能更新这P个可行解
4、减小控制条件T,直到终止条件
下面是代码:
#include<iostream>#include<cmath>#include<ctime>#include<cstdio>using namespace std;const int MAXN=1000+100;const int KMEAN=30;const double INF=1<<30;const double eps=1e-8;const double PI=3.141592653;int x,y,n;struct Point{double x,y;}myPoint[MAXN],myK[KMEAN];double dis[KMEAN];double GetMinDis(double tx,double ty){double minDis=INF,temp;for(int i=0;i<n;i++){ temp=sqrt((tx-myPoint[i].x)*(tx-myPoint[i].x)+(ty-myPoint[i].y)*(ty-myPoint[i].y));if(temp<minDis) minDis=temp;}return minDis;}int main(){int cas,i,j;double temp;scanf("%d",&cas);while(cas--){scanf("%d%d%d",&x,&y,&n);srand((unsigned)time(NULL));for(i=0;i<n;i++)scanf("%lf%lf",&myPoint[i].x,&myPoint[i].y);for(i=0;i<KMEAN;i++){dis[i]=INF;myK[i].x=rand()%10001/10000.0*x;myK[i].y=rand()%10001/10000.0*y;}for(i=0;i<KMEAN;i++) dis[i]=GetMinDis(myK[i].x,myK[i].y);double theta,delta=1.0*(x>y?x:y)/sqrt(1.0*n);while(delta>eps){for(i=0;i<KMEAN;i++){double nx=myK[i].x,ny=myK[i].y;for(j=0;j<KMEAN;j++){double tx,ty;theta=double(rand()%10001)/10000.0*2*PI; tx=nx+delta*cos(theta);ty=ny+delta*sin(theta);if(tx<0||tx>x||ty<0||ty>y)continue;temp=GetMinDis(tx,ty);if(temp>dis[i]){myK[i].x=tx;myK[i].y=ty;dis[i]=temp;}}}delta=0.8*delta;}int id=-1;temp=-INF;for(i=0;i<KMEAN;i++){if(dis[i]>temp){temp=dis[i];id=i;}}printf("The safest point is (%.1lf, %.1lf).\n",myK[id].x,myK[id].y); }return 0;}
下面是相似的题
Description
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
Output
Sample Input
40 00 1000010000 1000010000 0
Sample Output
28284
题解:
本题与上面那题的唯一区别就是目的函数不同,此处为最短距离和,上面为最短距离的最大者,模拟淬火算法。直接贴代码的。
#include<iostream>#include<cmath>#include<ctime>#include<cstdio>using namespace std;const int MAXN=100+10;const int KMEAN=30;const double INF=1<<30;const double eps=1e-8;const double PI=3.141592653;double x=10000.0,y=10000.0;int n;struct Point{double x,y;}myPoint[MAXN],myK[KMEAN];double dis[KMEAN];double GetMinDis(double tx,double ty){double temp=0;for(int i=0;i<n;i++){ temp+=sqrt((tx-myPoint[i].x)*(tx-myPoint[i].x)+(ty-myPoint[i].y)*(ty-myPoint[i].y));}return temp;}int main(){int i,j;double temp;while(scanf("%d",&n)!=EOF){srand((unsigned)time(NULL));for(i=0;i<n;i++)scanf("%lf%lf",&myPoint[i].x,&myPoint[i].y);for(i=0;i<KMEAN;i++){dis[i]=INF;myK[i].x=rand()%10001/10000.0*x;myK[i].y=rand()%10001/10000.0*y;}for(i=0;i<KMEAN;i++) dis[i]=GetMinDis(myK[i].x,myK[i].y);double theta,delta=10000.0/sqrt(1.0*n);while(delta>eps){for(i=0;i<KMEAN;i++){double nx=myK[i].x,ny=myK[i].y;for(j=0;j<KMEAN;j++){double tx,ty;theta=double(rand()%10001)/10000.0*2*PI; tx=nx+delta*cos(theta);//可改变方向ty=ny+delta*sin(theta);temp=GetMinDis(tx,ty);if(temp<dis[i]){myK[i].x=tx;myK[i].y=ty;dis[i]=temp;}}}delta=0.98*delta;}temp=INF;for(i=0;i<KMEAN;i++){if(dis[i]<temp){temp=dis[i];}}printf("%.0lf\n",temp); }return 0;}
下面这题是求最小圆覆盖。
Groundhog Build Home
Time Limit: 15000/5000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 1397 Accepted Submission(s): 625
1000 50 110 101000 50 40 01 00 11 1
(10.0,10.0).0.0(0.5,0.5).0.7
题解:
题意是要求到给定n个点的最大距离最小的点,且点限定在给定矩形内,对应数学模型最小点覆盖。贴段代码:
#include<iostream>#include<cmath>#include<ctime>#include<cstdio>using namespace std;const int MAXN=1000+100;const int KMEAN=30;const double INF=1<<30;const double eps=1e-8;const double PI=3.141592653;int x,y,n;struct Point{double x,y;}myPoint[MAXN],myK[KMEAN];double dis[KMEAN];double GetMaxDis(double tx,double ty){double maxDis=-INF,temp;for(int i=0;i<n;i++){ temp=sqrt((tx-myPoint[i].x)*(tx-myPoint[i].x)+(ty-myPoint[i].y)*(ty-myPoint[i].y));if(temp>maxDis) maxDis=temp;}return maxDis;}int main(){int i,j;double temp;while(scanf("%d%d%d",&x,&y,&n)!=EOF){srand((unsigned)time(NULL));for(i=0;i<n;i++)scanf("%lf%lf",&myPoint[i].x,&myPoint[i].y);for(i=0;i<KMEAN;i++){dis[i]=INF;myK[i].x=rand()%10001/10000.0*x;myK[i].y=rand()%10001/10000.0*y;}for(i=0;i<KMEAN;i++) dis[i]=GetMaxDis(myK[i].x,myK[i].y);double theta,delta=1.0*(x>y?x:y)/sqrt(1.0*n);while(delta>eps){for(i=0;i<KMEAN;i++){double nx=myK[i].x,ny=myK[i].y;for(j=0;j<KMEAN;j++){double tx,ty;theta=double(rand()%10001)/10000.0*2*PI; tx=nx+delta*cos(theta);ty=ny+delta*sin(theta);if(tx<0||tx>x||ty<0||ty>y)continue;temp=GetMaxDis(tx,ty);if(temp<dis[i]){myK[i].x=tx;myK[i].y=ty;dis[i]=temp;}}}delta=0.8*delta;}int id=-1;temp=INF;for(i=0;i<KMEAN;i++){if(dis[i]<temp){temp=dis[i];id=i;}}printf("(%.1lf,%.1lf).\n%.1lf\n",myK[id].x,myK[id].y,temp); }return 0;}
- poj1379+POJ2420+hdu3932(最短距离+费马点+模拟淬火算法)
- poj2069+hud3007(点的最小球(圆)覆盖+模拟淬火算法)
- 模拟退火算法(run away poj1379)
- hdu3932 最小圆覆盖-模拟退火实现-3+
- 素数最短距离算法
- 最短距离算法
- Dijkstra算法(最短距离)
- 模拟退火 hdu3932
- POJ2420 费马点问题求解 随机化 模拟退火
- poj1379 模拟退火
- 模拟退火算法A Star not a Tree?(poj2420)
- 迪杰斯特拉算法求最短距离
- Dijkstra算法求最短距离
- 最短距离 dijkstra floyd 算法
- Floyd-Warshall算法(最短距离)
- POJ2420模拟退火
- poj2420(模拟退火)
- poj2420 模拟退火
- Message broker课程讲解大纲
- 手机通讯录数据丢失怎么恢复
- 深入理解 Cocos2d-x 内存管理
- 黑马程序员------------web(第二天)
- cocos2d-x 3.0 基本概念 定时器Scheduler and Timer
- poj1379+POJ2420+hdu3932(最短距离+费马点+模拟淬火算法)
- POJ 1077 Eight(BFS:输出路径)
- SlidingMenu 左侧滑动菜单
- 淘宝前端设计
- netlink编程小例子
- 【scala系列4】使用富包装器或隐含类类型为值类添加函数
- PAT A 1030. Travel Plan (30)
- 将pvr.ccz 和 plist 文件转成 小图 python
- PacketReader 如何实现smack数据监听机制和packet分发机制