粒子群优化(微粒群算法)
迭代公式
\[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
*/