- 以下のcollect.c, player.h, player.cを用意して、コンパイル・実行
- gcc -o game0 collect.c player.c bandit00.o
- gcc -o game1 collect.c player.c bandit01.o
- gcc -o game2 collect.c player.c bandit02.o
- gcc -o game3 collect.c player.c bandit03.o
- gcc -o game4 collect.c player.c bandit04.o
- gcc -o game5 collect.c player.c bandit05.o
- gcc -o game6 collect.c player.c bandit06.o
- gcc -o game7 collect.c player.c bandit07.o
- gcc -o game8 collect.c player.c bandit08.o
- ./game0
- ./gam1
- ./game2
- ./game3
- ./game4
- ./game5
- ./game6
- ./game7
- ./game8
#include <stdio.h>
#include <stdlib.h>
#include "bandit.h"
#include "player.h"
#define MAX_TRIAL 100000
int main(){
/* 変数定義・初期化 */
int i,j,select_arm=0;
double reward=0.0,score[10000], max_score=0.0, tmp_score;
for(i=0 ; i<10000 ; i++){
score[i]=0.0;
}
init_bandit(); /* バンディット初期化 */
init_player(); /* プレーヤー初期化 */
set_arm_num(get_arm_num()); /* バンディットの腕の数を取得 */
/* MAX_TRIAL回まで自動実行 */
/* 連続した10000回のうち最大のスコアを自動計算・更新 */
for(i=0 ; i<MAX_TRIAL ; i++){
/* 意思決定・それによるバンディットの実行*/
select_arm = decision_making(reward);
reward = bandit(select_arm);
if(reward < 0.0) reward = 0.0;
/* 連続した10000回の最大スコアの確認 */
tmp_score=0.0;
for(j=0 ; j<10000 ; j++) tmp_score += score[j];
if(tmp_score > max_score) max_score = tmp_score;
/* 連続した10000回のスコアを更新 */
/* score[0] 〜score[9999] に対し, */
/* 最も古いものscore[9999]を消し, */
/* 一個ずつずらし(score[j] = score[j-1]) */
/* 最も新しいものをscore[0]に入れる */
for(j=9999 ; j> 0 ; j--) score[j] = score[j-1];
score[0] = reward;
}
printf("最大総獲得報酬: %lf\n", max_score);
close_player();
return 0;
}
void init_player();
void close_player();
void set_arm_num(int arm_num);
int decision_making(double previous_reward);
#include "player.h"
static int _arm_num=0; /* このファイルないでしか見えないグローバル変数 */
void init_player(){
return;
}
void close_player(){
return;
}
void set_arm_num(int arm_num){
if(arm_num>0){
_arm_num = arm_num; /* 使い方の例 */
}
return;
}
int decision_making(double previous_reward){
/* _arm_numを使えます */
/* ここに、bandit00〜bandit08を”解く”プログラムを書く */
return _arm_num; // 最後の腕を選択する(腕3本のバンディットなら3番目の腕を選択する)
}
- player.c
- ヒント1:ファイルスコープ変数を使う
- ファイルスコープ変数とは(教科書・本・webも参考に)
- ヒント2:decision_makingのprevious_rewardの説明
#include "player.h"
/* このファイルないでしか見えないグローバル変数 */
/* バンディットの腕の数 */
static int _arm_num=0;
/* player(decision_making)が選択した腕番号 */
static int _player_select_arm;
/* reward[i-1] がi番目の腕の報酬値.適当に超えない数字(20個の腕)にした */
/* 腕は1から,配列は0から始まるので,腕番号iとreward[ i-1 ]が対応 */
static double _reward[20];
void init_player(){
int i;
_player_select_arm = -5; /* なんとなく,選択した腕がない状態を -5 としてみた */
for(i=0 ; i<20 ; i++){
_reward[i]=-5.0; /* なんとなく,値の入っていない状態を-5.0とする */
}
return;
}
void close_player(){
return;
}
void set_arm_num(int arm_num){
if(arm_num>0){
_arm_num = arm_num; /* 使い方の例 */
}
return;
}
int decision_making(double previous_reward){
/* _arm_numを使えます */
/* bandit00を”解く”プログラム */
int i;
/* 前回選択した腕がいくつの報酬であったか記録 */
if( _player_select_arm != -5 ){ /* 1回目のプレイなど前回選択した腕がない(-5)状態か判定 */
/* 腕は1から,配列は0から始まるので,腕番号iとreward[ i-1 ]が対応 */
_reward[ _player_select_arm - 1 ] = previous_reward;
}
/* まずは試していない腕を試してみる */
for(i=1 ; i <= _arm_num ; i++){
if(_reward[i-1] == -5.0){ /* i番目の腕を試していない(rewardを持っていない,-5.0の状態) */
_player_select_arm = i;
return i;
}
}
/* 全部の腕を試していたら、その中から最も高い報酬の腕を選択 */
int max_reward=0;
int max_arm=1;
for(i=1 ; i <= _arm_num ; i++){
if( _reward[ i-1 ] >= max_reward ){
max_reward = _reward[ i-1 ];
max_arm = i;
}
}
_player_select_arm = max_arm;
return max_arm;
}
- player.c
- ヒント4:bandit00用player
- ポインタの演習資料中の4.動的配列を用いて,腕の数ぴったりにreward[]を取得.ヒント3では,腕の数を十分な数(20個)にしていた.
#include <stdlib.h>
#include "player.h"
/* このファイルないでしか見えないグローバル変数 */
/* バンディットの腕の数 */
static int _arm_num=0;
/* player(decision_making)が選択した腕番号 */
static int _player_select_arm;
/* reward[i-1] がi番目の腕の報酬値.*/
/* 腕は1から,配列は0から始まるので,腕番号iとreward[ i-1 ]が対応 */
static double* _reward;
void init_player(){
_player_select_arm = -5; /* なんとなく,選択した腕がない状態を -5 としてみた */
return;
}
void close_player(){
/* 動的配列は free で解放する必要あり */
free( _reward );
return;
}
void set_arm_num(int arm_num){
int i;
if(arm_num>0){
_arm_num = arm_num; /* 使い方の例 */
}
/* ここでバンディットの腕の数が得られるので,rewardの初期化 */
/* reward[ 腕の数分の配列 ] を動的配列で確保 */
_reward = (double *)malloc(sizeof(double) * _arm_num);
for(i=0 ; i < _arm_num ; i++){
_reward[i]=-5.0; /* なんとなく,値の入っていない状態を-5.0とする */
}
return;
}
int decision_making(double previous_reward){
/* _arm_numを使えます */
/* bandit00を”解く”プログラム */
int i;
/* 前回選択した腕がいくつの報酬であったか記録 */
if( _player_select_arm != -5 ){ /* 1回目のプレイなど前回選択した腕がない(-5)状態か判定 */
/* 腕は1から,配列は0から始まるので,腕番号iとreward[ i-1 ]が対応 */
_reward[ _player_select_arm - 1 ] = previous_reward;
}
/* まずは試していない腕を試してみる */
for(i=1 ; i <= _arm_num ; i++){
if(_reward[i-1] == -5.0){ /* i番目の腕を試していない(rewardを持っていない,-5.0の状態) */
_player_select_arm = i;
return i;
}
}
/* 全部の腕を試していたら、その中から最も高い報酬の腕を選択 */
int max_reward=0;
int max_arm=1;
for(i=1 ; i <= _arm_num ; i++){
if( _reward[ i-1 ] >= max_reward ){
max_reward = _reward[ i-1 ];
max_arm = i;
}
}
_player_select_arm = max_arm;
return max_arm;
}