【基础】随机优化算法
https://codeforces.com/contest/2/problem/C
随机移动算法。
double x[4], y[4], r[4];
double dis(double X, double Y, int id) {
double len = sqrt(sq(X - x[id]) + sq(Y - y[id]));
return PI / 2.0 - acos(r[id] / len);
}
double getLoss(double X, double Y) {
double dis1 = dis(X, Y, 1), dis2 = dis(X, Y, 2), dis3 = dis(X, Y, 3);
return sq(dis1 - dis2) + sq(dis1 - dis3) + sq(dis2 - dis3);
}
double myRand() {
return 2.0 * rand() / RAND_MAX - 1.0;
}
void InnerRandomOptimize(double &X, double &Y, double step, int p1, int p2) {
double curLoss = getLoss(X, Y);
for(int i = 1; i <= p1; ++i) {
for(int j = 1; j <= p2; ++j) {
double r1 = myRand(), r2 = myRand();
double rlen = sqrt(sq(r1) + sq(r2));
r1 /= rlen, r2 /= rlen;
double newX = X + r1 * step, newY = Y + r2 * step;
double newLoss = getLoss(newX, newY);
if(newLoss < curLoss)
X = newX, Y = newY, curLoss = newLoss;
}
//printf("X=%.6f Y=%.6f loss=%.6f\n", X, Y, curLoss);
step *= 0.75;
}
//printf("X=%.6f Y=%.6f loss=%.6f\n", X, Y, curLoss);
}
void RandomOptimize(double &X, double &Y) {
srand(time(0));
InnerRandomOptimize(X, Y, 10.0, 20, 2000);
InnerRandomOptimize(X, Y, 10.0, 200, 200);
InnerRandomOptimize(X, Y, 10.0, 2000, 20);
}
int n;
double x[105], y[105], z[105];
double dis(double X, double Y, double Z, int id) {
double len = sqrt(sq(X - x[id]) + sq(Y - y[id]) + sq(Z - z[id]));
return len;
}
double getLoss(double X, double Y, double Z) {
double sumLoss = 0.0;
for(int i = 1; i <= n; ++i)
cmax(sumLoss, dis(X, Y, Z, i));
return sumLoss;
}
double myRand() {
return 2.0 * rand() / RAND_MAX - 1.0;
}
void InnerRandomOptimize(double &X, double &Y, double &Z, double step, int p1, int p2) {
double curLoss = getLoss(X, Y, Z);
for(int i = 1; i <= p1; ++i) {
for(int j = 1; j <= p2; ++j) {
double r1 = myRand(), r2 = myRand(), r3 = myRand();
double rlen = sqrt(sq(r1) + sq(r2) + sq(r3));
r1 /= rlen, r2 /= rlen, r3 /= rlen;
double newX = X + r1 * step, newY = Y + r2 * step, newZ = r3 * step;
double newLoss = getLoss(newX, newY, newZ);
if(newLoss < curLoss)
X = newX, Y = newY, Z = newZ, curLoss = newLoss;
}
//printf("X=%.6f Y=%.6f Z=%.6f loss=%.6f\n", X, Y, Z, curLoss);
step *= 0.75;
}
//printf("X=%.6f Y=%.6f Z=%.6f loss=%.6f\n", X, Y, Z, curLoss);
}
void RandomOptimize(double &X, double &Y, double &Z) {
srand(time(0));
InnerRandomOptimize(X, Y, Z, 10.0, 20, 2000);
InnerRandomOptimize(X, Y, Z, 10.0, 200, 200);
InnerRandomOptimize(X, Y, Z, 10.0, 2000, 20);
}
启发式移动算法