My Project
featureSet.cc
Go to the documentation of this file.
1 /* featureSet.cc
2  */
4 #include "osl/config.h"
5 #include "osl/rating/group.h"
18 #include "osl/stat/variance.h"
19 #include "osl/oslConfig.h"
20 #include <boost/format.hpp>
21 #include <map>
22 #include <iostream>
23 #include <fstream>
24 #include <sstream>
25 #include <iomanip>
26 #include <stdexcept>
27 #include <cmath>
28 
29 // statistics for each feature
30 // #define RATING_STAT
31 // show statistics loaded for each feature
32 // #define VERBOSE_RATING
33 // statistics between rating and limit
34 // #define RATING_STAT2
35 
36 const int MinRating = -4000;
37 
39 {
45  average(0), variance(0), probability(0)
46  {
47  }
48 };
49 
50 
53  : capture_group(-1), checkmate_if_capture_group(-1), sendoff_group(-1)
54 {
55 }
56 
59 {
60 #ifdef RATING_STAT
61  showStatistics(std::cerr);
62 #endif
63 }
64 
66 FeatureSet::makeRange(size_t group) const
67 {
68  int first = 0;
69  for (size_t i=0; i<groups.size(); ++i) {
70  if (i == group)
71  return std::make_pair(first, first+groups[i].size());
72  first += groups[i].size();
73  }
74  assert(0);
75  abort();
76 }
77 
80 {
81  assert(normal_groups.size() == groups.size());
82  weights.resize(features.size(), 1.0);
83  weightslog10.resize(features.size(), 1);
84  assert(weights.size() == features.size());
85  ranges.resize(groups.size());
86  for (size_t i=0; i<groups.size(); ++i)
87  ranges[i] = makeRange(i);
88  variance_match.resize(groups.size());
89  variance_all.resize(groups.size());
90  frequency.resize(groups.size());
91  statistics.resize(groups.size());
92 }
93 
96 {
97  add(new Group(f));
98 }
99 
102 {
103  features.reserve(features.size()+g->size());
104  for (size_t i=0; i<g->size(); ++i) {
105  features.push_back(&(*g)[i]);
106  }
107  groups.push_back(g);
108  effective_in_check.push_back(g->effectiveInCheck());
109 }
110 
113 {
114  normal_groups.push_back(true);
115  addCommon(g);
116 }
117 
120 {
121  capture_group = normal_groups.size();
122  normal_groups.push_back(false);
123  addCommon(g);
124 }
125 
128 {
129  sendoff_group = normal_groups.size();
130  normal_groups.push_back(false);
131  addCommon(g);
132 }
133 
136 {
137  checkmate_if_capture_group = normal_groups.size();
138  normal_groups.push_back(false);
139  addCommon(g);
140 }
141 
143 FeatureSet::tryLoad(const std::string& input_directory)
144 {
145  bool result = true;
146  for (size_t i=0; i<groups.size(); ++i) {
147  const bool success = groups[i].load(input_directory, ranges[i], weights);
148  if (! success && result)
149  std::cerr << "warning: rating load failed " << groups[i].group_name << " " << i
150  << " in " << input_directory << "\n";
151  result &= success;
152  }
153  for (size_t i=0; i<features.size(); ++i)
154  weightslog10[i] = static_cast<int>(400*log10(weights[i]));
155 #ifndef RATING_STAT
156  std::string filename = input_directory + "/statistics.txt";
157  std::ifstream is(filename.c_str());
158  typedef std::map<std::string,Statistics> map_t;
159  map_t table;
160  std::string name;
161  double a, s, p, dummy;
162  while (is >> name >> a >> s >> dummy >> dummy >> p) {
163  Statistics& stat = table[name];
164  stat.average = a;
165  stat.variance = s*s;
166  stat.probability = p;
167  }
168  for (size_t i=0; i<groups.size(); ++i) {
169  double a = 0.0, v = 0.0;
170  for (size_t j=i+1; j<groups.size(); ++j) {
171  map_t::iterator q = table.find(groups[j].group_name);
172  if (q == table.end()) {
173  result = false;
174  break;
175  }
176  a += q->second.probability * q->second.average;
177  v += q->second.probability * q->second.variance;
178  }
179  statistics[i] = table[groups[i].group_name];
180  statistics[i].average_after = static_cast<int>(a);
181  statistics[i].sigma_after = static_cast<int>(sqrt(v)*3);
182 # ifdef VERBOSE_RATING
183  std::cerr << groups[i].group_name
184  << " " << statistics[i].average_after
185  << " " << statistics[i].sigma_after << "\n";
186 # endif
187  }
188 #endif
189  return result;
190 }
191 
193 FeatureSet::setWeight(size_t feature_id, const double& value)
194 {
195  weights[feature_id] = value;
196  weightslog10[feature_id] = static_cast<int>(400*log10(value));
197 }
198 
200 FeatureSet::generateRating(const NumEffectState& state, const RatingEnv& env,
201  int limit, RatedMoveVector& out, bool in_pv_or_all) const
202 {
203 #if (defined RATING_STAT) || (defined RATING_STAT2)
204  in_pv_or_all = true;
205 #endif
206  MoveVector moves;
207  const bool in_check = state.inCheck();
208  // generate legal moves except for pawn drop checkmate
209  if (in_check)
210  GenerateEscapeKing::generate(state, moves);
211  else
212  GenerateAllMoves::generate(state.turn(), state, moves);
213 
214  for (size_t i=0; i<moves.size(); ++i) {
215  if (moves[i].ptype() == KING) {
216  if (state.hasEffectAt(alt(state.turn()), moves[i].to()))
217  continue;
218  } else {
219  if (! in_check && env.my_pin.any() && ! moves[i].isDrop()
221  continue;
222  }
223 
224  if (in_pv_or_all)
225  out.push_back(makeRate(state, in_check, env, moves[i]));
226  else {
227  RatedMove r = makeRateWithCut(state, in_check, env, limit, moves[i]);
228  if (r.rating() > MinRating)
229  out.push_back(r);
230  }
231  }
232  out.sort();
233 }
234 
235 // width 4, [0,80]
237  186, 213, 243, 247, 249, 255, 252, 258, 263, 269, 267, 279, 295, 295, 295, 295, 295, 295, 295, 295,
238  191, 245, 283, 300, 313, 315, 319, 323, 326, 339, 321, 347, 334, 346, 328, 368, 328, 328, 328, 328,
239  183, 250, 304, 328, 346, 352, 373, 366, 365, 379, 396, 379, 392, 416, 420, 374, 423, 378, 395, 399,
240  184, 253, 312, 346, 358, 378, 389, 407, 409, 403, 404, 421, 432, 395, 421, 444, 444, 461, 411, 408,
241  190, 256, 319, 350, 373, 397, 397, 403, 420, 431, 415, 450, 424, 416, 436, 447, 456, 439, 429, 428,
242  197, 262, 324, 357, 374, 390, 407, 423, 415, 425, 436, 444, 458, 455, 439, 474, 451, 466, 464, 457,
243  202, 268, 332, 360, 381, 386, 416, 416, 418, 433, 447, 446, 452, 462, 479, 468, 467, 486, 483, 459,
244  205, 270, 330, 361, 383, 394, 410, 418, 427, 438, 438, 452, 446, 445, 447, 463, 475, 472, 483, 485,
245 }};
247  262, 445, 584, 685, 788, 890, 982,1067,1120,1148, 1137,1156,1182,1231,1259, 1343,1352,1359,1359,1359,
248  265, 456, 577, 665, 745, 809, 874, 938, 997,1061, 1088,1154,1179,1231,1259, 1343,1352,1359,1359,1359,
249  260, 467, 596, 680, 751, 807, 872, 908, 951,1003, 1054,1072,1117,1168,1198, 1188,1267,1259,1311,1344,
250  261, 467, 599, 688, 747, 810, 861, 914, 948, 975, 1008,1055,1092,1084,1142, 1189,1214,1254,1231,1258,
251  264, 463, 595, 679, 746, 808, 844, 885, 933, 973, 987,1049,1048,1068,1115, 1151,1184,1191,1209,1233,
252  268, 459, 588, 673, 732, 788, 840, 887, 910, 950, 989,1022,1059,1078,1088, 1144,1144,1180,1201,1216,
253  271, 459, 587, 664, 727, 771, 835, 866, 899, 942, 984,1006,1037,1069,1105, 1114,1134,1173,1188,1186,
254  272, 458, 581, 661, 725, 773, 824, 863, 902, 940, 966,1005,1023,1047,1074, 1113,1145,1163,1193,1214,
255 }};
256 
257 const int sc_width = 100, sc_length = 18, sc_start = -400;
259  263, 271, 274, 270, 278, 253, 235, 201, 171, 151, 111, 95, 83, 76, 78, 65, 71, 61,
260  330, 334, 328, 316, 312, 304, 284, 256, 218, 188, 159, 136, 113, 103, 92, 87, 82, 71,
261  377, 374, 376, 368, 356, 337, 311, 278, 246, 203, 175, 146, 131, 118, 107, 96, 81, 65,
262  415, 424, 406, 396, 376, 345, 315, 276, 243, 211, 179, 155, 138, 121, 110, 91, 80, 62,
263  423, 422, 433, 423, 405, 381, 341, 313, 276, 243, 210, 182, 158, 142, 123, 104, 85, 73,
264  442, 451, 448, 437, 417, 395, 364, 333, 297, 267, 234, 202, 178, 158, 133, 107, 91, 76,
265  446, 447, 455, 439, 427, 402, 373, 339, 307, 274, 242, 212, 188, 162, 133, 111, 92, 75,
266  467, 468, 469, 453, 433, 412, 389, 365, 334, 301, 268, 236, 205, 177, 153, 131, 116, 101,
267 }};
269  978, 880, 786, 676, 586, 475, 383, 302, 239, 208, 167, 153, 134, 127, 126, 100, 100, 82,
270  1020, 935, 836, 730, 634, 549, 472, 412, 351, 312, 269, 232, 190, 167, 143, 127, 112, 95,
271  1095, 998, 910, 810, 715, 623, 543, 471, 407, 338, 291, 246, 216, 189, 160, 140, 115, 90,
272  1106,1031, 929, 829, 730, 635, 551, 469, 402, 341, 290, 249, 217, 186, 159, 127, 108, 85,
273  1185,1092, 1011, 913, 811, 717, 617, 538, 459, 391, 331, 285, 242, 210, 176, 143, 114, 96,
274  1224,1150, 1058, 957, 853, 755, 658, 573, 493, 424, 363, 308, 262, 223, 181, 142, 116, 96,
275  1224,1134, 1057, 953, 857, 759, 666, 579, 501, 432, 373, 315, 267, 220, 178, 141, 115, 93,
276  1296,1201, 1115,1009, 904, 807, 717, 638, 563, 492, 425, 363, 305, 254, 210, 172, 145, 123,
277 }};
278 
279 const int rsc_length = 15;
281  193, 220, 235, 249, 256, 263, 268, 274, 279, 284, 283, 279, 292, 267, 272,
282  220, 243, 263, 273, 287, 300, 306, 308, 317, 325, 328, 339, 319, 336, 323,
283  215, 242, 267, 287, 302, 314, 329, 340, 347, 360, 367, 364, 349, 387, 374,
284  209, 243, 267, 293, 317, 332, 347, 360, 372, 383, 387, 387, 395, 398, 405,
285  216, 244, 276, 303, 322, 344, 360, 374, 378, 397, 405, 414, 408, 400, 424,
286  220, 251, 278, 307, 331, 355, 365, 381, 398, 406, 418, 423, 414, 433, 403,
287  226, 254, 284, 311, 336, 354, 378, 390, 408, 418, 420, 448, 414, 446, 408,
288  219, 250, 283, 310, 333, 356, 377, 391, 403, 417, 426, 426, 440, 445, 452,
289 }};
291  214, 285, 357, 442, 520, 596, 669, 742, 816, 881, 928, 972,1045,1079,1143,
292  237, 302, 374, 442, 519, 595, 662, 731, 799, 870, 925, 994,1031,1112,1159,
293  230, 294, 367, 442, 517, 595, 675, 746, 815, 884, 951,1012,1060,1149,1185,
294  224, 292, 361, 441, 524, 602, 682, 758, 833, 904, 964,1028,1105,1164,1223,
295  231, 295, 369, 449, 525, 611, 692, 771, 839, 922, 985,1041,1094,1150,1239,
296  235, 301, 370, 450, 532, 616, 690, 769, 851, 920, 991,1054,1100,1194,1217,
297  240, 300, 373, 448, 527, 607, 693, 768, 845, 919, 981,1066,1094,1191,1218,
298  233, 294, 364, 435, 511, 591, 674, 753, 832, 917, 993,1065,1157,1224,1300,
299 }};
300 
301 inline int make_prob(int score, int order, int limit, int highest, int progress8, bool in_pv_or_all)
302 {
303  const int order_index = std::min((int)order/4, 19);
304  int result = limit+1;
305  if (order_to_width[progress8][order_index] <= limit) {
306  result = (order == 0) ? 100 : order_to_depth[progress8][order_index];
307  }
308  score = std::max(sc_start, score);
309  highest = std::max(sc_start, highest);
310  const int score_index = std::min((score - sc_start)/sc_width, sc_length-1);
311  if (limit > 600 && score_to_width[progress8][score_index] <= limit) {
312  result = std::min(result, score_to_depth[progress8][score_index]);
313  }
314  if (limit > 700 && order > 0 && in_pv_or_all) {
315  const int rscore_index = std::min((highest - score)/100, rsc_length-1);
316  assert(rscore_index >= 0);
317  if (relative_score_to_width[progress8][rscore_index] <= limit)
318  result = std::min(result, relative_score_to_depth[progress8][rscore_index]);
319  }
320  return result;
321 }
322 
323 #ifdef RATING_STAT2
324 namespace osl
325 {
326  namespace
327  {
328  CArray2d<CArray<stat::Average,8>,14,40> data; // selected/generated for each range
329  CArray2d<CArray<double,8>,14,80> selected_all;
330  void add_stat(int limit, int rating, bool added, int progress8)
331  {
332  limit = std::min(limit, 999);
333  limit -= 300;
334  limit = std::max(limit, 0);
335  rating = std::max(-999,rating);
336  rating = std::min(999,rating);
337  data[limit/50][(rating+1000)/50][progress8].add(added);
338  if (added)
339  selected_all[limit/50][(rating+1000)/25][progress8] += 1.0;
340  }
341  struct Reporter
342  {
343  ~Reporter()
344  {
345  std::cerr << "limit " << 0*50+300 << " - " << (data.size1()-1)*50+300 << "\n";
346  for (int p=0; p<8; ++p)
347  {
348  std::cerr << "progress8 " << p << "\n ";
349  for (size_t j=0; j<data.size1(); ++j)
350  {
351  size_t i=0;
352  for (; i<data.size2(); ++i)
353  if (data[j][i][p].getAverage() > 0.05)
354  break;
355  std::cerr << (boost::format("%+4d, ") % static_cast<int>(i)*50-1000);
356  }
357  std::cerr << "\n";
358  }
359  std::cerr << "limit " << 0*50+300 << " - " << (selected_all.size1()-1)*50+300 << "\n";
360  CArray<double, 3> prob = {{ 0.01, 0.03, 0.05 }};
361  for (size_t pp=0; pp<prob.size(); ++pp) {
362  std::cerr << "prob " << prob[pp] << "\n";
363  for (int p=0; p<8; ++p)
364  {
365  std::cerr << "progress8 " << p << "\n ";
366  for (size_t j=0; j<selected_all.size1(); ++j)
367  {
368  double sum = 0;
369  for (size_t i=0; i<selected_all.size2(); ++i)
370  sum += selected_all[j][i][p];
371  size_t i=0
372  for (double so_far = 0; i<selected_all.size2(); ++i) {
373  so_far += selected_all[j][i][p];
374  if (so_far > prob[pp]*sum)
375  break;
376  }
377  std::cerr << (boost::format("%+4d, ") % static_cast<int>(i)*25-1000);
378  }
379  std::cerr << "\n";
380  }
381  }
382  }
383  } _reporter;
384  }
385 }
386 #endif
387 
389 FeatureSet::generateLogProb(const NumEffectState& state, const RatingEnv& env,
390  int limit, MoveLogProbVector& out, bool in_pv_or_all) const
391 {
392  RatedMoveVector score;
393  generateRating(state, env, limit, score, in_pv_or_all);
394  if (score.empty())
395  return;
396 
397  const int highest = score[0].rating();
398  const int progress8 = env.progress.value()/2;
399  for (size_t i=0; i<score.size(); ++i) {
400  const int log_prob = make_prob(score[i].rating(), i, limit, highest, progress8, in_pv_or_all);
401 #ifdef RATING_STAT2
402  add_stat(limit, score[i].rating(), log_prob <= limit, progress8);
403 #endif
404  out.push_back(MoveLogProb(score[i].move(), log_prob));
405  }
406 }
407 
408 const int max_score = 999, min_score = 0;
410  223, 204, 208, 190, 159, 137, 124, 110, 100, 89
411 }};
413  356, 337, 296, 262, 230, 200, 171, 148, 132, 120,
414 }};
416  203, 201, 199, 188, 181, 169, 159, 147, 136, 122,
417 }};
418 
420 FeatureSet::logProbTakeBack(const NumEffectState& state, const RatingEnv& env, Move move) const
421 {
422  const bool in_check = state.inCheck();
423  const int score = makeRate(state, in_check, env, move).rating();
424  if (score >= 1000) {
425  const int score_index = std::min((score - sc_start)/sc_width, sc_length-1);
426  return score_to_depth[env.progress.value()/2][score_index];
427  }
429 }
431 FeatureSet::logProbSeePlus(const NumEffectState& state, const RatingEnv& env,
432  Move move) const
433 {
434  const bool in_check = state.inCheck();
435  const int score = makeRate(state, in_check, env, move).rating();
436  if (score >= 1000) {
437  const int score_index = std::min((score - sc_start)/sc_width, sc_length-1);
438  return score_to_depth[env.progress.value()/2][score_index];
439  }
441 }
444  Move move) const
445 {
446  const bool in_check = state.inCheck();
447  const int score = makeRate(state, in_check, env, move).rating();
448  if (score >= 1000) {
449  const int score_index = std::min((score - sc_start)/sc_width, sc_length-1);
450  return score_to_depth[env.progress.value()/2][score_index];
451  }
452  const int prob = score_to_depth_kingescape[std::max(min_score, std::min(max_score, score))/100];
453  assert(prob > 0);
454  return prob;
455 }
456 
458 FeatureSet::rating(const NumEffectState& state,
459  const RatingEnv& env, Move move, size_t group_id) const
460 {
461  int found = groups[group_id].findMatch(state, move, env);
462  if (found < 0) {
463 #ifdef RATING_STAT
464  const int progress8 = env.progress.value()/2;
465  frequency[group_id][progress8].add(0);
466  variance_all[group_id].add(0);
467 #endif
468  return 0;
469  }
470  found += ranges[group_id].first;
471 #ifdef RATING_STAT
472  const int progress8 = env.progress.value()/2;
473  frequency[group_id][progress8].add(1);
474  variance_match[group_id][progress8].add(weightslog10[found]);
475  variance_all[group_id].add(weightslog10[found]);
476 #endif
477  return weightslog10[found];
478 }
479 
481 FeatureSet::makeRate(const NumEffectState& state, bool in_check,
482  const RatingEnv& env, Move move) const
483 {
484  int sum = 0;
485  for (size_t j=0; j<groups.size(); ++j) {
486  if (! normal_groups[j])
487  continue;
488  if (in_check && ! effectiveInCheck(j))
489  continue;
490  sum += rating(state, env, move, j);
491  }
492  int capture = 0;
493  if (capture_group >= 0)
494  capture = rating(state, env, move, capture_group);
495  int checkmate_if_capture = 0;
496  if (checkmate_if_capture_group >= 0)
497  checkmate_if_capture = rating(state, env, move, checkmate_if_capture_group);
498  sum += checkmate_if_capture;
499  int sendoff = 0;
500  if (sendoff_group >= 0)
501  sendoff = rating(state, env, move, sendoff_group);
502  sum += sendoff;
503 
504  if (checkmate_if_capture > 0)
505  capture = std::max(0, capture);
506  else if (sendoff > 0 && capture < 0)
507  capture /= 2;
508  const int optimistic = sum + std::max(0, capture);
509  sum += capture;
510 
511  return RatedMove(move, sum, optimistic);
512 }
513 
514 
515 // limit [0-800)
516 #if 1
517 // 1%
519  0, 0, 0, 0, 0, 0,
520  100, 100, 50, 0, 0, -75,-100,-150,-200,-200,
521 
522  0, 0, 0, 0, 0, 0,
523  125, 125, 125, 25, 25, -50, -50,-100,-125,-225,
524 
525  0, 0, 0, 0, 0, 0,
526  100, 75, 100, 25, 0, -25, -50,-100,-125,-175,
527 
528  0, 0, 0, 0, 0, 0,
529  75, 50, 75, 0, -25, -25, -75,-100,-125,-200,
530 
531  0, 0, 0, 0, 0, 0,
532  125, 125, 150, 50, 50, 50, -25, 0, -50,-200,
533 
534  0, 0, 0, 0, 0, 0,
535  175, 200, 200, 75, 75, 75, 0, 0,-175,-300,
536 
537  0, 0, 0, 0, 0, 0,
538  175, 175, 200, 50, 75, 75, 25, 0,-100,-250,
539 
540  0, 0, 0, 0, 0, 0,
541  225, 200, 225, 75, 100, 75, 50, 0, 0,-250,
542 }};
543 #endif
544 #if 0
545 static const osl::CArray2d<int,8,16> threshold = {{
546  // 0, 50, 100, 150, 200, ...
547  0, 0, 0, 0, 0, 0,
548  100,100,100,0,0,-100,-100,-200,-200,-200,
549 
550  0, 0, 0, 0, 0, 0,
551  100,100,100,0,0,-100,-100,-100,-100,-200,
552 
553  0, 0, 0, 0, 0, 0,
554  100,100,100,0,0,0,-100,-100,-100,-200
555 
556  0, 0, 0, 0, 0, 0,
557  100,100,100,0,0,0,-100,-100,-100,-200
558 
559  0, 0, 0, 0, 0, 0,
560  200,200,200,100,100,100,0,0,0,-100
561 
562  0, 0, 0, 0, 0, 0,
563  300,300,300,100,100,100,100,0,-200,-300
564 
565  0, 0, 0, 0, 0, 0,
566  300,300,300,100,100,100,100,0,0,-200
567 
568  0, 0, 0, 0, 0, 0,
569  300,300,300,100,200,200,100,0,0,-200
570 }};
571 #endif
574  bool in_check,
575  const RatingEnv& env,
576  int limit, Move move) const
577 {
578  if (limit >= 800)
579  return makeRate(state, in_check, env, move);
580 
581  limit /= 50;
582  int sum = 0;
583  int capture = 0;
584  int checkmate_if_capture = 0;
585  const int progress8 = env.progress.value()/2;
586  for (size_t j=0; j<groups.size(); ++j) {
587  if (in_check && ! effectiveInCheck(j))
588  continue;
589  const int r = rating(state, env, move, j);
590  sum += r;
591  if ((int)j == capture_group) {
592  capture = r;
593  }
594  else if ((int)j == checkmate_if_capture_group) {
595  checkmate_if_capture = r;
596  if (checkmate_if_capture > 0 && capture < 0) {
597  sum -= capture;
598  capture = 0;
599  }
600  }
601  // cut?
602  if (j % 8 == 7) {
603  int sigma = statistics[j].sigma_after;
604  if (sum + statistics[j].average_after + sigma < threshold[progress8][limit]) {
605  return RatedMove(move, MinRating, MinRating);
606  }
607  }
608  }
609 
610  const int optimistic = sum + std::max(0, capture);
611  return RatedMove(move, sum, optimistic);
612 }
613 
614 const std::string osl::rating::
616  const RatingEnv& env, Move move) const
617 {
618  const bool in_check = state.inCheck();
619  std::vector<std::pair<int, std::string> > values;
620  for (size_t j=0; j<groups.size(); ++j) {
621  if (in_check && ! effectiveInCheck(j))
622  continue;
623  int found = groups[j].findMatch(state, move, env);
624  if (found < 0)
625  continue;
626  found += ranges[j].first;
627  values.push_back(std::make_pair(weightslog10[found], groups[j].group_name));
628  }
629  std::sort(values.begin(), values.end());
630  std::reverse(values.begin(), values.end());
631  std::ostringstream ss;
632  for (size_t i=0; i<values.size(); ++i) {
633  if (i)
634  ss << " ";
635  ss << values[i].second << " " << values[i].first;
636  }
637  return ss.str();
638 }
639 
640 #ifndef MINIMAL
642 FeatureSet::showGroup(std::ostream& os, size_t group_id) const
643 {
644  os << std::setprecision(3);
645  group(group_id).show(os, 12, range(group_id), weights);
646 }
647 
649 FeatureSet::save(const std::string& output_directory, size_t group_id) const
650 {
651  group(group_id).saveResult(output_directory, range(group_id), weights);
652 }
653 
655 FeatureSet::showStatistics(std::ostream& os) const
656 {
657  os << std::setprecision(3);
658  for (size_t i=0; i<groups.size(); ++i) {
659  os << groups[i].group_name << "\t";
660  for (int p=0; p<8; ++p) {
661  os << " " << variance_match[i][p].average()
662  << " " << sqrt(variance_match[i][p].variance())
663  << " " << frequency[i][p].average() << " ";
664  }
665  os << "\t" << variance_all[i].average()
666  << "\t" << sqrt(variance_all[i].variance())
667  << "\n";
668  }
669 }
670 #endif
671 
673 {
674  return OslConfig::home()+"/data/rating";
675 }
676 
677 /* ------------------------------------------------------------------------- */
678 
680 StandardFeatureSet::StandardFeatureSet(bool allow_load_failure)
681 {
682  add(new CaptureGroup());
683  add(new SquareYGroup());
684  add(new RelativeKingXGroup(true));
685  add(new SquareXGroup());
686  add(new TakeBackGroup());
687  add(new RelativeKingYGroup(true));
688  add(new FromEffectGroup());
689  add(new PatternGroup(U));
690  add(new RelativeKingXGroup(false));
691  add(new PatternGroup(D));
692 
693  add(new PatternLongGroup(0));
694  add(new CheckGroup());
695  add(new BlockGroup());
696  add(new PtypeAttackedGroup());
697 
698  add(new PatternGroup(U,U));
699  add(new ImmediateAddSupportGroup()); // 300 cycles
700  add(new PatternGroup(DR));
701  add(new RelativeKingYGroup(false));
702  add(new DefenseKing8Group());
703  add(new PatternGroup(L));
704  add(new PatternGroup(UL));
705 
706  add(new ToSupportedGroup());
707 
708  add(new PatternGroup(UR));
709  add(new PatternBlockGroup(ROOK));
710  add(new AttackKing8Group());
711  add(new PatternGroup(R));
712  add(new PatternGroup(DL));
713 
714  add(new PatternGroup(R,R));
715  add(new PatternLongGroup(3));
716  add(new PatternGroup(UUL));
717  add(new PatternGroup(UUR));
718  add(new PatternGroup(L,L));
719 
720  add(new PatternLongGroup(2));
721  add(new OpenGroup());
722  add(new PatternBlockGroup(LANCE));
723  add(new ChaseGroup());
724  add(new PatternLongGroup(1));
725  add(new PatternLongGroup2(1));
726  add(new PatternBlockGroup(BISHOP));
727  add(new PatternGroup(UR,R));
728  add(new PatternLongGroup2(0));
729  add(new PatternGroup(UL,L));
730 
731  add(new ImmediateEscapeGroup());
732  add(new PatternLongGroup2(3));
733  add(new PatternLongGroup2(2));
734  add(new KaranariGroup());
735 
736  add(new BigramAttackGroup(true, true));
737  add(new BigramAttackGroup(false, true));
738  add(new BigramAttackGroup(true, false));
739  add(new BigramAttackGroup(false, false));
740 
741  add(new DropCapturedGroup());
742  add(new ContinueCaptureGroup());
743  add(new PawnAttackGroup());
744  add(new ThreatmateGroup());
745 
746  add(new BadLanceGroup());
747  add(new CheckmateIfCaptureGroup());
748  add(new RookDefense());
749  add(new SendOffGroup());
750 
751  add(new PinGroup());
752  add(new KingEscapeGroup());
753  add(new EscapePinGroup());
754 
755  addFinished();
756  bool success = tryLoad(defaultDirectory());
757  if (! allow_load_failure && ! success) {
758  std::cerr << "error: unable to load rating from " << defaultDirectory();
759  throw std::runtime_error("load failed " + OslConfig::home()+defaultDirectory());
760  }
761 }
762 
763 
766 {
767  static osl::rating::StandardFeatureSet common_instance;
768  return common_instance;
769 }
770 
772 {
773  std::cerr << "loading " << defaultDirectory() << ' ';
774  try {
775  instance();
776  std::cerr << "success\n";
777  }
778  catch (std::exception& e)
779  {
780  std::cerr << e.what() << "\n";
781  return false;
782  }
783  catch (...) {
784  std::cerr << "unknown exception\n";
785  return false;
786  }
787  return true;
788 }
789 
791 CaptureSet::CaptureSet(bool allow_load_failure)
792 {
793  add(new CaptureGroup());
794  add(new ShadowEffectGroup());
795 
796  addFinished();
797  bool success = tryLoad(defaultDirectory());
798  if (! allow_load_failure && ! success) {
799  std::cerr << "error: unable to load rating from " << defaultDirectory();
800  throw std::runtime_error("load failed " + defaultDirectory());
801  }
802 }
803 
804 /* ------------------------------------------------------------------------- */
805 // ;;; Local Variables:
806 // ;;; mode:c++
807 // ;;; c-basic-offset:2
808 // ;;; coding:utf-8
809 // ;;; End:
size_t size() const
Definition: container.h:243
void push_back(const T &e)
Definition: container.h:204
圧縮していない moveの表現 .
Definition: basic_type.h:1052
利きを持つ局面
bool hasEffectAt(Square target) const
対象とするマスにあるプレイヤーの利きがあるかどうか.
bool inCheck(Player P) const
Pの玉が王手状態
bool any() const
Definition: pieceMask.h:57
Player turn() const
Definition: simpleState.h:220
void push_back(Move move, int prob)
CaptureSet(bool allow_load_failure=false)
Definition: featureSet.cc:791
const range_t makeRange(size_t group) const
Definition: featureSet.cc:66
void showStatistics(std::ostream &) const
Definition: featureSet.cc:655
void save(const std::string &output_directory, size_t group_id) const
Definition: featureSet.cc:649
const RatedMove makeRate(const NumEffectState &state, bool in_check, const RatingEnv &env, Move move) const
Definition: featureSet.cc:481
void addCommon(Group *g)
Definition: featureSet.cc:101
void generateLogProb(const NumEffectState &state, const RatingEnv &env, int limit, MoveLogProbVector &out, bool in_pv_or_all=true) const
Definition: featureSet.cc:389
static std::string defaultDirectory()
Definition: featureSet.cc:672
int logProbKingEscape(const NumEffectState &state, const RatingEnv &env, Move) const
Definition: featureSet.cc:443
int rating(const NumEffectState &state, const RatingEnv &env, Move move, size_t group_id) const
Definition: featureSet.cc:458
void add(Feature *f)
Definition: featureSet.cc:95
int logProbSeePlus(const NumEffectState &state, const RatingEnv &env, Move) const
Definition: featureSet.cc:431
const RatedMove makeRateWithCut(const NumEffectState &state, bool in_check, const RatingEnv &env, int limit, Move move) const
Definition: featureSet.cc:573
void setWeight(size_t feature_id, const double &value)
Definition: featureSet.cc:193
int logProbTakeBack(const NumEffectState &state, const RatingEnv &env, Move) const
Definition: featureSet.cc:420
bool tryLoad(const std::string &input_directory)
Definition: featureSet.cc:143
const std::string annotate(const NumEffectState &state, const RatingEnv &env, Move move) const
Definition: featureSet.cc:615
void generateRating(const NumEffectState &state, const RatingEnv &env, int limit, RatedMoveVector &out, bool in_pv_or_all=true) const
Definition: featureSet.cc:200
void showGroup(std::ostream &, size_t group_id) const
Definition: featureSet.cc:642
mutually exclusive set of features
Definition: group.h:17
virtual bool effectiveInCheck() const
Definition: group.h:39
void sort()
ratingが高い順にsort
int rating() const
Definition: ratedMove.h:29
Progress16 progress
Definition: ratingEnv.h:22
static const StandardFeatureSet & instance()
Definition: featureSet.cc:765
StandardFeatureSet(bool allow_load_failure=false)
Definition: featureSet.cc:680
static const osl::CArray2d< int, 8, rsc_length > relative_score_to_width
Definition: featureSet.cc:290
static const osl::CArray< int, 10 > score_to_depth_takeback
Definition: featureSet.cc:409
const int sc_length
Definition: featureSet.cc:257
const int sc_width
Definition: featureSet.cc:257
static const osl::CArray2d< int, 8, 16 > threshold
Definition: featureSet.cc:518
const int MinRating
Definition: featureSet.cc:36
static const osl::CArray2d< int, 8, 20 > order_to_depth
Definition: featureSet.cc:236
static const osl::CArray2d< int, 8, sc_length > score_to_depth
Definition: featureSet.cc:258
int make_prob(int score, int order, int limit, int highest, int progress8, bool in_pv_or_all)
Definition: featureSet.cc:301
const int min_score
Definition: featureSet.cc:408
const int rsc_length
Definition: featureSet.cc:279
static const osl::CArray2d< int, 8, sc_length > score_to_width
Definition: featureSet.cc:268
const int sc_start
Definition: featureSet.cc:257
static const osl::CArray< int, 10 > score_to_depth_kingescape
Definition: featureSet.cc:415
static const osl::CArray2d< int, 8, rsc_length > relative_score_to_depth
Definition: featureSet.cc:280
static const osl::CArray< int, 10 > score_to_depth_seeplus
Definition: featureSet.cc:412
const int max_score
Definition: featureSet.cc:408
static const osl::CArray2d< int, 8, 20 > order_to_width
Definition: featureSet.cc:246
int max(Player p, int v1, int v2)
Definition: evalTraits.h:84
int min(Player p, int v1, int v2)
Definition: evalTraits.h:92
std::pair< int, int > range_t
Definition: range.h:10
@ ROOK
Definition: basic_type.h:100
@ BISHOP
Definition: basic_type.h:99
@ KING
Definition: basic_type.h:93
@ LANCE
Definition: basic_type.h:96
@ R
Definition: basic_type.h:317
@ D
Definition: basic_type.h:319
@ UUR
Definition: basic_type.h:323
@ UUL
Definition: basic_type.h:322
@ UL
Definition: basic_type.h:313
@ DR
Definition: basic_type.h:320
@ U
Definition: basic_type.h:314
@ L
Definition: basic_type.h:316
@ UR
Definition: basic_type.h:315
@ DL
Definition: basic_type.h:318
constexpr Player alt(Player player)
Definition: basic_type.h:13
std::unordered_map< osl::HashKey, list_t, std::hash< osl::HashKey > > map_t
static void generate(Player p, const NumEffectState &state, MoveVector &)
Definition: allMoves.cc:15
static void generate(const NumEffectState &state, MoveVector &out)
不成の受けも作成
Definition: escape_.cc:9
static const std::string & home(const std::string &initialize_if_first_invocation="")
compile時に指定されたディレクトリを返す.
Definition: oslConfig.cc:239
int average_after
group 以降の性質
Definition: featureSet.cc:41
double average
group 単独の性質
Definition: featureSet.cc:43