10 #include <boost/thread/thread.hpp>
17 : features(f),
kisen_filename(kisen_file), kisen_start(kisen_start), num_cpus(1), num_records(200),
29 valarray_t& wins, std::valarray<long double>& denominator)
const
33 if (! moves.isMember(selected))
35 const range_t range = features.range(g);
37 const bool in_check = EffectUtil::isKingInCheck(state.turn(), state);
38 if (! in_check || features.effectiveInCheck(g))
41 int found = features.group(g).findMatch(state, selected, env);
43 ++wins[found+range.first];
45 valarray_t sum_c(0.0, range.second-range.first);
46 long double sum_e = 0.0;
47 for (
size_t i=0; i<moves.size(); ++i) {
52 for (
size_t j=0; j<features.groupSize(); ++j) {
54 if (in_check && ! features.effectiveInCheck(j))
57 int found = features.group(j).findMatch(state, m, env);
60 found += features.range(j).first;
61 product *= features.weight(found);
64 assert(range.first <= found && found < range.second);
71 sum_c[match_id-range.first] += product / features.weight(match_id);
74 for (
int f=range.first; f<range.second; ++f)
75 denominator[f] += sum_c[f-range.first]/sum_e;
91 : features(a),
target(t), first(f), last(l), wins(w), denominator(d), skip(s)
96 *skip = features->accumulate(
target, first, last, *wins, *denominator);
103 assert(wins.size() == features.featureSize());
107 for (
size_t i=first; i<
last; i++) {
115 NumEffectState state(kisen_file.getInitialState());
119 for (
size_t j=0; j<moves.size(); j++) {
123 const Player turn = state.turn();
124 if (! state.inCheck()
128 if (!
addSquare(g, state, env, moves[j], wins, denominator))
131 state.makeMove(moves[j]);
132 env.update(state, moves[j]);
141 std::valarray<valarray_t>
wins(
valarray_t(0.0, features.featureSize()), num_cpus);
142 std::valarray<std::valarray<long double> >
denominator(std::valarray<long double>(0.0, features.featureSize()), num_cpus);
147 num_records=kisen_file.size();
149 accumulate(g, 0, num_records, wins[0], denominator[0]);
153 size_t last =
num_records, step = (last - cur)/num_cpus;
154 boost::ptr_vector<boost::thread> threads;
155 std::valarray<size_t>
skip((
size_t)0, num_cpus);
156 for (
size_t i=0; i<
num_cpus; ++i, cur += step) {
157 size_t next = (i+1 ==
num_cpus) ? last : cur + step;
158 threads.push_back(
new boost::thread(
Thread(
this, g, cur, next, &wins[i], &denominator[i], &skip[i])));
163 std::cerr <<
"skip " << skip.sum() <<
" / " << num_records <<
"\n";
165 const range_t range = features.range(g);
166 for (
int f=range.first; f<range.second; ++f) {
167 const int NPRIOR = 10;
168 double sum_win = NPRIOR;
169 long double sum_denom = (1.0 / (features.weight(f) + 1.0)) * 2 * NPRIOR;
171 sum_win += wins[i][f];
172 sum_denom += denominator[i][f];
175 std::cerr <<
" " << std::setw(14) << features.feature(f).name()
176 <<
" " << features.weight(f) <<
" => " << sum_win/sum_denom
177 <<
" " << sum_win <<
" / " << sum_denom
178 <<
" " << 400*log10(sum_win/sum_denom) <<
"\n";
182 features.setWeight(f, sum_win/sum_denom);
183 assert(! std::isinf(features.weight(f)));
184 assert(! std::isnan(features.weight(f)));
187 features.showGroup(std::cerr, g);
193 for (
int j=0; j<16; ++j) {
194 std::cerr <<
"\nnew iteration " << j <<
"\n";
195 for (
size_t i=0; i<features.groupSize(); ++i) {
197 features.save(output_directory, i);
198 if ((
int)(i+1) == fix_group)