粒子群优化(微粒群算法)

迭代公式

\[v_i = v_i * w + c * rand() * (pbest_i + gbest - 2 x_i) \]

其中:

\(v_i\) 是速度

\(w\) 是惯性因子 \(w \in [0, 1]\),和学习因子相反,就是该粒子原来的速度的 参考权重 。比如这个程序里取的是 \(0.5\),而据说从大到小衰减会更好。因为大的时候会重视每个个体的价值,可以更全面的寻找可行解,而越趋于 \(0\) 就越注重社会的价值就是所有粒子中的最优解。

\(C\) 是学习因子也就是权重一般取 \(2\)

我们可以通过这个速度向量来更新位置

b[i]_x += b[i].v

上面这段话 \(cv\)\(yuy\_\) 的题解

三分法

#include <bits/stdc++.h>
using namespace std;
#define rg register
#define gc getchar
#define rep(i, a, b) for(int i = a; i <= b; ++i)
inline int read(){
    rg char ch = gc();
    rg int x = 0, f = 0;
    while(!isdigit(ch)) f |= (ch == '-'), ch = gc();
    while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = gc();
    return f ? -x : x;
}
const int N = 105;
int n;
double xs[15];
double l, r, len;
inline double calc(double x){
    double res = 0;
    rep(i, 0, n) res += pow(x, i) * xs[i];
    return res;
}
inline double Rand(){
    return (double) rand() / RAND_MAX;
}
double by = -1e100, bx;//best of all
struct node{
    double v, x, y, besty, bestx;
} b[N];
inline void update(int a){
    b[a].v = b[a].v * 0.5 + Rand() * 2 * (bx + b[a].bestx - b[a].x * 2);
    
    b[a].x += b[a].v;

    if(b[a].x < l) b[a].x = l, b[a].v *= -1;
    if(b[a].x > r) b[a].x = r, b[a].v *= -1;

    b[a].y = calc(b[a].x);
    if(b[a].y > b[a].besty){
        b[a].bestx = b[a].x;
        b[a].besty = b[a].y;
    }
    
    if(b[a].y > by){
        by = b[a].y;
        bx = b[a].x;
    }
}
signed main(){
    n = read(); scanf("%lf %lf", &l, &r);
    len = r - l;
    for(int i = n; ~i; --i) scanf("%lf", &xs[i]);
    srand(time(0));
    for(int i = 0; i < N; ++i){
        b[i].x = b[i].bestx = l + Rand() * len;
        b[i].v = 0;
        b[i].y = b[i].besty = calc(b[i].x);
        if(by < b[i].y) bx = b[i].x, by = b[i].y;
    }
    rep(k, 1, 100)
        for(int i = 0; i < N; ++i)
            update(i);
    printf("%.5lf\n", bx);
    gc(), gc();
    return 0;
}

P2571 [SCOI2010]传送带

#include <bits/stdc++.h>
using namespace std;
#define rg register
#define gc getchar
#define rep(i, a, b) for(int i = a; i <= b; ++i)
inline double read(){
    rg char ch = gc();
    rg int x = 0, f = 0;
    while(!isdigit(ch)) f |= (ch == '-'), ch = gc();
    while(isdigit(ch)) x = (x << 1) + (x << 3) + (ch ^ 48), ch = gc();
    if(ch == '.'){
        double res = x, pos = .1; ch = gc();
        while(isdigit(ch)) res += pos * (ch ^ 48), pos /= 10, ch = gc();
        return f ? -res : res;
    }
    return f ? -x : x;
}
const int N = 25;
struct vec{
    double x, y;
    vec(){}
    vec(double x, double y): x(x), y(y) {}
    inline vec operator + (vec rhs) {
        return vec(x + rhs.x, y + rhs.y);
    }
    inline vec operator - (vec rhs) {
        return vec(x - rhs.x, y - rhs.y);
    }
    inline vec operator * (double k){
        return vec(x * k, y * k);
    }
    inline double dis(){
        return sqrt(x * x + y * y);
    }
    inline double dis(const vec &rhs){
        return sqrt((rhs.x - x) * (rhs.x - x) + (rhs.y - y) * (rhs.y - y));
    }
}sa, sb, ta, tb, ans_xy;
double ax, bx, ay, by, cx, cy, dx, dy, da, db;
double ans_z = 1e100;
struct node{
    double bstz;
    double x, vx, y, vy, bstx, bsty, z;
}b[N];
double p, q, r;
inline double Rand(){
    return (double) rand() / RAND_MAX;
}
inline double calc(double x, double y){
    return x / p + y / q + (sa + (ta * x)).dis(sb + (tb * y)) / r;
}
inline void update(node &a){
    a.vx = a.vx * 0.5 + Rand() * 2 * (ans_xy.x + a.bstx - 2 * a.x);
    a.vy = a.vy * 0.5 + Rand() * 2 * (ans_xy.y + a.bsty - 2 * a.y);
    a.x += a.vx;
    a.y += a.vy;
    if(a.x > da) a.x = da, a.vx *= -1;
    if(a.y > db) a.y = db, a.vy *= -1;
    if(a.x < 0) a.x = 0, a.vx *= -1;
    if(a.y < 0) a.y = 0, a.vy *= -1;

    a.z = calc(a.x, a.y);
    if(a.z < a.bstz){
        a.bstz = a.z;
        a.bstx = a.x;
        a.bsty = a.y;
    }

    if(a.z < ans_z){
        ans_z = a.z;
        ans_xy = vec(a.x, a.y);
    }
}
#define eps 1e-8
signed main(){
    ax = read(), ay = read(), bx = read(), by = read();
    sa = vec(ax, ay); ta = vec(bx - ax, by - ay); da = ta.dis() + eps; ta = ta * (1 / da);
    cx = read(), cy = read(), dx = read(), dy = read();
    sb = vec(dx, dy); tb = vec(cx - dx, cy - dy); db = tb.dis() + eps; tb = tb * (1 / db);
    p = read(), q = read(), r = read();
    for(int i = 0; i < N; ++i){
        b[i].bstx = b[i].x = Rand() * da;
        b[i].y = b[i].bsty = Rand() * db;
        b[i].bstz = b[i].z = calc(b[i].x, b[i].y);
        if(b[i].z < ans_z){
            ans_xy = vec(b[i].x, b[i].y);
            ans_z = b[i].z;
        }
    }
    rep(k, 1, 20)
        for(int i = 0; i < N; ++i)
            update(b[i]);
    printf("%.2lf\n", ans_z);
    gc(), gc();
    return 0;
}
/*
2 2 2 2
3 3 3 3
1 1 1
*/
posted @ 2020-06-06 11:46  __int256  阅读(341)  评论(0编辑  收藏  举报