20#include <boost/format.hpp>
53 : capture_group(-1), checkmate_if_capture_group(-1), sendoff_group(-1)
61 showStatistics(std::cerr);
69 for (
size_t i=0; i<groups.size(); ++i) {
71 return std::make_pair(first, first+groups[i].size());
72 first += groups[i].size();
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());
103 features.reserve(features.size()+g->size());
104 for (
size_t i=0; i<g->size(); ++i) {
105 features.push_back(&(*g)[i]);
114 normal_groups.push_back(
true);
121 capture_group = normal_groups.size();
122 normal_groups.push_back(
false);
129 sendoff_group = normal_groups.size();
130 normal_groups.push_back(
false);
137 checkmate_if_capture_group = normal_groups.size();
138 normal_groups.push_back(
false);
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";
153 for (
size_t i=0; i<features.size(); ++i)
154 weightslog10[i] =
static_cast<int>(400*log10(weights[i]));
156 std::string filename = input_directory +
"/statistics.txt";
157 std::ifstream is(filename.c_str());
158 typedef std::map<std::string,Statistics>
map_t;
161 double a, s, p, dummy;
162 while (is >> name >> a >> s >> dummy >> dummy >> p) {
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()) {
176 a += q->second.probability * q->second.average;
177 v += q->second.probability * q->second.variance;
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";
195 weights[feature_id] = value;
196 weightslog10[feature_id] =
static_cast<int>(400*log10(value));
203#if (defined RATING_STAT) || (defined RATING_STAT2)
207 const bool in_check = state.
inCheck();
214 for (
size_t i=0; i<moves.
size(); ++i) {
215 if (moves[i].ptype() ==
KING) {
219 if (! in_check && env.
my_pin.
any() && ! moves[i].isDrop()
225 out.
push_back(makeRate(state, in_check, env, moves[i]));
227 RatedMove r = makeRateWithCut(state, in_check, env, limit, moves[i]);
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,
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,
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,
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,
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,
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,
301inline int make_prob(
int score,
int order,
int limit,
int highest,
int progress8,
bool in_pv_or_all)
303 const int order_index = std::min((
int)order/4, 19);
304 int result = limit+1;
306 result = (order == 0) ? 100 :
order_to_depth[progress8][order_index];
309 highest = std::max(
sc_start, highest);
311 if (limit > 600 &&
score_to_width[progress8][score_index] <= limit) {
312 result = std::min(result,
score_to_depth[progress8][score_index]);
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);
328 CArray2d<CArray<stat::Average,8>,14,40> data;
329 CArray2d<CArray<double,8>,14,80> selected_all;
330 void add_stat(
int limit,
int rating,
bool added,
int progress8)
332 limit = std::min(limit, 999);
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);
339 selected_all[limit/50][(rating+1000)/25][progress8] += 1.0;
345 std::cerr <<
"limit " << 0*50+300 <<
" - " << (data.size1()-1)*50+300 <<
"\n";
346 for (
int p=0; p<8; ++p)
348 std::cerr <<
"progress8 " << p <<
"\n ";
349 for (
size_t j=0; j<data.size1(); ++j)
352 for (; i<data.size2(); ++i)
353 if (data[j][i][p].getAverage() > 0.05)
355 std::cerr << (boost::format(
"%+4d, ") %
static_cast<int>(i)*50-1000);
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)
365 std::cerr <<
"progress8 " << p <<
"\n ";
366 for (
size_t j=0; j<selected_all.size1(); ++j)
369 for (
size_t i=0; i<selected_all.size2(); ++i)
370 sum += selected_all[j][i][p];
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)
377 std::cerr << (boost::format(
"%+4d, ") %
static_cast<int>(i)*25-1000);
393 generateRating(state, env, limit, score, in_pv_or_all);
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);
402 add_stat(limit, score[i].rating(), log_prob <= limit, progress8);
410 223, 204, 208, 190, 159, 137, 124, 110, 100, 89
413 356, 337, 296, 262, 230, 200, 171, 148, 132, 120,
416 203, 201, 199, 188, 181, 169, 159, 147, 136, 122,
422 const bool in_check = state.
inCheck();
423 const int score = makeRate(state, in_check, env, move).rating();
434 const bool in_check = state.
inCheck();
435 const int score = makeRate(state, in_check, env, move).rating();
446 const bool in_check = state.
inCheck();
447 const int score = makeRate(state, in_check, env, move).rating();
461 int found = groups[group_id].findMatch(state, move, env);
464 const int progress8 = env.
progress.value()/2;
465 frequency[group_id][progress8].add(0);
466 variance_all[group_id].add(0);
470 found += ranges[group_id].first;
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]);
477 return weightslog10[found];
485 for (
size_t j=0; j<groups.size(); ++j) {
486 if (! normal_groups[j])
488 if (in_check && ! effectiveInCheck(j))
490 sum += rating(state, env, move, j);
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;
500 if (sendoff_group >= 0)
501 sendoff = rating(state, env, move, sendoff_group);
504 if (checkmate_if_capture > 0)
505 capture = std::max(0, capture);
506 else if (sendoff > 0 && capture < 0)
508 const int optimistic = sum + std::max(0, capture);
520 100, 100, 50, 0, 0, -75,-100,-150,-200,-200,
523 125, 125, 125, 25, 25, -50, -50,-100,-125,-225,
526 100, 75, 100, 25, 0, -25, -50,-100,-125,-175,
529 75, 50, 75, 0, -25, -25, -75,-100,-125,-200,
532 125, 125, 150, 50, 50, 50, -25, 0, -50,-200,
535 175, 200, 200, 75, 75, 75, 0, 0,-175,-300,
538 175, 175, 200, 50, 75, 75, 25, 0,-100,-250,
541 225, 200, 225, 75, 100, 75, 50, 0, 0,-250,
548 100,100,100,0,0,-100,-100,-200,-200,-200,
551 100,100,100,0,0,-100,-100,-100,-100,-200,
554 100,100,100,0,0,0,-100,-100,-100,-200
557 100,100,100,0,0,0,-100,-100,-100,-200
560 200,200,200,100,100,100,0,0,0,-100
563 300,300,300,100,100,100,100,0,-200,-300
566 300,300,300,100,100,100,100,0,0,-200
569 300,300,300,100,200,200,100,0,0,-200
576 int limit,
Move move)
const
579 return makeRate(state, in_check, env, move);
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))
589 const int r = rating(state, env, move, j);
591 if ((
int)j == capture_group) {
594 else if ((
int)j == checkmate_if_capture_group) {
595 checkmate_if_capture = r;
596 if (checkmate_if_capture > 0 && capture < 0) {
603 int sigma = statistics[j].sigma_after;
604 if (sum + statistics[j].average_after + sigma <
threshold[progress8][limit]) {
610 const int optimistic = sum + std::max(0, capture);
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))
623 int found = groups[j].findMatch(state, move, env);
626 found += ranges[j].first;
627 values.push_back(std::make_pair(weightslog10[found], groups[j].group_name));
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) {
635 ss << values[i].second <<
" " << values[i].first;
644 os << std::setprecision(3);
645 group(group_id).show(os, 12, range(group_id), weights);
651 group(group_id).saveResult(output_directory, range(group_id), weights);
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() <<
" ";
665 os <<
"\t" << variance_all[i].average()
666 <<
"\t" << sqrt(variance_all[i].variance())
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());
768 return common_instance;
773 std::cerr <<
"loading " << defaultDirectory() <<
' ';
776 std::cerr <<
"success\n";
778 catch (std::exception& e)
780 std::cerr << e.what() <<
"\n";
784 std::cerr <<
"unknown exception\n";
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());
void push_back(const T &e)
bool hasEffectAt(Square target) const
対象とするマスにあるプレイヤーの利きがあるかどうか.
bool inCheck(Player P) const
Pの玉が王手状態
void push_back(Move move, int prob)
CaptureSet(bool allow_load_failure=false)
const range_t makeRange(size_t group) const
void showStatistics(std::ostream &) const
void save(const std::string &output_directory, size_t group_id) const
const RatedMove makeRate(const NumEffectState &state, bool in_check, const RatingEnv &env, Move move) const
void generateLogProb(const NumEffectState &state, const RatingEnv &env, int limit, MoveLogProbVector &out, bool in_pv_or_all=true) const
static std::string defaultDirectory()
int logProbKingEscape(const NumEffectState &state, const RatingEnv &env, Move) const
int rating(const NumEffectState &state, const RatingEnv &env, Move move, size_t group_id) const
int logProbSeePlus(const NumEffectState &state, const RatingEnv &env, Move) const
const RatedMove makeRateWithCut(const NumEffectState &state, bool in_check, const RatingEnv &env, int limit, Move move) const
void setWeight(size_t feature_id, const double &value)
int logProbTakeBack(const NumEffectState &state, const RatingEnv &env, Move) const
bool tryLoad(const std::string &input_directory)
const std::string annotate(const NumEffectState &state, const RatingEnv &env, Move move) const
void generateRating(const NumEffectState &state, const RatingEnv &env, int limit, RatedMoveVector &out, bool in_pv_or_all=true) const
void showGroup(std::ostream &, size_t group_id) const
mutually exclusive set of features
virtual bool effectiveInCheck() const
void sort()
ratingが高い順にsort
static const StandardFeatureSet & instance()
StandardFeatureSet(bool allow_load_failure=false)
static bool healthCheck()
static const osl::CArray2d< int, 8, rsc_length > relative_score_to_width
static const osl::CArray< int, 10 > score_to_depth_takeback
static const osl::CArray2d< int, 8, 16 > threshold
static const osl::CArray2d< int, 8, 20 > order_to_depth
static const osl::CArray2d< int, 8, sc_length > score_to_depth
int make_prob(int score, int order, int limit, int highest, int progress8, bool in_pv_or_all)
static const osl::CArray2d< int, 8, sc_length > score_to_width
static const osl::CArray< int, 10 > score_to_depth_kingescape
static const osl::CArray2d< int, 8, rsc_length > relative_score_to_depth
static const osl::CArray< int, 10 > score_to_depth_seeplus
static const osl::CArray2d< int, 8, 20 > order_to_width
std::pair< int, int > range_t
constexpr Player alt(Player player)
std::unordered_map< osl::HashKey, list_t, std::hash< osl::HashKey > > map_t
static void generate(Player p, const NumEffectState &state, MoveVector &)
static void generate(const NumEffectState &state, MoveVector &out)
不成の受けも作成
static const std::string & home(const std::string &initialize_if_first_invocation="")
compile時に指定されたディレクトリを返す.
int average_after
group 以降の性質
double average
group 単独の性質