9#include <boost/accumulators/accumulators.hpp>
10#include <boost/accumulators/statistics/stats.hpp>
11#include <boost/accumulators/statistics/mean.hpp>
12#include <boost/accumulators/statistics/min.hpp>
13#include <boost/accumulators/statistics/max.hpp>
14#include <boost/format.hpp>
35 features.push_back(f);
37 light_features.push_back(features.size()-1);
43 offsets.resize(features.size()+1);
45 for (
size_t i=0; i<features.size(); ++i)
46 offsets[i+1] = offsets[i] + features[i].dimension();
55 for (
size_t i=0; i<
features.size(); ++i) {
64 return exp(matchNoExp(state, move, weights));
71 assert(offsets.size() == features.size()+1);
73 for (
size_t i: light_features) {
74 sum += features[i].match(state, info, offsets[i], weights);
85 std::vector<std::pair<double, std::string> > out;
86 for (
size_t i=0; i<features.size(); ++i) {
87 double s = features[i].match(state, info, offsets[i], weights);
89 out.push_back(make_pair(s, features[i].name()));
91 std::sort(out.begin(), out.end());
92 std::reverse(out.begin(), out.end());
93 for (
size_t i=0; i<out.size(); ++i) {
94 std::cerr << boost::format(
"%16s %6.2f ") % out[i].second % out[i].first;
98 if (out.size() % 3 != 0)
104 const double * weights)
const
106 assert(! state.
dirty);
111 for (
Move move: moves) {
112 double score = matchExp(state, move, weights);
123 static const double scale = 100.0 / log(0.5);
125 double p = move.first/sum;
126 if (std::isnan(p) || p <= 1.0/(1<<12))
128 const int logp = std::max(50,
static_cast<int>(log(p)*scale));
136 const double * weights)
const
139 double sum = generateRating(state, moves, weights);
140 ratingToLogProb(moves, sum, out);
144load(
const char *base_filename,
double * weights)
const
146 std::string filename = std::string(base_filename) +
".txt";
147 std::fill(weights, weights+dimension(), 0.0);
148 std::ifstream is(filename.c_str());
149 for (
int i=0; i<dimension(); ++i) {
152 std::cerr <<
"load failed at " << i <<
" in " << dimension()
153 <<
" file " << filename <<
"\n";
157 return static_cast<bool>(is);
161load_binary(
const char *base_filename,
double * weights)
const
163 std::string filename = std::string(base_filename) +
".bin";
164 std::fill(weights, weights+dimension(), 0.0);
165 std::ifstream is(filename.c_str(), std::ios_base::binary);
167 for (
int i=0; i<dimension(); ++i) {
169 std::cerr <<
"load failed at " << i <<
" in " << dimension()
170 <<
" file " << filename <<
"\n";
173 double value = reader.
read();
182 for (
size_t i=0; i<features.size(); ++i) {
183 const Feature& f = features[i];
184#if (__GNUC_MINOR__ < 5)
185 using namespace boost::accumulators;
186 accumulator_set<double, stats<tag::mean, tag::min, tag::max> > acc;
189 for (
int j=offsets[i]; j<offsets[i+1]; ++j)
191#if (__GNUC_MINOR__ < 5)
197 std::cerr << std::setw(16) << f.
name()
198 <<
" dim " << std::setw(5) << f.
dimension() - zero
200#if (__GNUC_MINOR__ < 5)
201 <<
" min " << std::setw(6) << min(acc)
202 <<
" max " << std::setw(6) << max(acc)
203 <<
" mean " << std::setw(6) << mean(acc)
281 the_instance.
setUp(verbose);
288 return instance(
true).
ok();
293 namespace move_probability
302 static bool initialized =
false;
306 weights.reset(
new double[dimension()]);
308 filename +=
"/data/move-order";
310 std::cerr <<
"loading " << filename <<
".bin ";
311 const bool success = load_binary(filename.c_str(), &weights[0]);
313 std::cerr << (success ?
"success" :
"failed\a") <<
"\n";
316 filename +=
"/data/move-tactical.txt";
317 const int tactical_dimension = 8*4;
318 tactical_weights.reset(
new double[tactical_dimension]);
320 std::cerr <<
"loading " << filename <<
" ";
321 std::ifstream is(filename.c_str());
322 for (
int i=0; i<tactical_dimension; ++i)
323 is >> tactical_weights[i];
325 std::cerr << (is ?
"success" :
"failed\a") <<
"\n";
326 this->initialized = success && is;
327 return this->initialized;
341 double elapsed = 0.0, welapsed = 0.0, last_p = 1.0;
342 std::sort(moves.
begin(), moves.
end());
343 for (
int i=moves.
size()-1; i>=0; --i) {
345 static const double scale = 100.0 / log(0.5);
346 if (i+1<(
int)moves.
size())
347 welapsed = std::max(welapsed, std::min(moves[i+1].first,move.first*4));
348 double p = move.first/(sum-elapsed+welapsed);
349 if (std::isnan(p) || p <= 1.0/(1<<12))
352 p = std::min(last_p, p);
353 int logp = std::max(50,
static_cast<int>(log(p)*scale));
354 if (moves.
size() - i <= 8)
355 logp = std::min(logp, 300);
356 else if (moves.
size() - i <= 16)
357 logp = std::min(logp, 500);
359 elapsed += move.first;
360 welapsed = (welapsed+move.first)*(moves.
size()-i)/moves.
size();
367 generateLogProb2(state, out);
392 const double sum = matchLight(state, target);
393 return tacticalLogProb(progress8*4 + 0, sum);
400 const double sum = matchLight(state, target);
401 return tacticalLogProb(progress8*4 + 2, sum);
407 static const double scale = 100.0 / log(0.5);
408 double x = tactical_weights[offset] * sum + tactical_weights[offset+1];
409 double p = 1/(1.0+exp(-x));
410 return std::max(50,
static_cast<int>(log(p)*scale));
void push_back(const T &e)
void generateLegal(MoveVector &) const
全ての合法手を生成する.
void push_back(Move move, int prob)
void sortByProbability()
確率が高い順にsort
double generateRating(const StateInfo &state, WeightedMoveVector &out, const double *weights) const
double matchExp(const StateInfo &, Move, const double *weights) const
double matchNoExp(const StateInfo &, Move, const double *weights) const
void generateLogProb(const StateInfo &state, MoveLogProbVector &out, const double *weights) const
bool load_binary(const char *base_filename, double *weights) const
std::vector< int > offsets
double matchLight(const StateInfo &, Move, const double *weights) const
void analyze(const StateInfo &state, Move move, const double *weights) const
bool load(const char *base_filename, double *weights) const
void showSummary(const double *weights) const
boost::ptr_vector< Feature > features
static void ratingToLogProb(const WeightedMoveVector &rating, double sum, MoveLogProbVector &out)
void pushBack(Feature *, bool light=false)
static boost::scoped_array< double > tactical_weights
void generateLogProb(const StateInfo &state, MoveLogProbVector &out) const
static boost::scoped_array< double > weights
bool setUp(bool verbose=false)
int logProbTakeBack(const StateInfo &state, Move target) const
void generateLogProb2(const StateInfo &state, MoveLogProbVector &out) const
int logProbSeePlus(const StateInfo &state, Move target) const
static bool healthCheck()
static const StandardFeatureSet & instance(bool verbose=false)
double matchLight(const StateInfo &, Move) const
double matchExp(const StateInfo &, Move) const
int tacticalLogProb(int offset, double sum) const
double matchNoExp(const StateInfo &, Move) const
const std::string show(Move)
PatternBase< false > Pattern
std::mutex standardfeatureset_lock
std::pair< double, Move > WeightedMove
static const std::string & home(const std::string &initialize_if_first_invocation="")
compile時に指定されたディレクトリを返す.
const NumEffectState * state