My Project
featureSet_.cc
Go to the documentation of this file.
1 /* featureSet.cc
2  */
5 #include "osl/container.h"
6 #include "osl/csa.h"
7 #include "osl/bits/binaryIO.h"
8 #include "osl/oslConfig.h"
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>
15 #include <mutex>
16 #include <fstream>
17 #include <iomanip>
18 #include <iostream>
19 #include <cstdio>
20 #include <cmath>
21 
24 {
25 }
26 
29 {
30 }
31 
33 FeatureSet::pushBack(Feature *f, bool light)
34 {
35  features.push_back(f);
36  if (light)
37  light_features.push_back(features.size()-1);
38 }
39 
42 {
43  offsets.resize(features.size()+1);
44  offsets[0] = 0;
45  for (size_t i=0; i<features.size(); ++i)
46  offsets[i+1] = offsets[i] + features[i].dimension();
47 }
48 
50 matchNoExp(const StateInfo& state, Move move, const double * weights) const
51 {
52  MoveInfo info(state, move);
53  assert(offsets.size() == features.size()+1);
54  double sum = 0.0;
55  for (size_t i=0; i<features.size(); ++i) {
56  sum += features[i].match(state, info, offsets[i], weights);
57  }
58  return sum;
59 }
60 
62 matchExp(const StateInfo& state, Move move, const double * weights) const
63 {
64  return exp(matchNoExp(state, move, weights));
65 }
66 
68 matchLight(const StateInfo& state, Move move, const double * weights) const
69 {
70  MoveInfo info(state, move);
71  assert(offsets.size() == features.size()+1);
72  double sum = 0.0;
73  for (size_t i: light_features) {
74  sum += features[i].match(state, info, offsets[i], weights);
75  }
76  return sum;
77 }
78 
79 
81 analyze(const StateInfo& state, Move move, const double * weights) const
82 {
83  MoveInfo info(state, move);
84  std::cerr << csa::show(move) << "\n";
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);
88  if (s)
89  out.push_back(make_pair(s, features[i].name()));
90  }
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;
95  if (i % 3 == 2)
96  std::cerr << "\n";
97  }
98  if (out.size() % 3 != 0)
99  std::cerr << "\n";
100 }
101 
103 generateRating(const StateInfo& state, WeightedMoveVector& out,
104  const double * weights) const
105 {
106  assert(! state.dirty);
107  MoveVector moves;
108  state.state->generateLegal(moves);
109  double sum = 0.0;
110  FixedCapacityVector<Move,128> unpromote_moves;
111  for (Move move: moves) {
112  double score = matchExp(state, move, weights);
113  out.push_back(WeightedMove(score, move));
114  sum += score;
115  }
116  return sum;
117 }
118 
120 ratingToLogProb(const WeightedMoveVector& rating,
121  double sum, MoveLogProbVector& out)
122 {
123  static const double scale = 100.0 / log(0.5);
124  for (WeightedMove move: rating) {
125  double p = move.first/sum;
126  if (std::isnan(p) || p <= 1.0/(1<<12))
127  p = 1.0/(1<<12);
128  const int logp = std::max(50, static_cast<int>(log(p)*scale));
129  out.push_back(MoveLogProb(move.second, logp));
130  }
131  out.sortByProbability();
132 }
133 
135 generateLogProb(const StateInfo& state, MoveLogProbVector& out,
136  const double * weights) const
137 {
138  WeightedMoveVector moves;
139  double sum = generateRating(state, moves, weights);
140  ratingToLogProb(moves, sum, out);
141 }
142 
144 load(const char *base_filename, double * weights) const
145 {
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) {
150  is >> weights[i];
151  if (! is) {
152  std::cerr << "load failed at " << i << " in " << dimension()
153  << " file " << filename << "\n";
154  break;
155  }
156  }
157  return static_cast<bool>(is);
158 }
159 
161 load_binary(const char *base_filename, double * weights) const
162 {
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) {
168  if (! reader.hasNext()) {
169  std::cerr << "load failed at " << i << " in " << dimension()
170  << " file " << filename << "\n";
171  return false;
172  }
173  double value = reader.read();
174  weights[i] = value;
175  }
176  return true;
177 }
178 
180 showSummary(const double * weights) const
181 {
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;
187 #endif
188  int zero = 0;
189  for (int j=offsets[i]; j<offsets[i+1]; ++j)
190  if (weights[j]) {
191 #if (__GNUC_MINOR__ < 5)
192  acc(weights[j]);
193 #endif
194  }
195  else
196  ++zero;
197  std::cerr << std::setw(16) << f.name()
198  << " dim " << std::setw(5) << f.dimension() - zero
199  << "/" << std::setw(5) << f.dimension()
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)
204 #endif
205  << "\n";
206  }
207 }
208 
209 
210 
211 boost::scoped_array<double> osl::move_probability::
213 boost::scoped_array<double> osl::move_probability::
215 
217 StandardFeatureSet() : initialized(false)
218 {
219  pushBack(new TakeBackFeature, 1);
220  pushBack(new CheckFeature, 1);
221  pushBack(new SeeFeature, 1);
222  pushBack(new ContinueCapture, 1);
223  pushBack(new DropCaptured);
224  pushBack(new SquareY, 1);
225  pushBack(new SquareX, 1);
226  pushBack(new KingRelativeY, 1);
227  pushBack(new KingRelativeX, 1);
228  pushBack(new FromEffect, 1);
229  pushBack(new ToEffect, 1);
230  pushBack(new FromEffectLong, 1);
231  pushBack(new ToEffectLong, 1);
232  pushBack(new Pattern(0,-1)); // U
233  pushBack(new Pattern(1,-1)); // UL
234  pushBack(new Pattern(1,0)); // L
235  pushBack(new Pattern(0,1)); // D
236  pushBack(new Pattern(1,1)); // DL
237  pushBack(new Pattern(1,-2)); // UUL
238  pushBack(new Pattern(0,-2)); // UU
239  pushBack(new Pattern(0,2)); // DD
240  pushBack(new Pattern(2,0)); // LL
241  pushBack(new Pattern(1,2)); // DDL
244  pushBack(new PawnAttack);
245  pushBack(new CapturePtype, 1);
246  pushBack(new BlockLong);
247  pushBack(new BlockLongFrom);
248  pushBack(new LanceAttack);
249  pushBack(new BishopAttack);
250  pushBack(new RookAttack);
252  pushBack(new SendOff);
254  pushBack(new OpposingPawn);
256  pushBack(new LongRecapture);
258  pushBack(new AddEffectLong);
259  pushBack(new King5x5Ptype);
260  pushBack(new KingBlockade);
261  pushBack(new CoverFork);
263  pushBack(new LureDefender);
264  pushBack(new CoverPawn);
267  pushBack(new BookMove);
268  addFinished();
269 }
270 
273 {
274 }
275 
278 instance(bool verbose)
279 {
280  static StandardFeatureSet the_instance;
281  the_instance.setUp(verbose);
282  return the_instance;
283 }
284 
286 healthCheck()
287 {
288  return instance(true).ok();
289 }
290 
291 namespace osl
292 {
293  namespace move_probability
294  {
296  }
297 }
299 setUp(bool verbose)
300 {
301  std::lock_guard<std::mutex> lk(standardfeatureset_lock);
302  static bool initialized = false;
303  if (initialized)
304  return true;
305  initialized = true;
306  weights.reset(new double[dimension()]);
307  std::string filename = OslConfig::home();
308  filename += "/data/move-order";
309  if (verbose)
310  std::cerr << "loading " << filename << ".bin ";
311  const bool success = load_binary(filename.c_str(), &weights[0]);
312  if (verbose)
313  std::cerr << (success ? "success" : "failed\a") << "\n";
314 
315  filename = OslConfig::home();
316  filename += "/data/move-tactical.txt";
317  const int tactical_dimension = 8*4;
318  tactical_weights.reset(new double[tactical_dimension]);
319  if (verbose)
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];
324  if (verbose)
325  std::cerr << (is ? "success" : "failed\a") << "\n";
326  this->initialized = success && is;
327  return this->initialized;
328 }
329 
331 generateLogProb(const StateInfo& state, MoveLogProbVector& out) const
332 {
333  FeatureSet::generateLogProb(state, out, &weights[0]);
334 }
335 
337 generateLogProb2(const StateInfo& state, MoveLogProbVector& out) const
338 {
339  WeightedMoveVector moves;
340  double sum = FeatureSet::generateRating(state, moves, &weights[0]);
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) {
344  WeightedMove move = moves[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))
350  p = 1.0/(1<<12);
351  else
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);
358  out.push_back(MoveLogProb(move.second, logp));
359  elapsed += move.first;
360  welapsed = (welapsed+move.first)*(moves.size()-i)/moves.size();
361  }
362 }
363 
365 generateLogProb(const StateInfo& state, int /*limit*/, MoveLogProbVector& out, bool /*in_pv*/) const
366 {
367  generateLogProb2(state, out);
368 }
369 
371 matchLight(const StateInfo& state, Move move) const
372 {
373  return FeatureSet::matchLight(state, move, &weights[0]);
374 }
375 
377 matchExp(const StateInfo& state, Move move) const
378 {
379  return FeatureSet::matchExp(state, move, &weights[0]);
380 }
381 
383 matchNoExp(const StateInfo& state, Move move) const
384 {
385  return FeatureSet::matchNoExp(state, move, &weights[0]);
386 }
387 
389 logProbTakeBack(const StateInfo& state, Move target) const
390 {
391  const int progress8 = state.progress8();
392  const double sum = matchLight(state, target);
393  return tacticalLogProb(progress8*4 + 0, sum);
394 }
395 
397 logProbSeePlus(const StateInfo& state, Move target) const
398 {
399  const int progress8 = state.progress8();
400  const double sum = matchLight(state, target);
401  return tacticalLogProb(progress8*4 + 2, sum);
402 }
403 
405 tacticalLogProb(int offset, double sum) const
406 {
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));
411 }
412 
413 
414 
415 
416 // ;;; Local Variables:
417 // ;;; mode:c++
418 // ;;; c-basic-offset:2
419 // ;;; End:
420 
osl::move_probability::FeatureSet::matchNoExp
double matchNoExp(const StateInfo &, Move, const double *weights) const
Definition: featureSet_.cc:50
osl::move_probability::LongRecapture
Definition: move_probability/feature.h:804
osl::move_probability::StandardFeatureSet::instance
static const StandardFeatureSet & instance(bool verbose=false)
Definition: featureSet_.cc:278
osl::move_probability::PawnAttack
Definition: move_probability/feature.h:638
osl::move_probability::StandardFeatureSet::StandardFeatureSet
StandardFeatureSet()
Definition: featureSet_.cc:217
osl::move_probability::FeatureSet::analyze
void analyze(const StateInfo &state, Move move, const double *weights) const
Definition: featureSet_.cc:81
csa.h
osl::misc::BinaryElementReader::hasNext
bool hasNext() const
Definition: binaryIO.cc:151
osl::move_probability::King5x5Ptype
Definition: move_probability/feature.h:1428
osl::move_probability::FeatureSet::load
bool load(const char *base_filename, double *weights) const
Definition: featureSet_.cc:144
osl::move_probability::StandardFeatureSet::tactical_weights
static boost::scoped_array< double > tactical_weights
Definition: move_probability/featureSet.h:52
osl::move_probability::StandardFeatureSet::matchLight
double matchLight(const StateInfo &, Move) const
Definition: featureSet_.cc:371
osl::move_probability::FeatureSet::ratingToLogProb
static void ratingToLogProb(const WeightedMoveVector &rating, double sum, MoveLogProbVector &out)
Definition: featureSet_.cc:120
osl::eval::min
int min(Player p, int v1, int v2)
Definition: evalTraits.h:92
osl::move_probability::FeatureSet::~FeatureSet
~FeatureSet()
Definition: featureSet_.cc:28
osl::move_probability::CheckFeature
Definition: move_probability/feature.h:41
osl::FixedCapacityVector::size
size_t size() const
Definition: container.h:243
osl::move_probability::TakeBackFeature
Definition: move_probability/feature.h:75
osl::move_probability::SquareY
Definition: move_probability/feature.h:187
osl::move_probability::StandardFeatureSet::matchNoExp
double matchNoExp(const StateInfo &, Move) const
Definition: featureSet_.cc:383
osl::move_probability::AddEffectLong
Definition: move_probability/feature.h:834
osl::move_probability::StateInfo::dirty
bool dirty
Definition: stateInfo.h:45
osl::move_probability::StandardFeatureSet
Definition: move_probability/featureSet.h:51
osl::move_probability::StandardFeatureSet::matchExp
double matchExp(const StateInfo &, Move) const
Definition: featureSet_.cc:377
osl::move_probability::Feature::name
std::string name() const
Definition: move_probability/feature.h:26
osl::move_probability::FeatureSet::matchLight
double matchLight(const StateInfo &, Move, const double *weights) const
Definition: featureSet_.cc:68
osl::move_probability::SendOff
Definition: move_probability/feature.h:1145
osl::move_probability::Feature
Definition: move_probability/feature.h:17
osl::move_probability::FeatureSet::features
boost::ptr_vector< Feature > features
Definition: move_probability/featureSet.h:23
osl::move_probability::ToEffect
Definition: move_probability/feature.h:351
osl::move_probability::StandardFeatureSet::tacticalLogProb
int tacticalLogProb(int offset, double sum) const
Definition: featureSet_.cc:405
osl::move_probability::WeightedMove
std::pair< double, Move > WeightedMove
Definition: move_probability/featureSet.h:17
osl::move_probability::DropCaptured
取った駒をすぐ使う
Definition: move_probability/feature.h:170
osl::move_probability::FromEffect
Definition: move_probability/feature.h:330
osl::move_probability::FeatureSet::showSummary
void showSummary(const double *weights) const
Definition: featureSet_.cc:180
osl::Move
х軒 move茵 .
Definition: basic_type.h:1052
osl::move_probability::CapturePtype
Definition: move_probability/feature.h:131
osl::move_probability::RookAttack
Definition: move_probability/feature.h:998
osl::move_probability::LanceAttack
Definition: move_probability/feature.h:868
osl::MoveLogProb
Definition: moveLogProb.h:10
osl::move_probability::Pattern
PatternBase< false > Pattern
Definition: move_probability/feature.h:558
osl::move_probability::BookMove
Definition: move_probability/feature.h:1741
osl::move_probability::MoveFromOpposingSliders
Definition: move_probability/feature.h:562
featureSet.h
osl::csa::show
const std::string show(Move)
Definition: csa.cc:133
osl::move_probability::SquareX
Definition: move_probability/feature.h:218
osl::move_probability::BlockLong
Definition: move_probability/feature.h:701
osl::move_probability::StateInfo
Definition: stateInfo.h:21
osl::FixedCapacityVector
Definition: container.h:137
osl::FixedCapacityVector::begin
iterator begin()
Definition: container.h:198
osl::move_probability::StandardFeatureSet::logProbTakeBack
int logProbTakeBack(const StateInfo &state, Move target) const
Definition: featureSet_.cc:389
osl::container::MoveLogProbVector::sortByProbability
void sortByProbability()
腆榊蕭sort
Definition: moveLogProbVector.cc:48
osl::move_probability::MoveInfo
Definition: moveInfo.h:14
binaryIO.h
osl::eval::max
int max(Player p, int v1, int v2)
Definition: evalTraits.h:84
osl::move_probability::ThreatmateByCapture
Definition: move_probability/feature.h:1583
osl::move_probability::BishopAttack
Definition: move_probability/feature.h:921
osl::move_probability::StateInfo::state
const NumEffectState * state
Definition: stateInfo.h:22
osl::move_probability::StandardFeatureSet::logProbSeePlus
int logProbSeePlus(const StateInfo &state, Move target) const
Definition: featureSet_.cc:397
osl::move_probability::EscapeThreatened
Definition: move_probability/feature.h:1689
osl::move_probability::DropAfterOpposingPawn
Definition: move_probability/feature.h:1319
osl::move_probability::StandardFeatureSet::setUp
bool setUp(bool verbose=false)
Definition: featureSet_.cc:299
osl::move_probability::LureDefender
Definition: move_probability/feature.h:1162
container.h
osl::container::MoveLogProbVector::push_back
void push_back(Move move, int prob)
Definition: moveLogProbVector.h:29
osl::move_probability::CoverFork
Definition: move_probability/feature.h:1533
osl::FixedCapacityVector::end
iterator end()
Definition: container.h:199
osl::move_probability::CoverPawn
Definition: move_probability/feature.h:1357
osl::move_probability::FeatureSet::generateRating
double generateRating(const StateInfo &state, WeightedMoveVector &out, const double *weights) const
Definition: featureSet_.cc:103
osl::move_probability::PromotionBySacrifice
Definition: move_probability/feature.h:1611
osl::move_probability::StandardFeatureSet::generateLogProb
void generateLogProb(const StateInfo &state, MoveLogProbVector &out) const
Definition: featureSet_.cc:331
osl::move_probability::KingRelativeX
Definition: move_probability/feature.h:284
osl::OslConfig::home
static const std::string & home(const std::string &initialize_if_first_invocation="")
compile絎c菴.
Definition: oslConfig.cc:239
oslConfig.h
osl::misc::BinaryElementReader
Definition: binaryIO.h:34
osl::container::MoveLogProbVector
Definition: moveLogProbVector.h:14
osl::move_probability::SacrificeAttack
Definition: move_probability/feature.h:1397
osl::move_probability::KingBlockade
Definition: move_probability/feature.h:1464
osl::move_probability::StandardFeatureSet::generateLogProb2
void generateLogProb2(const StateInfo &state, MoveLogProbVector &out) const
Definition: featureSet_.cc:337
osl::move_probability::FeatureSet::matchExp
double matchExp(const StateInfo &, Move, const double *weights) const
Definition: featureSet_.cc:62
feature.h
osl::move_probability::Feature::dimension
size_t dimension() const
Definition: move_probability/feature.h:28
osl::move_probability::BreakThreatmate
Definition: move_probability/feature.h:1023
osl::move_probability::SeeFeature
Definition: move_probability/feature.h:96
osl::move_probability::StateInfo::progress8
int progress8() const
Definition: stateInfo.h:92
osl::move_probability::FromEffectLong
Definition: move_probability/feature.h:407
osl::move_probability::ToEffectLong
Definition: move_probability/feature.h:440
osl::move_probability::ContinueCapture
Definition: move_probability/feature.h:155
osl::move_probability::CheckmateIfCapture
Definition: move_probability/feature.h:1224
osl::MoveVector
Definition: container.h:293
osl::move_probability::AttackToOpposingSliders
Definition: move_probability/feature.h:614
osl::move_probability::FeatureSet::generateLogProb
void generateLogProb(const StateInfo &state, MoveLogProbVector &out, const double *weights) const
Definition: featureSet_.cc:135
osl::move_probability::FeatureSet::addFinished
void addFinished()
Definition: featureSet_.cc:41
osl::move_probability::StandardFeatureSet::weights
static boost::scoped_array< double > weights
Definition: move_probability/featureSet.h:52
osl::NumEffectState::generateLegal
void generateLegal(MoveVector &) const
羈.
Definition: numEffectState.cc:1086
osl::move_probability::OpposingPawn
Definition: move_probability/feature.h:1286
osl::move_probability::BlockLongFrom
Definition: move_probability/feature.h:782
osl::move_probability::standardfeatureset_lock
std::mutex standardfeatureset_lock
Definition: featureSet_.cc:295
osl::move_probability::FeatureSet::offsets
std::vector< int > offsets
Definition: move_probability/featureSet.h:24
osl::misc::BinaryElementReader::read
T read()
Definition: binaryIO.cc:162
osl::move_probability::KingRelativeY
Definition: move_probability/feature.h:248
osl::move_probability::StandardFeatureSet::healthCheck
static bool healthCheck()
Definition: featureSet_.cc:286
osl::move_probability::StandardFeatureSet::~StandardFeatureSet
~StandardFeatureSet()
Definition: featureSet_.cc:272
osl::FixedCapacityVector::push_back
void push_back(const T &e)
Definition: container.h:204
osl::move_probability::FeatureSet::FeatureSet
FeatureSet()
Definition: featureSet_.cc:23
osl::move_probability::FeatureSet::load_binary
bool load_binary(const char *base_filename, double *weights) const
Definition: featureSet_.cc:161
osl
Definition: additionalEffect.h:6
osl::move_probability::FeatureSet::pushBack
void pushBack(Feature *, bool light=false)
Definition: featureSet_.cc:33