static void etgc_add_array (ETableGroup *etg, const int *array, int count) { int i; ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg); void *lastval = NULL; int laststart = 0; GCompareFunc comp = etgc->ecol->compare; ETableGroupContainerChildNode *child_node; ETableGroup *child; if (count <= 0) return; e_table_group_container_list_free (etgc); etgc->children = NULL; lastval = e_table_model_value_at (etg->model, etgc->ecol->col_idx, array[0]); for (i = 1; i < count; i++) { void *val = e_table_model_value_at (etg->model, etgc->ecol->col_idx, array[i]); int comp_val; comp_val = (*comp)(lastval, val); if (comp_val != 0) { child_node = create_child_node(etgc, lastval); child = child_node->child; e_table_group_add_array(child, array + laststart, i - laststart); child_node->count = i - laststart; etgc->children = g_list_append (etgc->children, child_node); compute_text (etgc, child_node); laststart = i; lastval = val; } } child_node = create_child_node(etgc, lastval); child = child_node->child; e_table_group_add_array(child, array + laststart, i - laststart); child_node->count = i - laststart; etgc->children = g_list_append (etgc->children, child_node); compute_text (etgc, child_node); e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etgc)); }
static svn_error_t * add_open_helper(const char *path, char action, svn_node_kind_t kind, void *parent_baton, const char *copyfrom_path, svn_revnum_t copyfrom_rev, apr_pool_t *pool, void **child_baton) { struct node_baton *pb = parent_baton; struct edit_baton *eb = pb->edit_baton; struct node_baton *nb = apr_pcalloc(pool, sizeof(*nb)); assert(parent_baton && path); nb->edit_baton = eb; nb->parent_baton = pb; /* Create and populate the node. */ nb->node = create_child_node(pb->node, svn_path_basename(path, pool), eb->node_pool); nb->node->kind = kind; nb->node->action = action; nb->node->copyfrom_rev = copyfrom_rev; nb->node->copyfrom_path = copyfrom_path ? apr_pstrdup(eb->node_pool, copyfrom_path) : NULL; *child_baton = nb; return SVN_NO_ERROR; }
void UCTParallel::expand_root_node(const Board& board, const Color color, UCTNode* root) { // 合法手の数をカウント XY legal_xy[BOARD_SIZE_MAX * BOARD_SIZE_MAX + 1]; for (XY xy = board.empty_list.begin(); xy != board.empty_list.end(); xy = board.empty_list.next(xy)) { if (board.is_legal(xy, color) == SUCCESS) { legal_xy[root->child_num++] = xy; } } // PASSを追加 legal_xy[root->child_num++] = PASS; // ノードを確保 root->child = create_child_node(root->child_num); // ノードの値を設定 for (int i = 0; i < root->child_num; i++) { root->child[i].xy = legal_xy[i]; root->child[i].playout_num = 0; root->child[i].playout_num_sum = 0; root->child[i].win_num = 0; root->child[i].child_num = 0; } }
static svn_error_t * delete_entry(const char *path, svn_revnum_t revision, void *parent_baton, apr_pool_t *pool) { struct node_baton *d = parent_baton; struct edit_baton *eb = d->edit_baton; svn_repos_node_t *node; const char *name; const char *base_path; svn_revnum_t base_rev; svn_fs_root_t *base_root; svn_node_kind_t kind; /* Get (or create) the change node and update it. */ name = svn_path_basename(path, pool); node = find_child_by_name(d->node, name); if (! node) node = create_child_node(d->node, name, eb->node_pool); node->action = 'D'; /* We need to look up this node's parents to see what its original path in the filesystem was. Why? Because if this deletion occurred underneath a copied path, the thing that was deleted probably lived at a different location (relative to the copy source). */ find_real_base_location(&base_path, &base_rev, node, pool); if (! SVN_IS_VALID_REVNUM(base_rev)) { /* No interesting base revision? We'll just look for the path in our base root. */ base_root = eb->base_root; } else { /* Oh. Perhaps some copy goodness happened somewhere? */ SVN_ERR(svn_fs_revision_root(&base_root, eb->fs, base_rev, pool)); } /* Now figure out if this thing was a file or a dir. */ SVN_ERR(svn_fs_check_path(&kind, base_root, base_path, pool)); if (kind == svn_node_none) return svn_error_createf(SVN_ERR_FS_NOT_FOUND, NULL, _("'%s' not found in filesystem"), path); node->kind = kind; return SVN_NO_ERROR; }
static void etgc_add (ETableGroup *etg, gint row) { ETableGroupContainer *etgc = E_TABLE_GROUP_CONTAINER (etg); void *val = e_table_model_value_at (etg->model, etgc->ecol->col_idx, row); GCompareFunc comp = etgc->ecol->compare; GList *list = etgc->children; ETableGroup *child; ETableGroupContainerChildNode *child_node; int i = 0; for (; list; list = g_list_next (list), i++){ int comp_val; child_node = list->data; comp_val = (*comp)(child_node->key, val); if (comp_val == 0) { child = child_node->child; child_node->count ++; e_table_group_add (child, row); compute_text (etgc, child_node); return; } if ((comp_val > 0 && etgc->ascending) || (comp_val < 0 && (!etgc->ascending))) break; } child_node = create_child_node (etgc, val); child = child_node->child; child_node->count = 1; e_table_group_add (child, row); if (list) etgc->children = g_list_insert (etgc->children, child_node, i); else etgc->children = g_list_append (etgc->children, child_node); compute_text (etgc, child_node); e_canvas_item_request_reflow (GNOME_CANVAS_ITEM (etgc)); }
Tree_node get_create_child_node(Tree_node parent, char symbol, int type) { Tree_node prev, cur; struct tree_node dummy_node; prev = &dummy_node; cur = prev->sibling = parent->child; while (cur && cur->symbol < symbol) { prev = cur; cur = cur->sibling; } if(cur && cur->symbol == symbol) { return cur; } // the correct node was not found, create a new one and put it at the correct position Tree_node new_node = create_child_node(parent, symbol, type); new_node->sibling = cur; if (prev == &dummy_node) parent->child = new_node; else prev->sibling = new_node; return new_node; }
/* * Creates an empty tree */ Tree_node Tree_create(int type) { return create_child_node(NULL, ' ', type); }
XY UCTParallel::select_move(Board& board, Color color) { UCTNode* root = create_root_node(); this->root = root; // ノードを展開(合法手のみ) expand_root_node(board, color, root); // root並列化 std::thread th[THREAD_NUM]; for (int th_i = 0; th_i < THREAD_NUM; th_i++) { th[th_i] = std::thread([root, &board, color] { // rootの子ノードのコピー UCTNode* copychild = create_child_node(root->child_num); if (copychild == nullptr) { fprintf(stderr, "node pool too small\n"); return; } for (int i = 0; i < root->child_num; i++) { copychild[i].xy = root->child[i].xy; copychild[i].playout_num = 0; copychild[i].playout_num_sum = 0; copychild[i].child_num = 0; } for (int i = 0; i < PLAYOUT_MAX / THREAD_NUM; i++) { // 局面コピー Board board_tmp = board; // UCT search_uct_root(board_tmp, color, root, copychild); } }); } // スレッド終了待機 for (int th_i = 0; th_i < THREAD_NUM; th_i++) { th[th_i].join(); } // 最もプレイアウト数が多い手を選ぶ UCTNode* best_move; int num_max = -999; double rate_min = 1; // 勝率 double rate_max = 0; // 勝率 for (int i = 0; i < root->child_num; i++) { UCTNode* child = root->child + i; if (child->playout_num > 0) { int num = child->playout_num; if (num > num_max) { best_move = child; num_max = num; } double rate; if (rate_min == 1) { rate = double(child->win_num) / child->playout_num; if (rate < rate_min) { rate_min = rate; } } if (rate_max == 0) { rate = double(child->win_num) / child->playout_num; if (rate > rate_max) { rate_max = rate; } } } } if (rate_min == 1) { return PASS; } if (rate_max == 0) { return RESIGN; } return best_move->xy; }