diff --git a/optimizer/box-eater.cpp b/optimizer/box-eater.cpp index cb9e4a5..7a4940c 100644 --- a/optimizer/box-eater.cpp +++ b/optimizer/box-eater.cpp @@ -10,9 +10,6 @@ std::mt19937 rng(std::random_device{}()); __builtin_unreachable(); \ } while (false); \ -const float temperature_initial = 60; -const float temperature_low = 10; -const float temperature_delta = .97; const int species_limit = 5; const int population_limit = 10; const int SPECIES_NAME_LEN = 4; @@ -27,11 +24,15 @@ struct Gene { struct Species { std::vector population; int best_w; - float T, eT; char name[SPECIES_NAME_LEN + 1]; - int age, tactic; + int stable_age, age, tactic; - Species() : population(), best_w(-1), T(1.), eT(-1), name{"NULL"}, age(0) {} + Species() : population(), best_w(-1), name{"NULL"}, stable_age(0), age(0), tactic(-1) {} + + void tick() { + age += 1; + stable_age += 1; + } int size() const { return population.size(); @@ -42,7 +43,7 @@ struct Species { } bool operator<(const Species &o) const { - return eT < o.eT; + return best_w < o.best_w; } }; @@ -59,7 +60,8 @@ inline Gene loadGene(std::FILE *f) { } inline void writeSpecies(const Species &s, std::FILE *f) { - std::fprintf(f, "%d %d %.12f %s %d %d\n", s.size(), s.best_w, s.T, s.name, s.age, s.tactic); + std::fprintf(f, "%d %d %s %d %d %d\n", (int)s.size(), s.best_w, s.name + , s.stable_age, s.age, s.tactic); for (const auto &g : s.population) { writeGene(g, f); } @@ -68,7 +70,8 @@ inline void writeSpecies(const Species &s, std::FILE *f) { inline Species loadSpecies(std::FILE *f) { Species res; int n; - std::fscanf(f, "%d %d %f %s %d %d", &n, &res.best_w, &res.T, res.name, &res.age, &res.tactic); + std::fscanf(f, "%d %d %s %d %d %d", &n, &res.best_w, res.name + , &res.stable_age, &res.age, &res.tactic); res.population.reserve(n); for (int i = 0; i < n; ++i) { res.population.push_back(loadGene(f)); @@ -146,11 +149,14 @@ inline void mutationReselectPOI(Species &res, const Gene &sc) { } } -inline void mutationLineCl(Species &res, const Gene &sc) { +inline void mutationRowCl(Species &res, const Gene &sc, int rep = 1) { Gene ac = sc; - int r = rng0N(rng); - for (int i = 0; i < N; ++i) { - ac.m.set(r, i, SQR_SPACE); + + std::uniform_int_distribution rngRow(0, N - rep); + int r = rngRow(rng); + for (int i = 0; i < rep; ++i) { + for (int j = 0; j < N; ++j) + ac.m.set(r + i, j, SQR_SPACE); } ac.w = Solve::solve(ac.m); @@ -158,11 +164,14 @@ inline void mutationLineCl(Species &res, const Gene &sc) { res.population.push_back(std::move(ac)); } -inline void mutationColCl(Species &res, const Gene &sc) { +inline void mutationColCl(Species &res, const Gene &sc, int rep = 1) { Gene ac = sc; - int c = rng0N(rng); - for (int i = 0; i < N; ++i) { - ac.m.set(i, c, SQR_SPACE); + + std::uniform_int_distribution rngCol(0, N - rep); + int c = rngCol(rng); + for (int i = 0; i < rep; ++i) { + for (int j = 0; j < N; ++j) + ac.m.set(j, c + i, SQR_SPACE); } ac.w = Solve::solve(ac.m); @@ -172,8 +181,8 @@ inline void mutationColCl(Species &res, const Gene &sc) { inline void mutationSqrCl(Species &res, const Gene &sc, int sz) { Gene ac = sc; + const int sz2 = sz / 2; int cx = rng0N(rng), cy = rng0N(rng); - int sz2 = sz / 2; for (int dx = -sz2; dx <= sz2; ++dx) { for (int dy = -sz2; dy <= sz2; ++dy) { int xx = cx + dx, yy = cy + dy; @@ -188,10 +197,9 @@ inline void mutationSqrCl(Species &res, const Gene &sc, int sz) { } inline Species mutation(const Species &sc) { - static std::uniform_int_distribution rngTacs(0, 6); + static std::uniform_int_distribution rngTacs(0, 4); Species res; randomName(SPECIES_NAME_LEN, res.name); - res.T = temperature_initial; do { int tactic = rngTacs(rng); @@ -201,26 +209,19 @@ inline Species mutation(const Species &sc) { mutationRandomHole(res, sc.population[0], 60); break; case 1: - mutationRandomHole(res, sc.population[0], 40); + mutationRowCl(res, sc.population[0], 2); break; case 2: - mutationReselectPOI(res, sc.population[0]); + mutationColCl(res, sc.population[0], 2); break; case 3: - mutationLineCl(res, sc.population[0]); + mutationSqrCl(res, sc.population[0], 3); break; case 4: - mutationColCl(res, sc.population[0]); - break; - case 5: - mutationSqrCl(res, sc.population[0], 3); - mutationSqrCl(res, sc.population[0], 3); - break; - case 6: mutationSqrCl(res, sc.population[0], 5); break; } - } while (res.size() == 0); + } while (res.empty()); return res; } @@ -268,10 +269,14 @@ inline void inherit(Species &s) { } s.population.clear(); + int ori_best_w = s.best_w; for (const auto &g : nxt) { s.best_w = std::max(s.best_w, g.w); } + if (ori_best_w != s.best_w) + s.stable_age = 0; + for (auto &g : nxt) { if (g.w == s.best_w) s.population.push_back(std::move(g)); @@ -293,21 +298,16 @@ int main() { std::uniform_real_distribution d01(0, 1); for (int iter_id = 1; ; ++iter_id) { - int best_w = 0, hbest_w = 0; + int best_w = 0; for (auto &s : biosphere) { inherit(s); best_w = std::max(best_w, s.best_w); - if (s.T > temperature_low) - hbest_w = std::max(hbest_w, s.best_w); } std::vector Hnxt, Lnxt; for (auto &s : biosphere) { - const bool is_ht = s.T > temperature_low; - const float dE = (is_ht ? hbest_w : best_w) - s.best_w; - s.eT = exp(-dE / s.T); - if (s.eT >= d01(rng) || s.age <= 15) { - if (is_ht) + if (s.stable_age <= 15 || s.best_w == best_w) { + if (s.best_w < best_w || s.age <= 35) Hnxt.push_back(std::move(s)); else Lnxt.push_back(std::move(s)); @@ -327,13 +327,13 @@ int main() { } } - for (auto &s : Hnxt) { - s.age += 1; - s.T = std::max(s.T * temperature_delta, temperature_low); + for (auto &s : Hnxt) biosphere.push_back(std::move(s)); - } Hnxt.clear(); + for (auto &s : biosphere) + s.tick(); + bool broke_record = best_w > history_best_w; if (broke_record) { history_best_w = best_w; @@ -347,7 +347,8 @@ int main() { printf("Iterated for %d times.\n", iter_id); printf("Current Best=%d, History Best=%d, Species:\n", best_w, history_best_w); for (auto &s : biosphere) { - printf(" - %s[%d]: best=%d T=%.3f age=%d.\n", s.name, s.tactic, s.best_w, s.T, s.age); + printf(" - %s[%d]: best=%d stable=%d age=%d.\n", s.name + , s.tactic, s.best_w, s.stable_age, s.age); } std::FILE *f = fopen("current.txt", "w");