的の得点の配置 その2
いくらやっても分からないので、延々と評価し続けるようにしました。
/** * ダーツの的の得点の配置を考える */ #include <cstdio> #include <cstdlib> #include <unistd.h> #include <ctime> #include <vector> #include <algorithm> using namespace std; // 固定値 enum { NINZU = 50, KAISUU = 3 }; // 人型 struct MAN { int no; double ave; }; // 得点 struct TOKUTEN { int point; // 評価関数による得点 int p[ 12 ]; // 的の得点の配列 }; // 取得得点の比較関数。降順 int myComp( const void* a, const void* b ) { return (((MAN*)a)->ave > ((MAN*)b)->ave) ? -1 : ((((MAN*)a)->ave < ((MAN*)b)->ave) ? 1 : 0); } // 得点配列比較のための関数オブジェクト class tokutenComp { public: bool operator() ( const TOKUTEN& lhs, const TOKUTEN& rhs ) const { return (lhs.point < rhs.point); }; }; // 取得得点の評価関数 int myEval( const MAN* m ) { int point = 0; // ダブったら +1。小さい方が優秀かもしれない for( int i = 0; i < NINZU-1; ++i ) { if( m[ i ].ave == m[ i+1 ].ave ) ++point; } return point; } //////////////////////////////////// main int main(void) { int i, j, k; // カウンタ int pickup = 0; // 引いた点数 TOKUTEN nowTk; // 現在の対象得点配列 TOKUTEN recordTk; // 最高ポイントをマークした得点配列 MAN m[ NINZU ]; // 人 vector< TOKUTEN > tokutenArray; // 20回試行したものを保存する // 初期値 for( int i = 0; i<12; ++i ) nowTk.p[i] = 30; nowTk.point = 50; // 乱数発生器 srand( (unsigned long)time(NULL) ); while( 1 ) { tokutenArray.clear(); printf( "proc %2d [%2d] [%2d] [%2d] [%2d] [%2d] [%2d] [%2d] [%2d] [%2d] [%2d] [%2d] [%2d]?n", nowTk.point, nowTk.p[ 0], nowTk.p[ 1], nowTk.p[ 2], nowTk.p[ 3], nowTk.p[ 4], nowTk.p[ 5], nowTk.p[ 6], nowTk.p[ 7], nowTk.p[ 8], nowTk.p[ 9], nowTk.p[10], nowTk.p[11] ); // 20 回試行 for( k = 0; k < 20; ++k ) { // ダーツ投げ部 for( i = 0; i < NINZU; ++i ) { // 人数分繰り返し // 初期化をここで m[ i ].no = i; m[ i ].ave = 0.0; // ダーツを投げる for( j = 0; j < KAISUU; ++j ) { // KAISUU 回投げます pickup = rand() % 12; // 的に刺さった m[ i ].ave += nowTk.p[ pickup ]; // 点数加算 } } // 集計 for( i = 0; i < NINZU; ++i ) { m[ i ].ave /= static_cast<double>(KAISUU); // 平均 } // ソート qsort( m, NINZU, sizeof( MAN ), &myComp ); // 評価関数による評価 nowTk.point = myEval( m ); // 得点配列に入れる tokutenArray.push_back( nowTk ); } // 試行が終わった // 得点配列を、ポイントの高い(= 得点の低い)順にソート sort( tokutenArray.begin(), tokutenArray.end(), tokutenComp() ); // 現在の最低得点を下回ったか? if( tokutenArray[0].point < recordTk.point ) { recordTk = tokutenArray[0]; // 記録更新!!! TOKUTEN a = tokutenArray[0]; printf( "HIT! %2d [%2d] [%2d] [%2d] [%2d] [%2d] [%2d] [%2d] [%2d] [%2d] [%2d] [%2d] [%2d]?n", a.point, a.p[ 0], a.p[ 1], a.p[ 2], a.p[ 3], a.p[ 4], a.p[ 5], a.p[ 6], a.p[ 7], a.p[ 8], a.p[ 9], a.p[10], a.p[11] ); } nowTk = recordTk; printf( "result %2d [%2d] [%2d] [%2d] [%2d] [%2d] [%2d] [%2d] [%2d] [%2d] [%2d] [%2d] [%2d]?n", nowTk.point, nowTk.p[ 0], nowTk.p[ 1], nowTk.p[ 2], nowTk.p[ 3], nowTk.p[ 4], nowTk.p[ 5], nowTk.p[ 6], nowTk.p[ 7], nowTk.p[ 8], nowTk.p[ 9], nowTk.p[10], nowTk.p[11] ); // 適当に調整 for( k = 0; k < 12; ++k ) { nowTk.p[ k ] = rand() % 30 + 1; } sleep( 1 ); // のんびりいきまっしょい } return 0; }
とりあえず明日はずっと裏でぶん回しておこうと思います。
いつか最適解に近い値が得られるでしょう。こんぴーた万歳。