小孩分油問題

2021-09-29 12:00:54 字數 2582 閱讀 2058

1.問題描述

兩個小孩去打油,一人帶了乙個一斤的空瓶,另乙個帶了乙個七兩、乙個三兩的空瓶。原計畫各打一斤油,可是由於所帶的錢不夠,只好兩人合打了一斤油,在回家的路上,兩人想平分這一斤油,可是又沒有其它工具,試僅用三個瓶子(一斤、七兩、三兩)精確地分成兩個半斤油來。

2.演算法設計

假設狀態a(x1,x2,x3)表示依次表示一斤,七兩,三兩瓶子中含油量為x1,x2,x3

每乙個瓶子含油量為0則不變。如果含油量不為0則可以選擇向其他兩個瓶子倒油,倒油的情況又可以分為兩種:1.當前瓶子剩餘油量不夠倒滿其他某個瓶子;2.當前瓶子剩餘油量足夠倒滿其他的某個瓶子

3.程式流程

1.將初始狀態s(10,0,0)加入到佇列之中。

2.從佇列中取出隊首元素對應的狀態a,狀態a進行寬度優先搜尋,狀態a擴充得到的狀態b,如果狀態b即為目標狀態(5,5,0)側退出搜尋,轉到步驟5。

3.判斷狀態b是否在佇列中,不在的話就新增至佇列末尾,並且記錄下狀態b的前乙個狀態為狀態a,方便找到目標狀態之後尋找解的路徑。已經在佇列中的話側跳過

4.用狀態a搜尋完所有的下乙個狀態之後,狀態a出隊,判斷佇列是否為空,為空的話就停止搜尋,宣告搜尋失敗;佇列不為空的話就轉到步驟2

5.搜尋過程中記錄了每個狀態的前乙個狀態,所以可以利用目標狀態輸出整個搜尋路徑。

4.**實現

import copy

class path(object):

def __init__(self, p, pre=-1):

self.p = p #當前狀態

self.pre = pre #前一步

def pour(i, j, p): #倒油處理

if p[i] >= (cap[j]-p[j]): #當前瓶子剩餘油量足夠倒滿其他的某個瓶子

p[i] = p[i]-(cap[j]-p[j])

p[j] = cap[j]

else: #當前瓶子剩餘油量不夠倒滿其他某個瓶子

p[j] += p[i]

p[i] = 0

def bfs(start, que):

front, tail = 0, 0

que[tail] = start

# que[tail].p = start.p

# que[tail].pre = start.pre

tail += 1

book[start.p[0]*100 + start.p[1]*10 + start.p[2]] = 1 #避免出現重複的狀態

while front <= tail:

node = que[front]

for i in range(0, 3):

if node.p[i] != 0:

for j in range(1, 3):

temp = copy.deepcopy(node.p)

pour(i, (i+j)%3, temp)

if (temp[0]==5 and temp[1]==5):

que[tail].p = temp

que[tail].pre = front

output(que[tail])

print("")

# return tail

if book[temp[0] * 100 + temp[1]*10 + temp[2]]:

continue

book[temp[0] * 100 + temp[1]*10 + temp[2]] = 1

que[tail].p = temp

que[tail].pre = front

tail += 1

front += 1

def output(node):

if node.pre == -1:

print(node.p)

return

output(que[node.pre])

print(node.p)

start = path([10, 0, 0], -1)

cap = [10, 7, 3]

que = [path(none) for i in range(100)] #假設最多一百步

book = [0]*100000

end = bfs(start, que)

# output(que[end])

6.結論油瓶分油問題借助廣度優先搜尋樹可以得到較好的解決。只要問題有解,廣度優先搜尋一定能在有限步內找到解且路徑最短。但是隨著深度的增加,結點數目指數增長,導致組合**。導致空間占用**。最後是可以利用啟發式搜尋效率會更高一些。

程式碎片 分油問題 bfs

這個問題是看演算法精華版時候看見的,人家的演算法看了很頭大,自己寫一遍後覺得清楚多了 using system using system.collections.generic using system.linq using system.text using system.windows.form...

三個油瓶分油問題

原問題 兩個小孩去打油,乙個人帶了乙個一斤的空瓶,另乙個帶了乙個七兩乙個三兩的空瓶。原計畫各打一斤油,可是由於所帶的錢不夠,只好兩人合打了一斤油,可是又沒有其它工具,試僅用三個瓶子 一斤 七兩 三兩 精確地分成兩個半斤油來。a.將分油問題構造的多叉樹存入佇列oilqueue 中,盡量將在陣列 arr...

小孩報數問題

description 有n個小孩圍成一圈,給他們從1開始依次編號,現指定從第w個開始報數,報到第s個時,該小孩出列,然後從下乙個小孩開始報數,仍是報到s個出列,如此重複下去,直到所有的小孩都出列 總人數不足s個時將迴圈報數 求小孩出列的順序。input 第一行輸入小孩的人數n n 64 接下來每行...