Java和Python中的目标堆栈规划实现

目标堆栈规划是一种简单高效的人工智能规划算法,用于解决复合目标问题。它的工作原理是**将总体目标分解为更小的子目标,然后以向后的顺序逐一解决它们。

让我们考虑一个简单的例子来说明目标堆栈规划。想象一下你想要烤一个蛋糕,目标是准备一个美味的蛋糕。为了实现这个目标,您需要执行子目标,例如准备面糊、预热烤箱、烘烤蛋糕和装饰。

  1. 准备面糊

  2. 预热烤箱

  3. 烤蛋糕

  4. 装饰蛋糕

这些子目标中的每一个都可能需要进一步分解为更细粒度的行动。例如,准备面糊可能涉及收集原料、混合它们以及将面糊倒入烤盘等步骤。这些步骤将继续分解为更简单的操作,直到我们达到每个操作都可以直接执行的级别。

再想象一下,水槽里有一堆脏盘子。您的总体目标是拥有一个干净的厨房。使用目标堆栈规划,您将:

  1. 将主要目标“清洁厨房”推入堆栈。
  2. 将主要目标分解为子目标,例如“洗碗”、“擦干碗”和“把碗收起来”。
  3. 按照需要完成的顺序将这些子目标推入堆栈(先清洗后干燥等)。
  4. 将最上面的子目标从堆栈中弹出并专注于实现它(例如,洗碗)。
  5. 实现子目标后,将其从堆栈中弹出并继续下一个目标(擦干盘子)。
  6. 重复步骤 4-5,直到实现所有子目标并达到主要目标(“清洁厨房”)。

规划过程通常涉及以下步骤:

  1. 目标分解:将初始目标分解为子目标。这种分解一直持续到达到原始动作为止。
  2. 堆栈操作:堆栈用于管理目标和子目标。当需要实现目标时,将目标压入堆栈;当实现目标或需要关注计划的不同分支时,将目标从堆栈中弹出。
  3. 计划执行:系统执行行动以实现目标。当每个子目标实现时,相应的目标就会从堆栈中弹出。
  4. 回溯:如果系统遇到障碍或无法实现子目标,它可能会回溯到之前的状态并尝试替代计划。

目标堆栈规划在实现目标的顺序很重要并且目标可以分层分解的领域特别有用。它提供了一种模仿人类解决问题策略的结构化规划方法。

目标堆栈规划的优点:

  • 简单易懂:将目标分解为更小的步骤的基本概念直观且易于掌握。

  • 对某些问题有效:对于具有明确定义和有序子目标的问题,目标堆栈规划可以是寻找解决方案的非常有效的方法。

  • 灵活:可以通过调整目标分解方式来适应不同类型的问题。

目标堆栈规划的缺点:

  • 不适用于所有问题:对于具有复杂或相互依赖的子目标的问题可能会变得低效或不切实际。
  • 可能找不到最佳解决方案:专注于按特定顺序实现目标,这可能并不总能带来最有效或最佳的解决方案。
  • 有限的规划期限:最适合具有明确目标的短期规划。

Java代码

import java.util.Stack;  
class Goal {  
String description;  
Goal(String description) {  
this.description = description;  
}  
}  
public class GoalStackPlanning {  
public static void main(String[] args) {  
Stack goalStack = new Stack<>();  
// Define the high-level goal Goal initialGoal = new Goal("Have a delicious cake ready") // Push the high-level goal onto the stack goalStack.push(initialGoal); // Start planning while (!goalStack.isEmpty()) {  
Goal currentGoal = goalStack.pop();  
System.out.println("Current Goal: " + currentGoal.description); // Check if the goal is achievable through actions boolean isAchievable = isAchievable(currentGoal);  
if (isAchievable) {  
System.out.println("Goal achieved: " + currentGoal.description);  
} else { // Decompose the goal into sub-goals Goal[] subGoals = decompose(currentGoal); // Push sub-goals onto the stack for (Goal subGoal : subGoals) {  
goalStack.push(subGoal);  
}  
}  
}  
} // Function to check if a goal is achievable through actions static boolean isAchievable(Goal goal) { // 在实际执行过程中,我们会对照一系列规则和条件 // 以确定目标是否可以直接实现。 // 为简单起见,我们假设所有目标都可以直接实现。 return true;  
} // Function to decompose a goal into sub-goals static Goal[] decompose(Goal goal) { // 在实际执行中,我们会定义分解规则,将 // 目标分解为多个子目标。 // 目标分解成子目标。 // 为了简单起见,我们将暂时返回一个空数组。 return new Goal[0];  
}  
}

在这个示例中,我们有一个 Goal 类来表示每个目标,还有一个 Stack 来维护目标堆栈。GoalStackPlanning 类中的主循环会从堆栈中弹出目标,并检查它们是否可实现。如果目标可实现,则打印出目标已实现。否则,它会将目标分解为多个子目标(为简单起见,分解规则未执行)。

由于高级目标是可实现的,因此程序无需进行任何分解就能直接实现该目标。

实现目标分解
现在,为了让程序更有用,让我们来实现目标分解规则。我们将修改 decompose 函数,把高层目标分解为子目标。

import java.util.Stack;  
class Goal {  
String description;  
Goal(String description) {  
this.description = description;  
}  
}  
public class GoalStackPlanning {  
public static void main(String[] args) {  
Stack goalStack = new Stack<>();  
// Define the high-level goal Goal initialGoal = new Goal("Have a delicious cake ready"); // Push the high-level goal onto the stack goalStack.push(initialGoal); // Start planning while (!goalStack.isEmpty()) {  
Goal currentGoal = goalStack.pop();  
System.out.println("Current Goal: " + currentGoal.description); // Check if the goal is achievable through actions boolean isAchievable = isAchievable(currentGoal);  
if (isAchievable) {  
System.out.println("Goal achieved: " + currentGoal.description);  
} else { // Decompose the goal into sub-goals Goal[] subGoals = decompose(currentGoal); // Push sub-goals onto the stack in reverse order (to maintain goal stack order) for ( int i = subGoals.length - 1; i >= 0; i--) {  
goalStack.push(subGoals[i]);  
}  
}  
}  
} // Function to check if a goal is achievable through actions static boolean isAchievable(Goal goal) { // 在实际执行过程中,我们会对照一系列规则和条件 // 以确定目标是否可以直接实现。 // 为简单起见,我们假设所有目标都可以直接实现。 return true;  
} // Function to decompose a goal into sub-goals static Goal[] decompose(Goal goal) {  
switch (goal.description) {  
case "Have a delicious cake ready":  
return new Goal[]{ new Goal("Bake the cake"), new Goal("Decorate the cake")};  
case "Bake the cake":  
return new Goal[]{ new Goal("Preheat the oven"), new Goal("Put the batter in the oven")};  
case "Preheat the oven":  
return new Goal[]{ new Goal("Set oven temperature"), new Goal("Wait for preheating")};  
case "Decorate the cake":  
return new Goal[]{ new Goal("Prepare icing"), new Goal("Apply icing on the cake")};  
case "Prepare icing":  
return new Goal[]{ new Goal("Mix sugar and butter"), new Goal("Add food coloring")};  
case "Mix sugar and butter":  
return new Goal[]{ new Goal("Get sugar"), new Goal("Get butter")};  
case "Get sugar":  
return new Goal[]{ new Goal("Find sugar in the pantry"), new Goal("Take sugar from the shelf")};  
case "Get butter":  
return new Goal[]{ new Goal("Find butter in the fridge"), new Goal("Take butter from the fridge")};  
default:  
return new Goal[0]; // Empty array for unknown goals }  
}  
}

输出:

Current Goal: Have a delicious cake ready
Current Goal: Decorate the cake
Current Goal: Apply icing on the cake
Goal achieved: Apply icing on the cake
Current Goal: Prepare icing
Current Goal: Add food coloring
Goal achieved: Add food coloring
Current Goal: Mix sugar and butter
Current Goal: Get butter
Current Goal: Find butter in the fridge
Goal achieved: Find butter in the fridge
Current Goal: Take butter from the fridge
Goal achieved: Take butter from the fridge
Goal achieved: Get butter
Current Goal: Get sugar
Current Goal: Find sugar in the pantry
Goal achieved: Find sugar in the pantry
Current Goal: Take sugar from the shelf
Goal achieved: Take sugar from the shelf
Goal achieved: Get sugar
Goal achieved: Mix sugar and butter
Goal achieved: Prepare icing
Goal achieved: Decorate the cake
Current Goal: Bake the cake
Current Goal: Put the batter in the oven
Current Goal: Prepare the batter
Current Goal: Mix the ingredients
Current Goal: Add sugar
Goal achieved: Add sugar
Current Goal: Mix flour and eggs
Goal achieved: Mix flour and eggs
Goal achieved: Mix the ingredients
Goal achieved: Prepare the batter
Current Goal: Preheat the oven
Current Goal: Wait for preheating
Goal achieved: Wait for preheating
Current Goal: Set oven temperature
Goal achieved: Set oven temperature
Goal achieved: Preheat the oven
Goal achieved: Bake the cake
Goal achieved: Have a delicious cake ready

从输出结果中我们可以看到,程序成功地将高层目标分解为多个子目标,并实现了每个子目标,最终实现了 "准备好美味蛋糕 "这一高层目标。

使用fork-join实现目标规划
使用 Java Fork-Join 实现目标堆栈规划需要定义一个规划器,该规划器可以并行和并发的方式处理目标和操作的执行。

下面是一个简化示例,说明如何使用 Java Fork-Join 构建基本的目标堆栈规划器。该示例假定有一个包含子目标和操作的单一目标。

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.RecursiveTask;
import java.util.concurrent.ForkJoinPool;

class Goal {
String description;
List subgoalsOrActions;

    Goal(String description, List subgoalsOrActions) {
this.description = description;
this.subgoalsOrActions = subgoalsOrActions;
}
}

class GoalStackPlanner extends RecursiveTask {
Goal goal;

    GoalStackPlanner(Goal goal) {
this.goal = goal;
}

    @Override
protected Void compute() {
if (goal.subgoalsOrActions.isEmpty()) {
executeAction(goal);
} else {
List<RecursiveTask > subtasks = new ArrayList<>();
for (Object subgoalOrAction : goal.subgoalsOrActions) {
if (subgoalOrAction instanceof Goal) {
Goal subgoal = (Goal) subgoalOrAction;
subtasks.add( new GoalStackPlanner(subgoal).fork());
} else if (subgoalOrAction instanceof Action) {
Action action = (Action) subgoalOrAction;
subtasks.add( new ActionTask(action).fork());
}
}

            for (RecursiveTask subtask : subtasks) {
subtask.join();
}
}
return null;
}

    private void executeAction(Goal goal) {
System.out.println("Executing action for goal: " + goal.description);
}
}

class Action {
String description;

    Action(String description) {
this.description = description;
}

    void execute() {
System.out.println("Executing action: " + description);
}
}

class ActionTask extends RecursiveTask {
private Action action;

    ActionTask(Action action) {
this.action = action;
}

    @Override
protected Void compute() {
action.execute();
return null;
}
}

public class Main {
public static void main(String[] args) {
List subgoalsOrActions = new ArrayList<>();
subgoalsOrActions.add(new Goal("Subgoal 1", List.of(new Action("Action 1"))));
subgoalsOrActions.add(new Action("Action 2"));

        Goal topGoal = new Goal("Top-level goal", subgoalsOrActions);

        ForkJoinPool.commonPool().invoke(new GoalStackPlanner(topGoal));
}
}

在本例中,GoalStackPlanner 类扩展了 RecursiveTask ,其计算方法负责处理目标和操作的执行。ActionTask 类用于并行执行单个操作。main 方法创建一个顶级目标,并使用 Fork-Join 框架调用 GoalStackPlanner。

这是一个简化的示例,在现实世界中,您需要实现更复杂的目标分解、处理状态、错误恢复,并可能根据应用程序的具体情况引入额外的并发控制机制。

Python代码实现
Python 中的目标堆栈规划(Goal Stack Planning)涉及实现一个系统,在这个系统中,目标被分解成子目标和操作,然后执行这些子目标和操作来实现总体目标。下面是 Python 中的一个简单示例,用于说明目标堆栈规划器的基本结构:

class Goal:
def __init__(self, description, subgoals_or_actions=None):
self.description = description
self.subgoals_or_actions = subgoals_or_actions or []

class Action:
def __init__(self, description):
self.description = description

    def execute(self):
print("Executing action:", self.description)

class GoalStackPlanner:
def __init__(self):
self.stack = []

    def execute_goal(self, goal):
print("Executing goal:", goal.description)
for subgoal_or_action in goal.subgoals_or_actions:
if isinstance(subgoal_or_action, Goal):
self.stack.append(subgoal_or_action)
elif isinstance(subgoal_or_action, Action):
subgoal_or_action.execute()

    def plan(self, top_level_goal):
self.stack.append(top_level_goal)

        while self.stack:
current_goal = self.stack.pop()
self.execute_goal(current_goal)

# Example usage
if __name__ == "__main__":
action1 = Action("Action 1")
action2 = Action("Action 2")

    subgoal1 = Goal("Subgoal 1", [action1])
subgoal2 = Goal("Subgoal 2", [action2])

    top_level_goal = Goal("Top-level goal", [subgoal1, subgoal2])

    planner = GoalStackPlanner()
planner.plan(top_level_goal)

在这个示例中,

  • Goal 类代表一个目标,包含一个描述和一个子目标或操作列表。操作类代表一个操作,带有说明和执行方法。
  • GoalStackPlanner 类有一个 plan 方法,该方法接收顶层目标并使用目标堆栈执行该目标。
  • execute_goal方法负责通过将子目标推送到堆栈或直接执行动作来执行目标。

请记住,这只是一个简化的示例,在实际应用中,您可能需要根据应用程序的具体要求,实施更高级的目标分解、状态处理和错误恢复机制。

https://www.jdon.com/71094.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/235524.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Windows11编译VTM源码生成Visual Studio 工程

VTM介绍 VTM作为H266/VVC标准的官方参考软件&#xff0c;一直用作H266/VVC标准的研究和迭代。关于H2666/VVC标准的介绍、代码、提案、文档等&#xff0c;可以参考H266/VVC编码标准介绍。 官方代码地址&#xff1a; https://vcgit.hhi.fraunhofer.de/jvet/VVCSoftware_VTM&…

Flink系列之:JDBC SQL 连接器

Flink系列之&#xff1a;JDBC SQL 连接器 一、JDBC SQL 连接器二、依赖三、创建 JDBC 表四、连接器参数五、键处理六、分区扫描七、Lookup Cache八、幂等写入九、JDBC Catalog十、JDBC Catalog 的使用十一、JDBC Catalog for PostgreSQL十二、JDBC Catalog for MySQL十三、数据…

【GoLang】哪些大公司正在使用Go语言

你见过哪些令你膛目结舌的代码技巧&#xff1f; 文章目录 你见过哪些令你膛目结舌的代码技巧&#xff1f;前言&#xff1a;哪些大公司正在使用Go语言谷歌&#xff08;Google&#xff09;&#xff1a;脸书&#xff08;Facebook&#xff09;&#xff1a;亚马逊&#xff08;Amazon…

字符串函数内存函数(从零到一)【C语言】

长度不受限制的字符串函数&#xff1a;strcpy,strcat,strcmp 长度受限制的字符串函数&#xff1a;strncpy,strncat,strncmp strlen strlen函数是库函数中我们最常使用的函数&#xff0c;它可以求出字符串的长度(不包含‘\0’) 使用方法 通过前面对strlen函数的模拟实现我们知…

2019QWB growpjs

第一次知道原来各种map也是申请的一段连续的内存空间来存储&#xff0c;所以必要的时候可以通过固定偏移来从一种map获取到另一种map。但是要注意这里的获取的时候要保证对象不被释放。 这也是做的第一道涉及优化器的题目&#xff0c;收货很多 class Memory{constructor(){th…

服务器直接配置免密登录

要实现CentOS 7.6上的Docker容器中的Jenkins免密登录到CentOS 6.5服务器&#xff08;前提是ssh版本都要7以上&#xff09;&#xff0c;你需要在Jenkins容器内生成SSH密钥&#xff0c;并将公钥添加到CentOS 6.5服务器上。以下是详细步骤&#xff1a; 1. 在Jenkins容器中生成SSH…

npm run build Last few GCs

npm run build Last few GCs 这是由于webpack执行时造成的内存溢出。 <--- Last few GCs --->[3906:0x3ce6a70] 165833 ms: Mark-sweep 1374.0 (1425.0) -> 1373.7 (1425.5) MB, 789.1 / 0.0 ms (average mu 0.108, current mu 0.007) allocation failure scaven…

深度学习模型压缩方法:剪枝方法分类介绍

本文将介绍深度学习模型压缩方法中的剪枝,内容从剪枝简介、剪枝步骤、结构化剪枝与非结构化剪枝、静态剪枝与动态剪枝、硬剪枝与软剪枝等五个部分展开。 一、剪枝简介 在介绍剪枝之前,首先介绍过参数化这个概念,过参数化主要是指在训练阶段,在数学上需要进行大量的微分求解…

二维码智慧门牌管理系统:实现数据通信安全

文章目录 前言一、传输隧道加密技术二、传输数据加密技术三、数据接入鉴权技术 前言 随着信息技术的蓬勃发展&#xff0c;智慧门牌管理系统已成为现代商业和家庭重要的一部分。然而&#xff0c;系统普及的同时也带来了数据通信安全的突出问题。为了解决这一挑战&#xff0c;二…

Netty Review - StringEncoder字符串编码器和StringDecoder 解码器的使用与源码解读

文章目录 概念概述StringEncoderStringDecoder Code源码分析StringEncoderStringDecoder 小结 概念 概述 Netty是一个高性能的网络应用程序框架&#xff0c;它提供了丰富的功能&#xff0c;包括编解码器&#xff0c;这些编解码器用于在网络中发送和接收数据时进行数据的编码和…

SOME/IP SubscriberEventGroup

1 SOME/IP SubscriberEventGroup SubscriberEventGroup是SOME/IP中的一种服务发现和注册的消息类型,它用于让服务使用者订阅服务提供者的事件组。 事件组是一种将服务的方法和字段分组的方式,它可以让服务使用者只接收感兴趣的数据,而不是所有的数据。 SubscriberEventGrou…

nodejs+vue+微信小程序+python+PHP柚子校园影院系统-计算机毕业设计推荐

柚子校园影院综合网络空间开发设计要求。目的是将系统传统管理方式转换为在网上管理&#xff0c;完成信息管理的方便快捷、安全性高、交易规范做了保障&#xff0c;目标明确。柚子校园影院可以将功能划分为管理员功能和用户功能。  而开发本系统&#xff0c;又能够提高系统整体…

在 Windows 搭建 SVN 服务

近公司给配了台新电脑&#xff0c;配置挺主流的&#xff0c;但是不舍得抛弃自己的旧电脑&#xff08;原配嘛&#xff0c;这叫贪新不舍旧&#xff09;&#xff0c;于是打算在新电脑上只作开发环境&#xff0c;然后旧电脑作为版本库&#xff0c;这样保存版本的时候可以直接上传到…

es、MySQL 深度分页问题

文章目录 es 深度分页MySQL 深度分页 es 深度分页 es 深度分页问题&#xff0c;有点忘记了&#xff0c;这里记录一下 当索引库中有10w条数据&#xff0c;比如是商品数据&#xff1b;用户就是要查在1w到后10条数据&#xff0c;怎么查询。 es查询是从各个分片中取出前1w到后10条数…

【Mysql basic commands/query: how to update the message/record data of each row】

mysql common commands I) desc, insert and update I) desc, insert and update desc describe, insert into subject values(null,“Geometry Politics”, 99); mysql> select * from subject; ------------------------------------------------- | subject_id | subj…

LeetCode 19 删除链表的倒数第 N 个结点

题目描述 删除链表的倒数第 N 个结点 给你一个链表&#xff0c;删除链表的倒数第 n 个结点&#xff0c;并且返回链表的头结点。 示例 1&#xff1a; 输入&#xff1a;head [1,2,3,4,5], n 2 输出&#xff1a;[1,2,3,5]示例 2&#xff1a; 输入&#xff1a;head [1], n 1…

列举mfc140u.dll丢失的解决方法,常见的mfc140u.dll问题

在使用电脑的过程中&#xff0c;有时会遇到mfc140u.dll文件丢失的问题&#xff0c;导致一些应用程序无法正常启动。本文将介绍mfc140u.dll丢失的常见原因&#xff0c;并提供相应的解决办法。同时&#xff0c;还会列举一些与mfc140u.dll丢失相关的常见问题和解答。 第一部分&…

Mybatis Mapper XML文件-查询(select)

MyBatis真正的力量在于映射语句&#xff08;Mapped Statements&#xff09;。这是魔力发生的地方。尽管拥有强大的功能&#xff0c;Mapper XML文件相对来说比较简单。如果将其与等效的JDBC代码进行比较&#xff0c;您会立即看到代码减少了95%。MyBatis专注于SQL的编写&#xff…

SVN客户端部署-win7操作系统

SVN客户端官网&#xff1a;https://tortoisesvn.net/downloads.zh.html 按照操作系统选择&#xff0c;我的是64位&#xff0c;双击运行 下一步&#xff08;next&#xff09; 下一步 点击x处&#xff0c;总共4个选项&#xff0c;修改安装路径 will be installed on local hard …

Linux id命令教程:如何有效地获取用户和组信息(附案例详解和注意事项)

Linux id命令介绍 id命令是Linux中的一个内置命令&#xff0c;用于显示特定用户或当前用户的用户和组信息。这个命令可以帮助你找到用户ID (UID)&#xff0c;组ID (GID)&#xff0c;以及用户所属的所有组。 Linux id命令适用的Linux版本 id命令在所有主流的Linux发行版中都是…