/@峰哥何峰 /
峰哥雖然后來去學(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())
#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 "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