Python中的旅行推销员PDDL

fslejnso  于 12个月前  发布在  Python
关注(0)|答案(1)|浏览(162)

我使用pddl python framework来实现旅行推销员问题。这个框架从python语言转换到pddl语言,然后用快速向下执行语言。我已经在一个简单的案例和域的生成以及问题上测试了它,然后我检查了输出并运行良好,但是当我使用一个新的类TSPBasic时,我得到了这个错误。我附上了main,工作类和TSPBasic类有问题。
main.py:

from pddl_domain_problem import PDDL
from tsp_basic import TSPBasic
import subprocess
from io_parser import parse_fast_downward_output

connections = [("Boston", "NewYork"),
               ("NewYork", "Boston"),
               ("Pittsburgh", "Boston"),
               ("Boston", "Pittsburgh"),
               ("Pittsburgh", "NewYork"),
               ("NewYork", "Pittsburgh"),
               ("Toronto", "Pittsburgh"),
               ("Toronto", "NewYork"),
               ("NewYork", "Toronto"),
               ("NewYork", "Albany"),
               ("Albany", "NewYork"),
               ("Albany", "Toronto"),
               ("Toronto", "Albany")]

start_city = "NewYork"

pddl = PDDL()
tsp = TSPBasic(connections, start_city)

# retrieve the domain and the problem
domain = tsp.get_domain()
problem = tsp.get_problem()

# Save the domain to a file named 'domain.pddl'
with open('domain.pddl', 'w') as domain_file:
    domain_file.write(domain)

# Save the problem to a file named 'problem.pddl'
with open('problem.pddl', 'w') as problem_file:
    problem_file.write(problem)

# Define the command to be executed
command = ["/home/mihai/tools/downward/fast-downward.py", "./domain.pddl", "./problem.pddl",
           "--heuristic", "h=ff()", "--search", "astar(h)"]

# Run the command
process = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True)

# Check if the process was successful
if process.returncode == 0:
    print("Command executed successfully!")
    print(process.stdout)
else:
    print("Error in command execution.")
    print("Error Output:\n", process.stderr)

字符串
pddl_domain_problem.py:

# demo for a basic case with domain and problem

from pddl.logic import Predicate, constants, variables
from pddl.core import Domain, Problem
from pddl.action import Action
from pddl.formatter import domain_to_string, problem_to_string
from pddl.requirements import Requirements

class PDDL:

    def __init__(self):
        # Variables and constants
        self.x, self.y, self.z = variables("x y z", types=["type_1"])
        self.a, self.b, self.c = constants("a b c", type_="type_1")

        # Predicates
        self.p1 = Predicate("p1", self.x, self.y, self.z)
        self.p2 = Predicate("p2", self.x, self.y)

        # Domain and problem
        self.domain = self.create_domain()
        self.problem = self.create_problem()

    def create_actions(self):
        a1 = Action(
            "action-1",
            parameters=[self.x, self.y, self.z],
            precondition=self.p1(self.x, self.y, self.z) & ~self.p2(self.y, self.z),
            effect=self.p2(self.y, self.z)
        )
        return [a1]

    def create_domain(self):
        requirements = [Requirements.STRIPS, Requirements.TYPING]
        return Domain("my_domain",
                      requirements=requirements,
                      types={"type_1": None},
                      constants=[self.a, self.b, self.c],
                      predicates=[self.p1, self.p2],
                      actions=self.create_actions())

    def create_problem(self):
        requirements = [Requirements.STRIPS, Requirements.TYPING]
        return Problem(
            "problem-1",
            domain=self.domain,
            requirements=requirements,
            objects=[],
            init=[self.p1(self.a, self.b, self.c), ~self.p2(self.b, self.c)],
            goal=self.p2(self.b, self.c)
        )

    def get_domain(self):
        return domain_to_string(self.domain)

    def get_problem(self):
        return problem_to_string(self.problem)


tsp_basic.py:

# travelling salesman domain and problem basic case

from pddl.logic import Predicate, variables
from pddl.core import Domain, Problem
from pddl.action import Action
from pddl.formatter import domain_to_string, problem_to_string
from pddl.requirements import Requirements

class TSPBasic:
    def __init__(self, connections, start_city):
        self.connections = connections  # List of tuples representing connections between cities
        self.start_city = start_city  # Starting city from the TSP

        # Extracting unique cities from connections
        unique_cities = set()
        for start, end in connections:
            unique_cities.update([start, end])
        self.cities = variables(" ".join(unique_cities), types=["position"])

        # Single city variables for actions
        self.start = variables("start", types=["position"])[0]  # Extract single city variable
        self.finish = variables("finish", types=["position"])[0]  # Extract single city variable

        # Predicates
        self.at = Predicate("at", self.start)
        self.connected = Predicate("connected", self.start, self.finish)
        self.visited = Predicate("visited", self.finish)

        self.domain = self.create_domain()
        self.problem = self.create_problem()

    def create_actions(self):
        move = Action(
            "move",
            parameters=[self.start, self.finish],
            precondition=self.at(self.start) &
                         self.connected(self.start, self.finish) &
                         ~self.visited(self.finish),
            effect="&".join([
                str(self.at(self.finish)),
                str(self.visited(self.finish)),
                "~" + str(self.at(self.start))
            ])
        )
        return [move]

    def create_domain(self):
        requirements = [Requirements.STRIPS, Requirements.TYPING, Requirements.NEG_PRECONDITION]

        domain = Domain(
            "tsp_basic_domain",
            requirements=requirements,
            types={"position": None},
            constants=[],
            predicates=[self.at, self.connected, self.visited],
            actions=self.create_actions()
        )

        return domain

    def create_problem(self):
        requirements = [Requirements.STRIPS, Requirements.TYPING]

        # Define objects based on unique cities
        objects = self.cities

        # Initial state
        init = [self.at(variables(self.start_city, types=["position"])[0])]
        for start, finish in self.connections:
            init.append(self.connected(variables(start, types=["position"])[0],
                                       variables(finish, types=["position"])[0]))

        # Goal state: all cities must be visited and return to start
        goal_conditions = [self.visited(city) for city in self.cities if city.name != self.start_city]
        goal_conditions.append(self.at(variables(self.start_city, types=["position"])[0]))
        goal = "&".join(goal_conditions)

        problem = Problem(
            "tsp_basic_problem",
            domain=self.domain,
            requirements=requirements,
            objects=objects,
            init=init,
            goal=goal
        )

        return problem

    def get_domain(self):
        return domain_to_string(self.domain)

    def get_problem(self):
        return problem_to_string(self.problem)


我得到的错误是:

Traceback (most recent call last):
  File "/home/user/project/main.py", line 23, in <module>
    tsp = TSPBasic(connections, start_city)
  File "/home/user/project/tsp_basic.py", line 30, in __init__
    self.domain = self.create_domain()
  File "/home/user/project/tsp_basic.py", line 51, in create_domain
    domain = Domain(
  File "/usr/local/lib/python3.10/dist-packages/pddl/core.py", line 77, in __init__
    self._check_consistency()
  File "/usr/local/lib/python3.10/dist-packages/pddl/core.py", line 84, in _check_consistency
    type_checker.check_type(self._actions)
  File "/usr/lib/python3.10/functools.py", line 926, in _method
    return method.__get__(obj, cls)(*args, **kwargs)
  File "/usr/local/lib/python3.10/dist-packages/pddl/_validation.py", line 231, in _
    self.check_type(obj)
  File "/usr/lib/python3.10/functools.py", line 926, in _method
    return method.__get__(obj, cls)(*args, **kwargs)
  File "/usr/local/lib/python3.10/dist-packages/pddl/_validation.py", line 309, in _
    self.check_type(action.effect)
  File "/usr/lib/python3.10/functools.py", line 926, in _method
    return method.__get__(obj, cls)(*args, **kwargs)
  File "/usr/local/lib/python3.10/dist-packages/pddl/_validation.py", line 231, in _
    self.check_type(obj)
RecursionError: maximum recursion depth exceeded while calling a Python object


有没有人可以看看这个错误?

vnjpjtjt

vnjpjtjt1#

你不能仅仅用字符串操作来合并。所以这是行不通的.

effect="&".join([
                str(self.at(self.finish)),
                str(self.visited(self.finish)),
                "~" + str(self.at(self.start))
            ])

字符串
但这将:

effect = self.at(self.finish) & self.visited(self.finish) & ~self.at(self.start)


它出现在tsp模型中的多个位置。

相关问题