﻿
■　dynamic futility margin


  // dynamic futility margin ( inspired by 読み太 )
  // 探索したときに abs(staticEval-value)をサンプリングしてその平均らへんをmargin値として用いる
  Value futility_margin_table[MAX_PLY];
  int futility_margin_count[MAX_PLY];
  Value futility_margin_sum[MAX_PLY];

  // margin値をサンプリングする周期
  const int futility_margin_update_interval = 16;
  // futility_margin_sum[]は、futility_margin_update_interval×futility_margin_update_countの個数がサンプリングされていると考える。
  const int futility_margin_update_count = 8;



#if 1
//    return futility_margin_table[d / ONE_PLY];
    return futility_margin_table[0] * (int)d/ONE_PLY;
#endif


  // -----------------------
  // dynamic futility margin
  // -----------------------

  for (int i = 0; i < DEPTH_MAX; ++i)
  {
    // depth * 90
    futility_margin_table[i] = (Value)(i*90);
    futility_margin_count[i] = 0;

    futility_margin_table[0] = (Value)(1 * 90);

    // 初期状態ではfutility_margin_sum[i]には、futility_margin_update_intervalの
    // (futility_margin_update_count-1)倍の個数のabs(eval-value)の合計が格納されていると考える。
    // ここにfutility_margin_update_interval個さらに突っ込んで、futility_margin_update_intervalの
    // futility_margin_update_count倍の個数になったときに
    // (futility_margin_update_interval*futility_margin_update_count)で割って平均を出す。(移動平均みたいなの)
    futility_margin_sum[i] = futility_margin_table[i] * futility_margin_update_interval * (futility_margin_update_count - 1);
  }



        // このときにdynamic futility marginの値をサンプリングする
        if (newDepth == 1 * ONE_PLY
          && eval!=VALUE_NONE && abs(value) <= VALUE_MAX_EVAL
          && value < beta   // fail highしている値は信用ならないので除外
          && alpha < value  // fail lowしている値は参考にならないので除外
          
          )
        {
//          int d = newDepth / ONE_PLY;
//          futility_margin_sum[d] += (eval >= beta) ? (eval - value) * d : eval - value;
          futility_margin_sum[0] += abs(eval - value);

          if (futility_margin_count[0]++ == futility_margin_update_interval)
          {
            // futility_sampling_intervalのfutility_margin_update_count倍の要素の合計がfutility_margin_sum[d]
            futility_margin_table[0] = ((param1 + 4) * futility_margin_sum[0] / 4)
              / (futility_margin_update_count * futility_margin_update_interval);
#if 0
            futility_margin_table[d] = ((5 + 3) * futility_margin_sum[d] / 4)
              / (futility_margin_update_count * futility_margin_update_interval);
#endif
            //  1/futility_margin_update_count が入れ替わったという考え。
            // (本当は古い部分を入れ替えたほうがいいかも知れないが…)
            futility_margin_sum[0] = futility_margin_sum[0] * (futility_margin_update_count - 1)/ futility_margin_update_count;
            futility_margin_count[0] = 0;
    //        cout << "futility_margin[" << 0 << "] = " << futility_margin_table[0] << endl;
          }
        }
