iT邦幫忙

2017 iT 邦幫忙鐵人賽
DAY 42
0
自我挑戰組

從科展學寫程式系列 第 33

33 柏拉圖問題 競爭模型對拿取總價值的影響 III

最近幾天都超級忙,我去參加了很多的營隊。一個三天兩夜,一個兩天來回。昨天補眠補到中午後來想程式,寫完之後發現有bug,又一直找不出來...

1/20~1/22 國中生物科技體驗營 in 北醫大
1/23~1/24 永中八資寒假課程 in 永中&清大
1/25 找程式都找不出來 at home

好吧,接續上一次的問題。

我不想算上一篇S=3,4,5,6的了...直接來寫程式吧~


在這個主題的intro當中,有提到分成兩種路徑方式,裡面有分「別人的選擇無關我的選擇」和「別人的選擇有關我的選擇」不過一直到現在都是致力於「第二種」。第二種的定義如下:

1.在一條商店街上,你跟對手站在商店街的兩端。
2.你往前走一家店,他就往前走一家店。你們兩個是同進的。
3.你跟對方要互相聯繫,你要告訴他這家店花的分數,他也必須告訴你他那家店花的分數。
4.拿到就要立即告訴對方“價值”,直到兩個人都拿完。取價值大的一方獲勝。

第一篇裡有寫把第二個人當成朋友,他不會拿取,看最後拿到最大值的機率的程式。最後跑出來的如下圖:
http://ithelp.ithome.com.tw/upload/images/20170126/20103852Oc5UTNOIVn.png

可以拿到最大值的機率最高可以到達66.908%,策略則是要從全部的23%之後再開始考慮拿取就可以了~

接下來所要討論的是關於「敵人」。也就是第二個人會跟你競爭價值最大的大一朵花,他一樣告訴你他那家店的價值為何,反之亦然。我就直接寫一個程式來做這件事,最後寫成這樣:(寫了兩天XD)

<?php

if (isset($argv))
    for ($i=1;$i<count($argv);$i++)
    {
        $it = explode("=",$argv[$i]);
        $_GET[$it[0]] = $it[1];
    }

$n="\n";
$brn="<br />\n";

date_default_timezone_set("Asia/Taipei");

//設定變數

//mode=0 無變數
//mode=1 凋謝速率
//mode=2 員工貢獻度
//mode=3 競爭
//mode=4 參考 v(敵人)

if(isset($_GET['debug'])) $debug=$_GET['debug'];
else $debug=1;//顯示步驟

if(isset($_GET['from'])) $from=$_GET['from'];
else $from=0;

if(isset($_GET['to'])) $to=$_GET['to'];
else $to=100;

if(isset($_GET['choice_time'])) $choice_time=$_GET['choice_time'];
else $choice_time=1;

if(isset($_GET['limit'])) $limit=$_GET['limit'];
else $limit=100;

if(isset($_GET['gap'])) $gap=$_GET['gap'];
else $gap=0.1;

if(isset($_GET['loop_num'])) $loop_num=$_GET['loop_num'];
else $loop_num=50;

printf("date,percent,=>,best,fail,fine,win $n");

 for($k=$from;$k<=$to;$k=$k+$gap){

 $percent=$k;

 $best=0;
 $fail=0;
 $fine=0;
 $win=0;

 if($debug>1){
  echo "From: ", $from, $n;
  echo "To: ", $to, $n;
  echo "Limit: ", $limit, $n;
  echo "Percent: ", $percent, $n;
  echo "Border: ", $limit*$percent/100, $n;
 } 
  
 for($j=0;$j<$loop_num;$j++){
  //變數設定
  
  $max_num=0;
  
  $max_percent=$limit*$percent/100;
  $army_max_percent=$limit*(100-$percent)/100;
  
  $percent_num=0;
  $army_percent_num=0;
  
  $choice=0;
  $army_choice=0;
  
  $time=0;
  $army_time=0;
  
  $thisnum=range(1,$limit,1);//(小,大,差)
  shuffle($thisnum);//洗牌
  
   for($i=0;$i<$limit;$i++){
    
    if($i>=$max_percent and $i-1<$max_percent) $time=$choice_time;
    if($limit-$i>=$army_max_percent and $limit-$i-1<$army_max_percent) $army_time=$choice_time;
    
    $num=$thisnum[$i];//我方此家分數
    $army_num=$thisnum[$limit-$i-1];//敵方此家分數
    
    if($max_num<=$num) $max_num=$num;//找尋最大值
    if($max_num<=$army_num) $max_num=$army_num;
    
    if($percent_num<$num) $percent_num=$num;
    if($army_percent_num<$army_num) $army_percent_num=$army_num;
    
    if($time>0 and $num>=$percent_num and $num>=$army_percent_num) {
    $choice=$choice+$num;
    $time=$time-1;
    $thisnum[$i]=0;
    }//拿走
    
    if($army_time>0 and $army_num>=$army_percent_num and $army_num>=$percent_num) {
    $army_choice=$army_choice+$army_num;
    $army_time=$army_time-1;
    $thisnum[$limit-$i-1]=0;
    }//敵方拿走
    
    if($debug>0) echo $i+1, " ", $num, " ", $army_num, "  ", $percent_num, " ", $army_percent_num, "  ", $time, " ", $army_time, $n;//顯示資訊
    
   }
  
  if($debug>0){
   echo "Choice: ", $choice, ",", $army_choice, $n;
   echo "Max: ", $max_num, $n;
  }
  
  if($max_num==$choice) $best++;
  if($choice==0) $fail++;
  if($max_num>$choice and $choice>0) $fine++;
  if($choice>$army_choice) $win++;
  
 }  

 $thedate=date("m-d H:i");
 printf("%s,%.1f,=>,%.7f,%.7f,%.7f,%.7f,(%.0f/%.0f)\n", $thedate, $percent, $best/$loop_num, $fail/$loop_num, $fine/$loop_num, $win/$loop_num, log($loop_num, 10), log($limit, 10));

} 

?>

差不多就這樣吧,我發誓明天一定會發文的~~


上一篇
32 柏拉圖問題 競爭模型對拿取總價值的影響 II
下一篇
34 柏拉圖問題 敵人與自己的策略不一對勝率的影響 I
系列文
從科展學寫程式43

尚未有邦友留言

立即登入留言