我是否缺少对给定状态下的操作的检查?
Am I missing a check for the actions in the given state?
问题:
三对传统但嫉妒的夫妻需要过河。每对夫妇由丈夫和妻子组成。他们找到了一艘最多只能容纳两人的小船。找到最简单的渡河时间表,允许所有六个人过河,这样 none 的女性将与任何男性同行,除非她的丈夫在场。假设在下一次旅行之前所有在船上的乘客都已经上船,并且每次穿越至少有一个人在船上。
教授要求必须编辑代码。
我已经在这个问题上工作了 6 个小时,我被难住了。我的教授很忙,帮不上忙
我仔细看了你的代码。这确实是一个非常有趣且相当复杂的问题。一段时间后,我意识到可能导致您出现问题的原因是您在过境之前检查条件而不是事后。 A 看到了您提供的模板,我想我们可以尝试坚持 1- 使动作方法 return 所有可能的交叉(尚未检查状态)2- 给定每个动作,获得相应的新状态并检查该状态是否有效。 3- 制作 value() 方法来检查我们是否在优化方面取得进展。
class Problem:
def __init__(self, initial_state, goal):
self.goal = goal
self.record = [[0, initial_state, "LEFT", []]]
# list of results [score][state][boat_side][listActions]
def actions(self, state, boat_side):
side = 0 if boat_side == 'LEFT' else 1
boat_dir = 'RIGHT' if boat_side == 'LEFT' else 'LEFT'
group = [i for i, v in enumerate(state) if v == side]
onboard_2 = [[boat_dir, a, b] for a in group for b in group if
a < b and ( # not the same person and unique group
(a%2==0 and b - a == 1) or ( # wife and husband
a%2==0 and b%2==0) or ( # two wife's
a%2==1 and b%2==1) # two husbands
)]
onboard_1 = [[boat_dir, a] for a in group]
return onboard_1 + onboard_2
def result(self, state, action):
new_boat_side = action[0]
new_state = []
for i, v in enumerate(state):
if i in action[1:]:
new_state.append(1 if v == 0 else 0)
else:
new_state.append(v)
# check if invalid
for p, side, in enumerate(new_state):
if p%2 == 0: # is woman
if side != new_state[p+1]: # not with husband
if any(men == side for men in new_state[1::2]):
new_state = False
break
return new_state, new_boat_side
def goal_test(self, state):
return state == self.goal
def value(self, state):
# how many people already crossed
return state.count(1)
# optimization process
initial_state = [0]*6
goal = [1]*6
task = Problem(initial_state, goal)
while True:
batch_result = []
for score, state, side, l_a in task.record:
possible_actions = task.actions(state, side)
for a in possible_actions:
new_state, new_boat_side = task.result(state, a)
if new_state: # is a valid state
batch_result.append([
task.value(new_state),
new_state,
new_boat_side,
l_a + a,
])
batch_result.sort(key= lambda x: x[0], reverse= True)
# sort the results with the most people crossed
task.record = batch_result[:5]
# I am only sticking with the best 5 results but
# any number should be fine on this problem
if task.goal_test(task.record[0][1]):
break
# for i in task.record[:5]: # uncomment these lines to see full progress
# print(i)
# x = input() # press any key to continue
print(task.record[0][3])
希望对你有所帮助,有什么不明白的地方欢迎补充。
问题: 三对传统但嫉妒的夫妻需要过河。每对夫妇由丈夫和妻子组成。他们找到了一艘最多只能容纳两人的小船。找到最简单的渡河时间表,允许所有六个人过河,这样 none 的女性将与任何男性同行,除非她的丈夫在场。假设在下一次旅行之前所有在船上的乘客都已经上船,并且每次穿越至少有一个人在船上。
教授要求必须编辑代码。
我已经在这个问题上工作了 6 个小时,我被难住了。我的教授很忙,帮不上忙
我仔细看了你的代码。这确实是一个非常有趣且相当复杂的问题。一段时间后,我意识到可能导致您出现问题的原因是您在过境之前检查条件而不是事后。 A 看到了您提供的模板,我想我们可以尝试坚持 1- 使动作方法 return 所有可能的交叉(尚未检查状态)2- 给定每个动作,获得相应的新状态并检查该状态是否有效。 3- 制作 value() 方法来检查我们是否在优化方面取得进展。
class Problem:
def __init__(self, initial_state, goal):
self.goal = goal
self.record = [[0, initial_state, "LEFT", []]]
# list of results [score][state][boat_side][listActions]
def actions(self, state, boat_side):
side = 0 if boat_side == 'LEFT' else 1
boat_dir = 'RIGHT' if boat_side == 'LEFT' else 'LEFT'
group = [i for i, v in enumerate(state) if v == side]
onboard_2 = [[boat_dir, a, b] for a in group for b in group if
a < b and ( # not the same person and unique group
(a%2==0 and b - a == 1) or ( # wife and husband
a%2==0 and b%2==0) or ( # two wife's
a%2==1 and b%2==1) # two husbands
)]
onboard_1 = [[boat_dir, a] for a in group]
return onboard_1 + onboard_2
def result(self, state, action):
new_boat_side = action[0]
new_state = []
for i, v in enumerate(state):
if i in action[1:]:
new_state.append(1 if v == 0 else 0)
else:
new_state.append(v)
# check if invalid
for p, side, in enumerate(new_state):
if p%2 == 0: # is woman
if side != new_state[p+1]: # not with husband
if any(men == side for men in new_state[1::2]):
new_state = False
break
return new_state, new_boat_side
def goal_test(self, state):
return state == self.goal
def value(self, state):
# how many people already crossed
return state.count(1)
# optimization process
initial_state = [0]*6
goal = [1]*6
task = Problem(initial_state, goal)
while True:
batch_result = []
for score, state, side, l_a in task.record:
possible_actions = task.actions(state, side)
for a in possible_actions:
new_state, new_boat_side = task.result(state, a)
if new_state: # is a valid state
batch_result.append([
task.value(new_state),
new_state,
new_boat_side,
l_a + a,
])
batch_result.sort(key= lambda x: x[0], reverse= True)
# sort the results with the most people crossed
task.record = batch_result[:5]
# I am only sticking with the best 5 results but
# any number should be fine on this problem
if task.goal_test(task.record[0][1]):
break
# for i in task.record[:5]: # uncomment these lines to see full progress
# print(i)
# x = input() # press any key to continue
print(task.record[0][3])
希望对你有所帮助,有什么不明白的地方欢迎补充。