提出 #37220631
ソースコード 拡げる
#include <iostream>
#include <vector>
#include <cmath>
#include <algorithm>
#include <cstdint>
#include <random>
#include <iomanip>
#include <bits/stdc++.h>
struct Timer {
std::chrono::high_resolution_clock::time_point st;
Timer() { st = now(); }
std::chrono::high_resolution_clock::time_point now() { return std::chrono::high_resolution_clock::now(); }
std::chrono::milliseconds::rep span() {
auto ed = now();
return std::chrono::duration_cast<std::chrono::milliseconds>(ed - st).count();
}
};
using u32 = std::uint_fast32_t;
using i64 = std::int_fast64_t;
constexpr int K = 26;
int D;
std::vector<i64> C;
std::vector<std::vector<i64>> S;
using Score = i64;
struct Individual {
std::vector<int> vec;
Individual() = default;
explicit Individual(std::vector<int> vec): vec(std::move(vec)) {}
Individual crossover(std::mt19937& mt, const Individual& y) const {
Individual mx;
Score score = -1e9;
int now = vec.size() / 2;
{
std::vector<int> next(vec.size());
std::copy(vec.begin(), vec.begin() + vec.size() / 2, next.begin());
std::copy(y.vec.begin() + vec.size() / 2, y.vec.end(), next.begin() + vec.size() / 2);
Individual child(std::move(next));
score = child.evaluate_state();
mx = std::move(child);
}
constexpr int Count = 30;
for(int q = 0; q < Count; q++) {
int DIFF = 15;
int at = std::min(D - 1, std::max(1, std::uniform_int_distribution<>(-DIFF, DIFF - 1)(mt) + now));
if(at >= 0) at++;
std::vector<int> next(vec.size());
std::copy(vec.begin(), vec.begin() + at, next.begin());
std::copy(y.vec.begin() + at, y.vec.end(), next.begin() + at);
Individual child(std::move(next));
Score next_score = child.evaluate_state();
if(score <= next_score || std::bernoulli_distribution(std::exp(-(score - next_score) / 4e2))(mt)) {
score = next_score;
mx = std::move(child);
now = at;
}
}
return mx;
}
void mutation(std::mt19937& mt) {
std::bernoulli_distribution swap_dist(0.005);
for(int i = 1; i < vec.size(); i++) {
if(swap_dist(mt)) {
std::uniform_int_distribution<> at_dist(std::max(0, i - 15), i - 1);
int j = at_dist(mt);
std::swap(vec[i], vec[j]);
}
}
for(int i = 0; i < vec.size(); i++) {
if(swap_dist(mt)) {
vec[i] = std::uniform_int_distribution<>(0, K - 1)(mt);
}
}
}
Score evaluate_state() const {
i64 sum = 0;
std::vector<i64> before(K, -1);
for(int i = 0; i < D; i++) {
int v = vec[i];
sum += S[i][v];
i64 d = i - before[v];
sum -= C[v] * d * (d - 1) / 2;
before[v] = i;
}
for(int v = 0; v < K; v++) {
i64 d = D - before[v];
sum -= C[v] * d * (d - 1) / 2;
}
return sum;
}
};
void local_search(std::mt19937& mt, Individual& x, Score& score) {
constexpr int Count = 50;
constexpr double T = 5e2;
for(int q = 0; q < Count; q++) {
if(std::bernoulli_distribution(0.5)(mt)) {
int i = std::uniform_int_distribution<>(0, x.vec.size() - 1)(mt);
int j = std::uniform_int_distribution<>(std::max(0, i - 13), std::min(D - 2, i + 12))(mt);
if(j >= i) j++;
std::swap(x.vec[i], x.vec[j]);
Score next = x.evaluate_state();
if(score <= next || std::bernoulli_distribution(std::exp(-(score - next) / T))(mt)) {
score = next;
}
else {
std::swap(x.vec[i], x.vec[j]);
}
}
else {
int i = std::uniform_int_distribution<>(0, x.vec.size() - 1)(mt);
int before = x.vec[i];
x.vec[i] = std::uniform_int_distribution<>(0, K - 2)(mt);
if(before <= x.vec[i]) x.vec[i]++;
Score next = x.evaluate_state();
if(score <= next || std::bernoulli_distribution(std::exp(-(score - next) / T))(mt)) {
score = next;
}
else {
x.vec[i] = before;
}
}
}
}
struct Generation {
constexpr static int Count = 12;
constexpr static int Elite = 4;
constexpr static int NewInd = 3;
std::vector<std::pair<Individual, Score>> inds;
void init(std::mt19937& mt) {
for(int i = 0; i < Count; i++) {
std::vector<int> init(D);
for(int d = 0; d < D; d++) {
init[d] = std::uniform_int_distribution<>(0, K - 1)(mt);
}
Individual x(std::move(init));
Score score = x.evaluate_state();
inds.emplace_back(std::move(x), std::move(score));
}
}
Generation next_gen(std::mt19937& mt) const {
Generation next;
std::vector<int> idx(Count);
std::iota(idx.begin(), idx.end(), 0);
// elitism
std::nth_element(idx.begin(), idx.begin() + Elite - 1, idx.end(), [&](int i, int j) { return inds[i].second > inds[j].second; });
for(int i = 0; i < Elite; i++) {
next.inds.push_back(inds[idx[i]]);
}
// selection & crossover by roulette
Score max_score = std::max_element(inds.begin(), inds.end(), [](auto& a, auto& b) { return a.second > b.second; })->second;
std::vector<double> pie(inds.size());
for(int i = 0; i < inds.size(); i++) {
pie[i] = inds[i].second - max_score;
if(i > 0) {
pie[i] += pie[i - 1];
}
}
std::uniform_real_distribution<> dice(0, pie.back());
for(int i = Elite; i < Count - NewInd; i++) {
int x = std::lower_bound(pie.begin(), pie.end(), dice(mt), [](auto& a, double v) { return a < v; }) - pie.begin();
double diff = pie[x] - (x == 0 ? 0 : pie[x - 1]);
int y = std::lower_bound(pie.begin(), pie.end(), std::uniform_real_distribution<>(0, pie.back() - diff)(mt),
[&](auto& a, double v) { return (a >= pie[x] ? a - diff : a ) < v; }
) - pie.begin();
Individual child = inds[x].first.crossover(mt, inds[y].first);
child.mutation(mt);
Score score = child.evaluate_state();
next.inds.emplace_back(std::move(child), std::move(score));
}
for(int i = Count - NewInd; i < Count; i++) {
std::vector<int> init(D);
for(int d = 0; d < D; d++) {
init[d] = std::uniform_int_distribution<>(0, K - 1)(mt);
}
Individual x(std::move(init));
/*
Individual x(next.inds[i - Count + NewInd].first);
x.mutation(mt);
x.mutation(mt);
*/
Score score = x.evaluate_state();
next.inds.emplace_back(std::move(x), std::move(score));
}
for(auto& [x, score]: next.inds) {
local_search(mt, x, score);
}
return next;
}
};
int main() {
std::mt19937 mt;
//const int Century = 100000;
std::cin >> D;
C.resize(K);
for(int i = 0; i < K; i++) {
std::cin >> C[i];
}
S.resize(D, std::vector<i64>(K));
for(int i = 0; i < D; i++) {
for(int j = 0; j < K; j++) {
std::cin >> S[i][j];
}
}
Generation gen;
gen.init(mt);
Timer timer;
//for(int q = 0; q < Century; q++) {
int q = 0;
Individual MAX;
Score score = -1e9;
while(timer.span() < 1980) {
gen = gen.next_gen(mt);
q++;
if(q % 100 == 0) {
auto& NEXT = *std::max_element(gen.inds.begin(), gen.inds.end(), [](const auto& a, const auto& b) { return a.second < b.second; });
if(score < NEXT.second) {
MAX = NEXT.first;
score = NEXT.second;
}
std::cerr << q << " " << score << std::endl;
}
//std::cerr << std::fixed << std::setprecision(10) << q++ << "\t" << MAX.second << std::endl;
}
std::cerr << timer.span() << std::endl;
std::cerr << score << std::endl;
for(int i = 0; i < D; i++) {
std::cout << MAX.vec[i] + 1 << "\n";
}
}
提出情報
コンパイルエラー
./Main.cpp: In member function ‘void Individual::mutation(std::mt19937&)’:
./Main.cpp:69:22: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::vector<int>::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
69 | for(int i = 1; i < vec.size(); i++) {
| ~~^~~~~~~~~~~~
./Main.cpp:76:22: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::vector<int>::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
76 | for(int i = 0; i < vec.size(); i++) {
| ~~^~~~~~~~~~~~
./Main.cpp: In member function ‘Generation Generation::next_gen(std::mt19937&) const’:
./Main.cpp:169:22: warning: comparison of integer expressions of different signedness: ‘int’ and ‘std::vector<std::pair<Individual, long int> >::size_type’ {aka ‘long unsigned int’} [-Wsign-compare]
169 | for(int i = 0; i < inds.size(); i++) {
| ~~^~~~~~~~~~~~~
ジャッジ結果
セット名 |
test_ALL |
得点 / 配点 |
117381492 / 365000000 |
結果 |
|
セット名 |
テストケース |
test_ALL |
test_00.txt, test_01.txt, test_02.txt, test_03.txt, test_04.txt, test_05.txt, test_06.txt, test_07.txt, test_08.txt, test_09.txt, test_10.txt, test_11.txt, test_12.txt, test_13.txt, test_14.txt, test_15.txt, test_16.txt, test_17.txt, test_18.txt, test_19.txt, test_20.txt, test_21.txt, test_22.txt, test_23.txt, test_24.txt, test_25.txt, test_26.txt, test_27.txt, test_28.txt, test_29.txt, test_30.txt, test_31.txt, test_32.txt, test_33.txt, test_34.txt, test_35.txt, test_36.txt, test_37.txt, test_38.txt, test_39.txt, test_40.txt, test_41.txt, test_42.txt, test_43.txt, test_44.txt, test_45.txt, test_46.txt, test_47.txt, test_48.txt, test_49.txt |
ケース名 |
結果 |
実行時間 |
メモリ |
test_00.txt |
AC |
1990 ms |
4132 KiB |
test_01.txt |
AC |
1989 ms |
4216 KiB |
test_02.txt |
AC |
1986 ms |
4088 KiB |
test_03.txt |
AC |
1986 ms |
4248 KiB |
test_04.txt |
AC |
1989 ms |
4148 KiB |
test_05.txt |
AC |
1989 ms |
4172 KiB |
test_06.txt |
AC |
1987 ms |
4088 KiB |
test_07.txt |
AC |
1990 ms |
4176 KiB |
test_08.txt |
AC |
1988 ms |
4140 KiB |
test_09.txt |
AC |
1988 ms |
4128 KiB |
test_10.txt |
AC |
1987 ms |
4184 KiB |
test_11.txt |
AC |
1987 ms |
4284 KiB |
test_12.txt |
AC |
1986 ms |
4284 KiB |
test_13.txt |
AC |
1988 ms |
4268 KiB |
test_14.txt |
AC |
1987 ms |
4084 KiB |
test_15.txt |
AC |
1988 ms |
4140 KiB |
test_16.txt |
AC |
1988 ms |
4384 KiB |
test_17.txt |
AC |
1988 ms |
4220 KiB |
test_18.txt |
AC |
1985 ms |
4144 KiB |
test_19.txt |
AC |
1987 ms |
4176 KiB |
test_20.txt |
AC |
1988 ms |
4280 KiB |
test_21.txt |
AC |
1986 ms |
4384 KiB |
test_22.txt |
AC |
1989 ms |
4140 KiB |
test_23.txt |
AC |
1988 ms |
4388 KiB |
test_24.txt |
AC |
1985 ms |
4284 KiB |
test_25.txt |
AC |
1988 ms |
4180 KiB |
test_26.txt |
AC |
1988 ms |
4128 KiB |
test_27.txt |
AC |
1987 ms |
4136 KiB |
test_28.txt |
AC |
1989 ms |
4268 KiB |
test_29.txt |
AC |
1987 ms |
4284 KiB |
test_30.txt |
AC |
1987 ms |
4148 KiB |
test_31.txt |
AC |
1988 ms |
4132 KiB |
test_32.txt |
AC |
1987 ms |
4216 KiB |
test_33.txt |
AC |
1988 ms |
4152 KiB |
test_34.txt |
AC |
1987 ms |
4264 KiB |
test_35.txt |
AC |
1987 ms |
4180 KiB |
test_36.txt |
AC |
1987 ms |
4176 KiB |
test_37.txt |
AC |
1987 ms |
4268 KiB |
test_38.txt |
AC |
1990 ms |
4152 KiB |
test_39.txt |
AC |
1987 ms |
4172 KiB |
test_40.txt |
AC |
1988 ms |
4088 KiB |
test_41.txt |
AC |
1986 ms |
4128 KiB |
test_42.txt |
AC |
1989 ms |
4092 KiB |
test_43.txt |
AC |
1988 ms |
4092 KiB |
test_44.txt |
AC |
1986 ms |
4172 KiB |
test_45.txt |
AC |
1989 ms |
4264 KiB |
test_46.txt |
AC |
1989 ms |
4252 KiB |
test_47.txt |
AC |
1989 ms |
4252 KiB |
test_48.txt |
AC |
1987 ms |
4092 KiB |
test_49.txt |
AC |
1986 ms |
4180 KiB |