您的位置:首页 > 其它

hdoj 1109 粒子群优化算法(PSO)

2015-10-02 18:50 429 查看
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=1109

大意是在一个平面内有很多点,我们要在平面内找到一个点,使得这个点与其他点之间的最短距离最大。

看到别人都是用的模拟退火或者是爬山法,感觉模拟退火与粒子群优化算法相比更容易陷入局部最优,所以还是用PSO算法比较心安。

利用粒子群优化算法,设置了20个粒子和100代即可AC。代码如下:

#include <iostream>
#include <ctime>
#include <iomanip>
#include <cmath>
using namespace std;
#define num_parcle 20
double w = 0.8;
int n;
int gen = 100;
struct parcle
{
double x, y;
double dis;
double vx,vy;
};
struct point
{
double x,y;
};
template <class X ,class Y>
double distance(X& p,Y& q)
{
return sqrt((p.x-q.x)*(p.x-q.x)+(p.y-q.y)*(p.y-q.y));
}
point point_list[1000];
parcle now[num_parcle+1];
parcle last[num_parcle+1];
parcle history[num_parcle+1];
int max_x,max_y;
double valuate(parcle& cv)
{
if(cv.x<0||cv.y<0||cv.x>max_x||cv.y>max_y){
return 0;
}
double dis = distance(cv,point_list[0]);
double temp;
for(int i(1);i<n;i++)
{
temp = distance(cv,point_list[i]);
if(temp<dis)
dis = temp;
}
return dis;
}
void initi()
{
now[0].dis = 0;
for(int i(1);i<=num_parcle;i++)
{
history[i].x=now[i].x = rand()%10000/10000.0*max_x;
history[i].y=now[i].y = rand()%10000/10000.0*max_y;
history[i].dis=now[i].dis = valuate(now[i]);
history[i].vx = now[i].vx = rand()%10000/10000.0*max_y*0.3;
history[i].vy = now[i].vy = rand()%10000/10000.0*max_x*0.3;
if(now[i].dis > now[0].dis)
now[0]=now[i];
}
}
void update()
{
double temp;
for(int i(1);i<=num_parcle;i++)
{
now[i].x = now[i].x+now[i].vx;
now[i].y = now[i].y+now[i].vy;
temp = valuate(now[i]);
now[i].dis = temp;
if(temp>history[i].dis)
{
history[i].dis = temp;
history[i].x = now[i].x;
history[i].y = now[i].y;
}
if(temp>now[0].dis)
{
now[0].dis = temp;
now[0].x = now[i].x;
now[0].y = now[i].y;
}
now[i].vx = w*now[i].vx + 2*rand()%1000/1000.0*(now[0].x-now[i].x)+2*rand()%1000/1000.0*(history[i].x-now[i].x);
now[i].vy = w*now[i].vy + 2*rand()%1000/1000.0*(now[0].y-now[i].y)+2*rand()%1000/1000.0*(history[i].y-now[i].y);
}
}
int main()
{
int t;
cin >> t;
srand(time(NULL));
while(t--)
{
cin >> max_x>>max_y;
cin >> n;
for(int i(0);i<n;i++)
{
cin >> point_list[i].x>>point_list[i].y;
}
initi();
w = 0.8;
for(int j(0);j<gen;j++)
{
w = 0.2+0.6*(gen-j)/gen;
update();
}
cout << "The safest point is ("<<setprecision(1)<<fixed<<now[0].x<<", "<<setprecision(1)<<fixed<<now[0].y<<")."<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息