使用Python PDDL框架实现TSP时遇递归深度超限错误求助
递归深度超限错误排查:基于pddl Python框架的TSP实现问题
我使用pddl Python框架实现旅行商问题(Travelling Salesman Problem,TSP),该框架可将Python代码转换为PDDL语言,再通过Fast-Downward执行。简单案例中领域与问题文件的生成及执行均正常,但新增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) # 获取领域和问题描述 domain = tsp.get_domain() problem = tsp.get_problem() # 将领域保存到domain.pddl文件 with open('domain.pddl', 'w') as domain_file: domain_file.write(domain) # 将问题保存到problem.pddl文件 with open('problem.pddl', 'w') as problem_file: problem_file.write(problem) # 定义要执行的命令 command = ["/home/mihai/tools/downward/fast-downward.py", "./domain.pddl", "./problem.pddl", "--heuristic", "h=ff()", "--search", "astar(h)"] # 执行命令 process = subprocess.run(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) # 检查执行是否成功 if process.returncode == 0: print("命令执行成功!") print(process.stdout) else: print("命令执行出错。") print("错误输出:\n", process.stderr)
pddl_domain_problem.py
# 基础领域与问题示例 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): # 变量与常量 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") # 谓词 self.p1 = Predicate("p1", self.x, self.y, self.z) self.p2 = Predicate("p2", self.x, self.y) # 领域与问题 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
# 旅行商问题基础领域与问题实现 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 # 表示城市间连接的元组列表 self.start_city = start_city # TSP的起始城市 # 从连接中提取唯一城市 unique_cities = set() for start, end in connections: unique_cities.update([start, end]) self.cities = variables(" ".join(unique_cities), types=["position"]) # 动作使用的单个城市变量 self.start = variables("start", types=["position"])[0] # 提取单个城市变量 self.finish = variables("finish", types=["position"])[0] # 提取单个城市变量 # 谓词 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] # 基于唯一城市定义对象 objects = self.cities # 初始状态 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_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)
报错信息
回溯(最近的调用最后): 文件 "/home/user/project/main.py", 第23行, 在 <module> tsp = TSPBasic(connections, start_city) 文件 "/home/user/project/tsp_basic.py", 第30行, 在 __init__ self.domain = self.create_domain() 文件 "/home/user/project/tsp_basic.py", 第51行, 在 create_domain domain = Domain( 文件 "/usr/local/lib/python3.10/dist-packages/pddl/core.py", 第77行, 在 __init__ self._check_consistency() 文件 "/usr/local/lib/python3.10/dist-packages/pddl/core.py", 第84行, 在 _check_consistency type_checker.check_type(self._actions) 文件 "/usr/lib/python3.10/functools.py", 第926行, 在 _method return method.__get__(obj, cls)(*args, **kwargs) 文件 "/usr/local/lib/python3.10/dist-packages/pddl/_validation.py", 第231行, 在 _ self.check_type(obj) 文件 "/usr/lib/python3.10/functools.py", 第926行, 在 _method return method.__get__(obj, cls)(*args, **kwargs) 文件 "/usr/local/lib/python3.10/dist-packages/pddl/_validation.py", 第309行, 在 _ self.check_type(action.effect) 文件 "/usr/lib/python3.10/functools.py", 第926行, 在 _method return method.__get__(obj, cls)(*args, **kwargs) 文件 "/usr/local/lib/python3.10/dist-packages/pddl/_validation.py", 第231行, 在 _ self.check_type(obj) 递归错误: 调用Python对象时超过最大递归深度
内容的提问来源于stack exchange,提问作者Mihai Daian
相关产品推荐
相关产品推荐

