简体   繁体   English

我是否缺少对给定 state 中的操作的检查?

[英]Am I missing a check for the actions in the given state?

The problem: Three traditional, but jealous, couples need to cross a river.问题:三对传统但嫉妒的夫妻需要过河。 Each couple consists of a husband and a wife.每对夫妇由丈夫和妻子组成。 They find a small boat that can contain no more than two persons.他们找到了一艘最多只能容纳两人的小船。 Find the simplest schedule of crossings that will permit all six people to cross the river so that none of the women shall be left in company with any of the men, unless her husband is present.找出最简单的渡河时间表,允许所有六个人过河,这样,除非她的丈夫在场,否则没有一个女人会和任何一个男人在一起。 It is assumed that all passengers on the boat onboard before the next trip and at least one person has to be in the boat for each crossing.假设在下一次旅行之前船上的所有乘客都已上船,并且每次穿越时至少有一个人必须在船上。

Had to edit out code, was requested by professor.必须编辑代码,应教授的要求。

I've been working on this problem for 6 hours and I am stumped.我已经在这个问题上工作了 6 个小时,但我很困惑。 My professor is busy and cannot help.我的教授很忙,帮不上忙。

I toke a careful look on your code.我仔细查看了您的代码。 It is indeed a very interesting problem and quite complex.这确实是一个非常有趣且相当复杂的问题。 After some while I realized that what maybe causing your problem is that your are checking the conditions before the crossing is made and not afterwords.一段时间后,我意识到可能导致您出现问题的原因是您正在检查交叉之前的条件,而不是后记。 A saw the template you provided and I guess we can try to stick with to logic proposed by 1- make the action method return all possible crosses (without checking the states yet) 2- given each action, get the corresponding new state and check if that state is valid. A 看到了您提供的模板,我想我们可以尝试坚持 1- 使操作方法返回所有可能的交叉(尚未检查状态)2- 给定每个操作,获取相应的新 state 并检查是否state 是有效的。 3- make the value() method to check if we are making progress on the optimization. 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])

I hope it helped, please fill free to say if anything is still not so clear.希望对您有所帮助,如果还有什么不明白的地方,请随意说。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM