Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 用基本条带算法求解猴子和香蕉_Python - Fatal编程技术网

Python 用基本条带算法求解猴子和香蕉

Python 用基本条带算法求解猴子和香蕉,python,Python,我们被要求(做家庭作业)使用Python创建几个AI问题的解决方案,并对基本算法进行修改。目前,我正试图用它来解决猴子和香蕉的问题,并取得了一些成功,但在算法的行为方面有很多问题,我不确定我在这里遗漏了什么。当我试图让猴子把椅子推到某个地方并爬上去时,这段代码被删减了 from string import * class Stripper: # A STRIPS-style planner for the blocks world # Initialization code def

我们被要求(做家庭作业)使用Python创建几个AI问题的解决方案,并对基本算法进行修改。目前,我正试图用它来解决猴子和香蕉的问题,并取得了一些成功,但在算法的行为方面有很多问题,我不确定我在这里遗漏了什么。当我试图让猴子把椅子推到某个地方并爬上去时,这段代码被删减了

from string import *


class Stripper:
    # A STRIPS-style planner for the blocks world

# Initialization code
def __init__(self):
    """
    Initialize the global variables, and function dictionaries
    """
    self.worldStack = []
    self.goalStack = []
    self.plan = []

    # token to function mappings
    self.formulas = {"height": self.height, "at": self.at}
    self.Operators = {"GO": self.go, "PUSH": self.push,
                      "CLIMB": self.climb}

    # safety net tests are denoted by the following as the first list item.
    self.SafetyTag = "SAFETYTAG"

@staticmethod
def populate(strng, statestack):
    """
    Helper function that parses strng according to expectations
    and adds to the sateStack passed in.
    """
    for x in (strng.lower().replace('(', '').replace(')', '').split(',')):
        ls = x.strip().split(' ')
        statestack.append(ls)
    statestack.reverse()

def populategoal(self, strng):
    """
    Populate the goal stack with data in strng.
    """
    self.populate(strng, self.goalStack)
    # add original safety check
    goalcheck = [self.SafetyTag]
    for g in self.goalStack:
        goalcheck.append(g)
    self.goalStack.insert(0, goalcheck)

def populateworld(self, strng):
    """
    Populate the world state stack with data in strng.
    """
    self.populate(strng, self.worldStack)

# ----------------------------------------------------
# Solver
#   Attempts to solve the problem using the setup
#   goal and world states
# ----------------------------------------------------

def solve(self):
    """
    Attempts to solve the problem using STRIPS Algorithm
    Note: You need to setup the problem prior to running this
          by using populateWorld and populateGoal using a well
          formatted string.
    """
    if (not len(self.worldStack) > 0) or (not len(self.goalStack) > 0):
        print "\nNothing to do.\nMake sure you populate the problem using\n" \
              "populateWorld and populateGoal before calling this function."
        return
    while len(self.goalStack) > 0:
        # if the subgoal is in world state
        if self.top(self.goalStack) in self.worldStack:
            # pop it from the stack
            self.goalStack.pop()
        # if that item is an operator,
        elif self.top(self.goalStack)[0].upper() in self.Operators:
            subgoal = self.goalStack.pop()
            # store it in a "plan"
            self.plan.append(subgoal)
            # and modify the world state as specified
            self.Operators[(subgoal[0])](subgoal)
        # if the item is a safety check
        elif self.SafetyTag == self.top(self.goalStack)[0].upper():
            safetycheck = self.goalStack.pop()
            for check in safetycheck[1:]:
                if not (check in self.worldStack):
                    print " Safety net ripped.n Couldn't contruct a plan. Exiting...", check
                    return
        else:
            # find an operator that will cause the
            # top subgoal to result
            if self.top(self.goalStack)[0] in self.formulas:
                self.formulas[self.top(self.goalStack)[0]]()
            else:
                raise Exception(self.top(self.goalStack)[0] + " not valid formula/subgoal")
                # or add to goal stack and try, but not doing that for now.
    print "\nFinal Plan:\n",
    for step in self.plan:
        print "  ", join(step, " ").upper()

# ----------------------------------------------------
# Predicate logic
# ----------------------------------------------------
def at(self):
    topg = self.top(self.goalStack)
    assert(topg[0] == "at"), "expected at"
    assert(len(topg) == 3), "expected 3 arguments"
    print topg
    x = self.getloc(topg[1])
    if topg[1] == "monkey":
        self.goalStack.append(["GO", x, topg[2]])
        self.goalStack.append([self.SafetyTag, ["at", "monkey", x], ["height", "monkey", "low"]])
        self.goalStack.append(["at", "monkey", x])
        self.goalStack.append(["height", "monkey", "low"])
    else:
        self.goalStack.append(["PUSH", topg[1], x, topg[2]])
        self.goalStack.append([self.SafetyTag, ["at", topg[1], x], ["at", "monkey", x], ["height", "monkey", "low"],
                               ["height", topg[1], "low"], ["handempty"]])
        self.goalStack.append(["at", topg[1], x])
        self.goalStack.append(["at", "monkey", x])
        self.goalStack.append(["height", "monkey", "low"])
        self.goalStack.append(["height", topg[1], "low"])
        self.goalStack.append(["handempty"])

def height(self):
    topg = self.top(self.goalStack)
    print topg
    assert(topg[0] == "height"), "expected height"
    assert(len(topg) == 3), "expected 3 arguments"
    if topg[1] == "monkey":
        x = self.getloc("monkey")
        y = "low" if (self.getheight("monkey") == "low") else "high"
        self.goalStack.append(["CLIMB"])
        self.goalStack.append([self.SafetyTag, ["at", "monkey", x], ["at", "chair", x], ["height", "monkey", y],
                               ["height", "chair", "low"]])
        self.goalStack.append(["at", "chair", x])
        self.goalStack.append(["height", "monkey", y])
        self.goalStack.append(["height", "chair", "low"])
        self.goalStack.append(["at", "monkey", x])

# ----------------------------------------------------
# Operators
# ----------------------------------------------------

def go(self, subgoal):
    # deletion
    self.worldstateremove(["at", "monkey", subgoal[1]])
    # addition
    self.worldstateadd(["at", "monkey", subgoal[2]])

def push(self, subgoal):
    # deletion
    self.worldstateremove(["at", "monkey", subgoal[2]])
    self.worldstateremove(["at", subgoal[1], subgoal[2]])
    # addition
    self.worldstateadd(["at", subgoal[1], subgoal[3]])
    self.worldstateadd(["at", "monkey", subgoal[3]])

def climb(self, subgoal):
    # deletion
    self.worldstateremove(["height", "monkey", "low"])
    # addition
    self.worldstateadd(["height", "monkey", "high"])

# ----------------------------------------------------
# Utility functions
# ----------------------------------------------------

#  Returns the item that is being held in the world state, 0 if not
def getholdingitem(self):
    for x in self.worldStack:
        if x[0] == "holding":
            return x[1]
    return 0

# Return height of object
def getheight(self, item):
    for x in self.worldStack:
        if x[0] == "height" and x[1] == item:
            return x[2]
    raise Exception("Object " + item + " is on nothing!")

# Return location of object
def getloc(self, item):
    for x in self.worldStack:
        if x[0] == "at" and x[1] == item:
            return x[2]
    raise Exception("Object " + item + " has no location!")

# Adds a state to world state if the state isn't already true
def worldstateadd(self, toadd):
    if toadd not in self.worldStack:
        self.worldStack.append(toadd)

# Tries to remove the toRem state from the world state stack.
def worldstateremove(self, torem):
    while torem in self.worldStack:
        self.worldStack.remove(torem)

@staticmethod
def top(lst):
    """
    Returns the item at the end of the given list
    We don't catch an error because that's the error we want it to throw.
    """
    return lst[len(lst) - 1]
我已经设置了一些基本测试:

from monkey2 import Stripper


def runtests():

print "\n\nRunning Monkey-Banana Problem - Part 1\n"
ws = "((height chair low), (height monkey low), (handempty), (at monkey a), (at chair b))"
gs = "((at monkey d))"
s = Stripper()
s.populateworld(ws)
s.populategoal(gs)
s.solve()

print "\n\nRunning Monkey-Banana Problem - Part 2\n"
ws = "((height chair low), (height monkey low), (handempty), (at monkey a), (at chair b))"
gs = "((at monkey d), (height monkey high))"
s = Stripper()
s.populateworld(ws)
s.populategoal(gs)
s.solve()

print "\n\nRunning Monkey-Banana Problem - Part 2 Rearranged\n"
ws = "((height chair low), (height monkey low), (handempty), (at monkey a), (at chair b))"
gs = "((height monkey high), (at monkey d))"
s = Stripper()
s.populateworld(ws)
s.populategoal(gs)
s.solve()

if __name__ == "__main__":
    runtests()
对于测试第2部分,它是有效的,但是当它被重新排列时,猴子会被卡住,我知道这可能很简单,但我不太明白为什么我的算法不够健壮,无法处理这个问题。有人能看到我遗漏了什么吗?或者给我指出正确的方向

我觉得问题在于base solve()方法,因为它不允许回溯