編程的樂趣

/@峰哥何峰 /

峰哥雖然后來去學(xué)了個(gè) MBA,但其實(shí)本科時(shí)候是學(xué)習(xí)數(shù)學(xué)的,并且也曾經(jīng)會(huì)寫程序。畢業(yè)之后,做起了 management consulting, 讀了 MBA,編程技能就生疏了。

不過偶爾有機(jī)會(huì),還是會(huì)寫點(diǎn)代碼。從中獲得很大樂趣。比如上周【簡(jiǎn)單心理】工程師導(dǎo)出了一些數(shù)據(jù),需要分析。但是工程師開發(fā)太忙,而需要做的分析又足夠復(fù)雜到 Excel 不能勝任。于是乎峰哥自己手癢在周末寫了些代碼,搞的不亦樂乎。

周末的代碼不便分享,不過還是可以分享以前寫的另一個(gè)小程序。首先說明,我對(duì)自己的代碼能力還是有自知之明。在很多略懂編程的朋友看來,下面的代碼肯定是慘不忍睹。之所以還好意思拿出來分享,是因?yàn)槲蚁胫С忠粋€(gè)寫代碼的文化。在現(xiàn)代社會(huì),對(duì)電腦技術(shù)有個(gè)基本的了解,并且能夠?qū)懸恍┖?jiǎn)單的代碼,簡(jiǎn)直就想算數(shù)、識(shí)字、英語(yǔ)一樣重要。這是一個(gè)非常實(shí)用的技能,甚至像峰哥這樣粗糙的水平,也能夠派上用場(chǎng)。

并且,編程本身就是件非??鞓返氖虑椋?/p>

有個(gè)很好的活動(dòng)叫做 Rails Girls (http://railsgirlschina.org),是教女生學(xué)編程的活動(dòng)。峰哥大愛 ruby 語(yǔ)言,但是水平不足以當(dāng)教練,那就以自己的經(jīng)歷分享來支持!希望更多人(無(wú)論男生女生)會(huì)喜歡上編程:)

===

曾經(jīng)有人給我出了這么一道數(shù)學(xué)題:今有A、B、C 三門大炮。三門大炮的命中率分別是:

A:1/2

B:1/3

C:1/6

三門大炮互相開炮,問最后幸存的那門炮是A、B、C,以及大家同歸于盡的概率分別是幾何?

這道數(shù)學(xué)題是為了演示一個(gè)有點(diǎn)違背常理的結(jié)果:A、B 各自的最佳戰(zhàn)略是相互開炮,因?yàn)楸舜硕际菍?duì)方最大的敵人。結(jié)果就是反而是 C 很有可能成為最后的幸存者。

這個(gè)概念并不復(fù)雜,可到底 C 幸存的概率是多少?比 A、B 如何?要能夠量化的回答這個(gè)問題,還是需要比較繁瑣的概率分析。但是可能的情況很多,分析起來不厭其煩。有一個(gè)簡(jiǎn)單的方法:通過很多次模擬和統(tǒng)計(jì),求得概率的近似值。這也就是通常所說的 monte carlo method。

作為一個(gè) math 和 CS geek,我忍不住寫了一個(gè)簡(jiǎn)單的 python 程序。因?yàn)楹镁脹]有寫程序了,以前也沒有用過 python,所以程序?qū)懙南氡厥欠浅T愀?,但是結(jié)果是正確的。從中得到莫大樂趣。以下是模擬 30w 次后的結(jié)果??梢钥闯?C 幸存的概率遠(yuǎn)遠(yuǎn)高于 A、B。

這是 python 程序:

import random

class Cannon(object):

def __init__(self, name, accuracy):

self.name = name

self.accuracy = accuracy

self.alive = True

self.target = None

def setTarget(self, target):

self.target = target

def hit(self):

result = random.uniform(0, 1)

if result < self.accuracy:

#print "hit!"

self.target.alive = False

return True

else:

#print "miss!"

return False

def __str__(self):

return 'This cannon is named ' + self.name + ", accuracy " + str(self.accuracy)

def testCannon():

myCannon = Cannon('A', 0.5)

target = Cannon('target', 0)

hitcount, misscount = 0, 0

for i in range(0,500):

myCannon.setTarget(target)

if myCannon.hit() == 1:

hitcount = hitcount + 1

else:

misscount = misscount + 1

print "hit " + str(hitcount) + "? miss " + str(misscount)

class Game(object):

def __init__(self):

self.cannons = []

def addCannon(self, newCannon):

if newCannon in self.cannons:

raise ValueError('Duplicate cannon')

else:

self.cannons.append(newCannon)

def removeCannon(self, cannon):

if cannon in self.cannons:

self.cannons.remove(cannon)

else:

raise ValueError('Cannon not found')

def bestPlayer(self):

if len(self.cannons) == 0:

return None

bestcannon = self.cannons[0]

for cannon in self.cannons:

if bestcannon.accuracy > cannon:

bestcannon = cannon

return bestcannon

def secondBest(self):

if len(self.cannons) < 2:

return None

bestcannon = self.bestPlayer()

secondBest = self.cannons[0]

if secondBest == bestcannon:

secondBest = self.cannons[1]

for cannon in self.cannons:

if (secondBest.accuracy < cannon.accuracy) and (bestcannon != cannon):

secondBest = cannon

return secondBest

def endGame(self):

#print "there are " + str(len(self.cannons)) + "cannons right now."

if len(self.cannons) <= 1:

return True

else:

return False

def winner(self):

if not self.endGame():

return

if len(self.cannons) == 0:

#print "no winner!!!"

return None

else:

return self.cannons[0]

def printCannons(self):

for cannon in self.cannons:

print cannon

def setTargets(self):

best = self.bestPlayer()

secondBest = self.secondBest()

for cannon in self.cannons:

cannon.setTarget(best)

best.setTarget(secondBest)

#for cannon in self.cannons:

#? print str(cannon) + ' target is ' + str(cannon.target)

def fire(self):

if self.endGame():

print "Game ended."

return None

self.setTargets()

for cannon in self.cannons:

cannon.hit()

for i in range(len(self.cannons)-1, -1, -1):

#print i

if not self.cannons[i].alive:

#print "hahaha this one dead " + str(cannon)

del self.cannons[i]

#self.printCannons()

def play(self):

while not self.endGame():

self.fire()

#winner = self.winner()

def testGame():

game = Game()

cannonA = Cannon('A', 1.0/2)

cannonB = Cannon('B', 1.0/3)

cannonC = Cannon('C', 1.0/6)

game.addCannon(cannonA)

game.addCannon(cannonB)

game.addCannon(cannonC)

game.printCannons()

game.endGame()

print "best " + str(game.bestPlayer())

print "2nd best " + str(game.secondBest())

print

#game.removeCannon(cannonA)

#print game.bestPlayer()

game.play()

def gameRuns():

totalRuns = 300000

aCount, bCount, cCount, nowinner = 0, 0, 0, 0

for i in range(totalRuns):

game = Game()

cannonA = Cannon('A', 1.0/2)

cannonB = Cannon('B', 1.0/3)

cannonC = Cannon('C', 1.0/6)

game.addCannon(cannonA)

game.addCannon(cannonB)

game.addCannon(cannonC)

game.play()

winner = game.winner()

if winner == cannonA:

aCount = aCount + 1

elif winner == cannonB:

bCount = bCount + 1

elif winner == cannonC:

cCount = cCount + 1

else:

nowinner = nowinner + 1

print "game " + str(i),

if winner is None:

print ": No winner"

else:

print ": winner is " + str(winner.name)

print

print "total simulation runs: " + str(totalRuns)

print "A wins " + str(aCount*1.0/totalRuns)

print "B wins " + str(bCount*1.0/totalRuns)

print "C wins " + str(cCount*1.0/totalRuns)

print "no winner " + str(nowinner*1.0/totalRuns)

#print "total: " + str(aCount + bCount + cCount + nowinner) + " " +? str(totalRuns)

gameRuns()

======

簡(jiǎn)單心理

加入我們!戳 =>http://www.jiandanxinli.com/pages/37

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容