Pagini recente » Cod sursa (job #1035067) | Cod sursa (job #652296) | Cod sursa (job #2333397) | Cod sursa (job #34970) | Cod sursa (job #2343702)
#include <iostream>
#include <fstream>
#include <iomanip>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <vector>
using namespace std;
const int N = 10;
const int L = 3;
const int E = 100;
double f[L][N][N][N];
double e[E][L][N][N][N];
/// f[l][a][b][x] = the probability for picking x, given that the ball
/// is a dinstance l from the player's base, the player has a banace of
/// a and the enemy has a balance of b
/// Num. data points = L * N^3 = 3000
const int EPOCH = 1;
const int NUM_ATTEMPTS = 1000000000;
const double lr = 1.1;
int draw_random(double *f, int n) {
double p = 1.0 * rand() / RAND_MAX;
for (int i = 1; i < n; i++) {
if (f[i] > p)
return i;
p -= f[i];
}
return n - 1;
}
void normalize(double *f, int n) {
double sum = 0;
for (int i = 0; i < n; i++)
sum += f[i];
for (int i = 1; i < n; i++)
f[i] = max(f[i] / sum, 0.001);
}
double F(double f[L][N][N][N], double g[L][N][N][N]) {
double ans = 0, ans2 = 0, dr = 0;
double p[L][N][N] = {};
p[1][N - 1][N - 1] = 1.0;
for (int att = 4; att > 0; att--) {
for (int a = N - 1; a >= 0; a--)
for (int b = N - 1; b >= 0; b--) {
if (!a && !b) dr += p[1][a][b];
for (int i = 1; i <= a; i++)
for (int j = 1; j <= b; j++) {
double P = p[1][a][b] * f[1][a][b][i] * g[1][b][a][j];// / (1 - f[1][a][b][0] * g[1][b][a][0]);
if (i > j) {
p[2][a - i][b - j] += P;
} else if (j > i) {
p[0][a - i][b - j] += P;
} else {
p[1][a - i][b - j] += P;
}
}
p[1][a][b] = 0;
}
for (int a = N - 1; a >= 0; a--)
for (int b = N - 1; b >= 0; b--) {
if (!a && !b) dr += p[0][a][b];
for (int i = 1; i <= a; i++)
for (int j = 1; j <= b; j++) {
double P = p[0][a][b] * f[0][a][b][i] * g[2][b][a][j];// / (1 - f[0][a][b][0] * g[2][b][a][0]);
if (i > j) {
p[1][a - i][b - j] += P;
} else if (j > i) {
ans2 += P;
} else {
p[0][a - i][b - j] += P;
}
}
p[0][a][b] = 0;
}
for (int a = N - 1; a >= 0; a--)
for (int b = N - 1; b >= 0; b--) {
if (!a && !b) dr += p[2][a][b];
for (int i = 1; i <= a; i++)
for (int j = 1; j <= b; j++) {
double P = p[2][a][b] * f[2][a][b][i] * g[0][b][a][j];// / (1 - f[2][a][b][0] * g[0][b][a][0]);
if (i > j) {
ans += P;
} else if (j > i) {
p[1][a - i][b - j] += P;
} else {
p[2][a - i][b - j] += P;
}
}
p[2][a][b] = 0;
}
}
return ans / (ans + ans2);
}
double eval() {
double score = 0;
for (int i = 0; i < E; i++)
score += F(f, e[i]);
return score / E;
}
int main() {
srand(time(NULL));
for (int l = 0; l < L; l++)
for (int a = 0; a < N; a++)
for (int b = 0; b < N; b++)
for (int x = 1; x <= a; x++)
f[l][a][b][x] = 1.0 / a;
for (int i = 0; i < E; i++)
for (int l = 0; l < L; l++)
for (int a = 0; a < N; a++)
for (int b = 0; b < N; b++) {
for (int x = 1; x <= a; x++)
e[i][l][a][b][x] = pow(1.0 * rand() / RAND_MAX, 3);
normalize(e[i][l][a][b], a + 1);
}
double score = eval();
for (int attempt = 1; attempt <= NUM_ATTEMPTS; attempt++) {
for (int l = 0; l < L; l++)
for (int a = 0; a < N; a++) {
double c[N];
for (int b = 0; b < N; b++) {
for (int x = 0; x <= a; x++) {
memcpy(c, f[l][a][b], sizeof(c));
f[l][a][b][x] *= lr;
normalize(f[l][a][b], a + 1);
double ev = eval();
if (ev <= score)
memcpy(f[l][a][b], c, sizeof(c));
else
score = ev;
}
}
}
if (attempt % EPOCH == 0) {
for (int i = 0; i < N; i++)
cout << i << ": " << fixed << setprecision(2) << f[1][N - 1][N - 1][i] << endl;
cout << endl;
cout << endl << "Win rate: " << score;
cout << endl << endl;
ofstream out1("f1.txt");
for (int l = 0; l < L; l++) {
out1 << "L=" << l << '\n' << '\n';
for (int a = 0; a < N; a++)
for (int b = 0; b < N; b++) {
out1 << "a=" << a << ", b=" << b << '\n';
for (int x = 1; x <= a; x++)
out1 << x << ": " << (int)(f[l][a][b][x] * 100) << "%\n";
out1 << '\n';
}
out1 << '\n';
}
}
}
return 0;
}