Python實(shí)現(xiàn)哲學(xué)家就餐問題實(shí)例代碼
哲學(xué)家就餐問題:
哲學(xué)家就餐問題是典型的同步問題,該問題描述的是五個(gè)哲學(xué)家共用一張圓桌,分別坐在五張椅子上,在圓桌上有五個(gè)盤子和五個(gè)叉子(如下圖),他們的生活方式是交替的進(jìn)行思考和進(jìn)餐,思考時(shí)不能用餐,用餐時(shí)不能思考。平時(shí),一個(gè)哲學(xué)家進(jìn)行思考,饑餓時(shí)便試圖用餐,只有在他同時(shí)拿到他的盤子左右兩邊的兩個(gè)叉子時(shí)才能進(jìn)餐。進(jìn)餐完畢后,他會(huì)放下叉子繼續(xù)思考。請(qǐng)寫出代碼來解決如上的哲學(xué)家就餐問題,要求代碼返回“當(dāng)每個(gè)哲學(xué)家分別需要進(jìn)食 n 次”時(shí)這五位哲學(xué)家具體的行為記錄。
測(cè)試用例:
輸入:n = 1 (1<=n<=60,n 表示每個(gè)哲學(xué)家需要進(jìn)餐的次數(shù)。)
預(yù)期輸出:
[[4,2,1],[4,1,1],[0,1,1],[2,2,1],[2,1,1],[2,0,3],[2,1,2],[2,2,2],[4,0,3],[4,1,2],[0,2,1],[4,2,2],[3,2,1],[3,1,1],[0,0,3],[0,1,2],[0,2,2],[1,2,1],[1,1,1],[3,0,3],[3,1,2],[3,2,2],[1,0,3],[1,1,2],[1,2,2]]
思路:
輸出列表中的每一個(gè)子列表描述了某個(gè)哲學(xué)家的具體行為,它的格式如下:
output[i] = [a, b, c] (3 個(gè)整數(shù))
a 哲學(xué)家編號(hào)。
b 指定叉子:{1 : 左邊, 2 : 右邊}.
c 指定行為:{1 : 拿起, 2 : 放下, 3 : 吃面}。
如 [4,2,1] 表示 4 號(hào)哲學(xué)家拿起了右邊的叉子。所有自列表組合起來,就完整描述了“當(dāng)每個(gè)哲學(xué)家分別需要進(jìn)食 n 次”時(shí)這五位哲學(xué)家具體的行為記錄。
代碼實(shí)現(xiàn)
import queue import threading import time import random class CountDownLatch: def __init__(self, count): self.count = count self.condition = threading.Condition() def wait(self): try: self.condition.acquire() while self.count > 0: self.condition.wait() finally: self.condition.release() def count_down(self): try: self.condition.acquire() self.count -= 1 self.condition.notifyAll() finally: self.condition.release() class DiningPhilosophers(threading.Thread): def __init__(self, philosopher_number, left_fork, right_fork, operate_queue, count_latch): super().__init__() self.philosopher_number = philosopher_number self.left_fork = left_fork self.right_fork = right_fork self.operate_queue = operate_queue self.count_latch = count_latch def eat(self): time.sleep(0.01) self.operate_queue.put([self.philosopher_number, 0, 3]) def think(self): time.sleep(random.random()) def pick_left_fork(self): self.operate_queue.put([self.philosopher_number, 1, 1]) def pick_right_fork(self): self.operate_queue.put([self.philosopher_number, 2, 1]) def put_left_fork(self): self.left_fork.release() self.operate_queue.put([self.philosopher_number, 1, 2]) def put_right_fork(self): self.right_fork.release() self.operate_queue.put([self.philosopher_number, 2, 2]) def run(self): while True: left = self.left_fork.acquire(blocking=False) right = self.right_fork.acquire(blocking=False) if left and right: self.pick_left_fork() self.pick_right_fork() self.eat() self.put_left_fork() self.put_right_fork() break elif left and not right: self.left_fork.release() elif right and not left: self.right_fork.release() else: time.sleep(0.01) print(str(self.philosopher_number) + ' count_down') self.count_latch.count_down() if __name__ == '__main__': operate_queue = queue.Queue() fork1 = threading.Lock() fork2 = threading.Lock() fork3 = threading.Lock() fork4 = threading.Lock() fork5 = threading.Lock() n = 1 latch = CountDownLatch(5 * n) for _ in range(n): philosopher0 = DiningPhilosophers(0, fork5, fork1, operate_queue, latch) philosopher0.start() philosopher1 = DiningPhilosophers(1, fork1, fork2, operate_queue, latch) philosopher1.start() philosopher2 = DiningPhilosophers(2, fork2, fork3, operate_queue, latch) philosopher2.start() philosopher3 = DiningPhilosophers(3, fork3, fork4, operate_queue, latch) philosopher3.start() philosopher4 = DiningPhilosophers(4, fork4, fork5, operate_queue, latch) philosopher4.start() latch.wait() queue_list = [] for i in range(5 * 5 * n): queue_list.append(operate_queue.get()) print(queue_list)
總結(jié)
到此這篇關(guān)于Python實(shí)現(xiàn)哲學(xué)家就餐問題的文章就介紹到這了,更多相關(guān)Python哲學(xué)家就餐內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
成功解決ValueError:?Supported?target?types?are:('binary
本文給大家分享成功解決ValueError:?Supported?target?types?are:('binary',?'multiclass').?Got?'continuous'?instead.的錯(cuò)誤問題,需要的朋友可以參考下2023-03-03Python語言編寫電腦時(shí)間自動(dòng)同步小工具
家里有臺(tái)很多年前買的電腦,CMOS電池殘廢了,經(jīng)常遇到開機(jī)后系統(tǒng)時(shí)間被重置的情況2013-03-03python 實(shí)現(xiàn)將文件或文件夾用相對(duì)路徑打包為 tar.gz 文件的方法
今天小編就為大家分享一篇python 實(shí)現(xiàn)將文件或文件夾用相對(duì)路徑打包為 tar.gz 文件的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-06-06使用Python對(duì)Dicom文件進(jìn)行讀取與寫入的實(shí)現(xiàn)
這篇文章主要介紹了使用Python對(duì)Dicom文件進(jìn)行讀取與寫入的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04pytorch建立mobilenetV3-ssd網(wǎng)絡(luò)并進(jìn)行訓(xùn)練與預(yù)測(cè)方式
這篇文章主要介紹了pytorch建立mobilenetV3-ssd網(wǎng)絡(luò)并進(jìn)行訓(xùn)練與預(yù)測(cè)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02一文教你用Python中progress庫實(shí)現(xiàn)進(jìn)度條
這篇文章主要為大家詳細(xì)介紹了如何通過Python中的progress庫實(shí)現(xiàn)進(jìn)度條的繪制,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-03-03