add: 0943

This commit is contained in:
Eatswap 2023-04-11 10:29:24 +08:00
parent a9ff3c5bc0
commit 873ac4de1e
Signed by: Eatswap
GPG Key ID: BE661106A1F3FA0B
2 changed files with 111 additions and 1 deletions

110
cpp/more/0943.cpp Normal file
View File

@ -0,0 +1,110 @@
#include <iostream>
#include <numeric>
#include <vector>
#include <string>
#include <random>
#include <ctime>
#include <algorithm>
#include <cstdio>
// INCOMPLETE
class Solution {
private:
static int calc_dist(const std::string&, const std::string&);
static void get_next(std::mt19937&, std::vector<int>&, int = 1);
static const inline int ITER_COUNT = 2200000;
public:
static std::string shortestSuperstring(const std::vector<std::string>&);
};
std::string Solution::shortestSuperstring(const std::vector<std::string>& w) {
const int n = w.size();
int dist[12][12]{}, MAX_DIST = 1;
for (int i = 0; i < n; ++i) {
for (int j = i + 1; j < n; ++j) {
dist[i][j] = calc_dist(w[i], w[j]);
dist[j][i] = calc_dist(w[j], w[i]);
MAX_DIST = std::max(MAX_DIST, std::max(dist[i][j], dist[j][i]));
}
}
auto energy = [&](const std::vector<int>& v) {
int ret = 0;
for (int i = 1; i < v.size(); ++i)
ret += dist[v[i - 1]][v[i]];
return -ret;
};
auto print_state = [](const char* prompt, const std::vector<int>& v) {
std::printf("%s: ", prompt);
for (int i : v)
std::printf("%2d ", i);
std::printf("\n");
};
auto seed = std::time(nullptr);
std::cout << "Seed = " << seed << "\n";
std::mt19937 r(seed);
std::vector<int> state(n), next_state;
std::iota(state.begin(), state.end(), 0);
int current_energy = energy(state);
for (int i = 0; i < ITER_COUNT; ++i) {
// std::printf("ITERATION # %d\n", i);
// Temperature is defined as (ITER_COUNT - i);
next_state = state;
get_next(r, next_state);
// print_state("Current state", state);
// print_state("Next state", next_state);
int next_energy = energy(next_state);
if (next_energy <= current_energy) {
// std::printf("Next E = %d < %d (Current E), accepting new state.\n", next_energy, current_energy);
state = next_state;
current_energy = next_energy;
} else if (double x = (double(r()) / r.max()), dte = double(current_energy - next_energy) / (double(ITER_COUNT - i) / ITER_COUNT * MAX_DIST), dt = std::exp(dte); x < dt) {
// std::printf("Next state worse (%d >= %d), rand = %.5f and exp(dE / T) = %.5f, accept anyway.\n", next_energy, current_energy, x, dt);
state = next_state;
current_energy = next_energy;
} else {
// std::printf("Next state worse (%d >= %d), rand = %.5f and exp(dE / T) = %.5f, rejected.\n", next_energy, current_energy, x, dt);
}
// std::printf("------------------------------------------------\n");
}
print_state("Final state", state);
std::printf("ENERGY = %d\n", energy(state));
std::string ret = w[state[0]];
for (int i = 1; i < n; ++i)
ret += w[state[i]].substr(dist[state[i - 1]][state[i]]);
return ret;
}
int Solution::calc_dist(const std::string& s, const std::string& t) {
const int m = s.size(), n = t.size();
int k = std::min(m, n), r = 0;
for (int i = 1; i <= k; ++i) {
int p = m - i, q = 0, ok = 1;
for (; p < m; ++p, ++q) {
if (s[p] != t[q]) {
ok = 0;
break;
}
}
r = ok ? i : r;
}
return r;
}
void Solution::get_next(std::mt19937& r, std::vector<int>& v, int c) {
int i, j;
while (c--) {
i = double(r()) / r.max() * v.size();
j = double(r()) / r.max() * v.size();
std::swap(v[i], v[j]);
}
}
int main() {
auto r = Solution::shortestSuperstring({"cgjufdqhfw","bsrchpiau","hfwbsrchpi","sezsorql","srchpiaues","rqlmc"});
Solution::shortestSuperstring({"wmiy","yarn","rnnwc","arnnw","wcj"});
Solution::shortestSuperstring({"jap","zebr","ebrxx","apz"});
std::printf("%s\n", r.c_str());
return 0;
}

View File

@ -3,4 +3,4 @@ PROJECT(more)
SET(CMAKE_CXX_STANDARD 23) SET(CMAKE_CXX_STANDARD 23)
ADD_EXECUTABLE(more 0001.cpp) ADD_EXECUTABLE(more 0943.cpp)