Python實現(xiàn)哲學(xué)家就餐問題實例代碼
哲學(xué)家就餐問題:
哲學(xué)家就餐問題是典型的同步問題,該問題描述的是五個哲學(xué)家共用一張圓桌,分別坐在五張椅子上,在圓桌上有五個盤子和五個叉子(如下圖),他們的生活方式是交替的進行思考和進餐,思考時不能用餐,用餐時不能思考。平時,一個哲學(xué)家進行思考,饑餓時便試圖用餐,只有在他同時拿到他的盤子左右兩邊的兩個叉子時才能進餐。進餐完畢后,他會放下叉子繼續(xù)思考。請寫出代碼來解決如上的哲學(xué)家就餐問題,要求代碼返回“當(dāng)每個哲學(xué)家分別需要進食 n 次”時這五位哲學(xué)家具體的行為記錄。

測試用例:
輸入:n = 1 (1<=n<=60,n 表示每個哲學(xué)家需要進餐的次數(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]]
思路:
輸出列表中的每一個子列表描述了某個哲學(xué)家的具體行為,它的格式如下:
output[i] = [a, b, c] (3 個整數(shù))
a 哲學(xué)家編號。
b 指定叉子:{1 : 左邊, 2 : 右邊}.
c 指定行為:{1 : 拿起, 2 : 放下, 3 : 吃面}。
如 [4,2,1] 表示 4 號哲學(xué)家拿起了右邊的叉子。所有自列表組合起來,就完整描述了“當(dāng)每個哲學(xué)家分別需要進食 n 次”時這五位哲學(xué)家具體的行為記錄。
代碼實現(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實現(xiàn)哲學(xué)家就餐問題的文章就介紹到這了,更多相關(guān)Python哲學(xué)家就餐內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
成功解決ValueError:?Supported?target?types?are:('binary
本文給大家分享成功解決ValueError:?Supported?target?types?are:('binary',?'multiclass').?Got?'continuous'?instead.的錯誤問題,需要的朋友可以參考下2023-03-03
python 實現(xiàn)將文件或文件夾用相對路徑打包為 tar.gz 文件的方法
今天小編就為大家分享一篇python 實現(xiàn)將文件或文件夾用相對路徑打包為 tar.gz 文件的方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-06-06
使用Python對Dicom文件進行讀取與寫入的實現(xiàn)
這篇文章主要介紹了使用Python對Dicom文件進行讀取與寫入的實現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-04-04
pytorch建立mobilenetV3-ssd網(wǎng)絡(luò)并進行訓(xùn)練與預(yù)測方式
這篇文章主要介紹了pytorch建立mobilenetV3-ssd網(wǎng)絡(luò)并進行訓(xùn)練與預(yù)測方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-02-02
一文教你用Python中progress庫實現(xiàn)進度條
這篇文章主要為大家詳細(xì)介紹了如何通過Python中的progress庫實現(xiàn)進度條的繪制,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-03-03

