当前位置: 首页 > news >正文

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

相关文章:

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

目标堆栈规划是一种简单高效的人工智能规划算法&#xff0c;用于解决复合目标问题。它的工作原理是**将总体目标分解为更小的子目标&#xff0c;然后以向后的顺序逐一解决它们。 让我们考虑一个简单的例子来说明目标堆栈规划。想象一下你想要烤一个蛋糕&#xff0c;目标是准备…...

(前端)后管系统登录后隐藏url上信息同时获取url上携带参数~开发需求(bug)总结7

问题描述&#xff1a; 首先我这个后管项目是若依权限管理系统&#xff0c;路由实现都是动态加载的。现在有一个需求&#xff0c;后端会邮件发送系统中的链接&#xff0c;这个链接是携带参数(id、用户的加密信息)&#xff0c;比如&#xff1a;https://47.23.12.1/task/list?id…...

CSS3新增样式

1&#xff0c;圆角边框 在CSS3中&#xff0c;新增了圆角边框样式&#xff0c;这样我们的盒子就可以变圆角了 border-radious属性用于设置元素的外边框圆角 语法&#xff1a; border-radious&#xff1a;length&#xff1b; radious 半径&#xff08;圆的半径&#xff09;原理…...

HP服务器idrac设置以及系统安装

HP服务器idrac设置以及系统安装 一、设置管理口的地址和密码1、HP服务器重新界面选择"F9"进入BIOS&#xff0c;设置iLo5(idrac)的IP和用户名密码。2、选择"系统配置"。3、选择"iLO 4"配置程序。4、网络选项是设置idrac管理口的地址&#xff0c;设…...

rpc和消息队列区别

RPC 和消息队列都是分布式微服务系统中重要的组件之一&#xff0c;下面我们来简单对比一下两者&#xff1a; 从用途来看&#xff1a;RPC 主要用来解决两个服务的远程通信问题&#xff0c;不需要了解底层网络的通信机制。通过 RPC可以帮助我们调用远程计算机上某个服务的方法&a…...

Permission denied (publickey,gssapi-keyex,gssapi-with-mic).

当使用ssh登录服务器时&#xff0c;由于文件权限没有设置报以下错误 WARNING: UNPROTECTED PRIVATE KEY FILE! Permissions for test_1.pem are too open. It is required that your private key files are NOT accessible by others. This private key will be ignored. Loa…...

虚幻学习笔记18—C++委托(多播)和事件

一、前言 委托分单播和多播&#xff0c;多播就是可以绑定多个回调函数&#xff0c;然后一次性执行。这样也可以理解为啥多播没有返回值&#xff0c;多个回调函数执行后返回哪一个都是问题啊。而事件呢官方官方文档说法是“对于事件而言&#xff0c;只有定义事件的类才能调用 Br…...

【UML】第9篇 类图

目录 一、类图的概念 二、类图的主要作用 三、类图的构成 3.1 类的名称 3.2 抽象类&#xff08;Abstract Class&#xff09; 一、类图的概念 类图是UML模型中静态视图。它用来描述系统中的有意义的概念&#xff0c;包括具体的概念、抽象的概念、实现方面的概念等。静态视…...

I.MX6ULL启动详解:Boot配置、Bootable image启动头的组成

本篇文章来了解一下I.MX6ULL的启动方式&#xff0c;实际上之前我介绍了NXP的跨界MCU RT1170的启动方式&#xff1a;I.MX RT1170启动详解&#xff1a;Boot配置、Bootable image头的组成&#xff0c;两个芯片虽然一个是Cortex-M&#xff0c;一个是Cortex-A&#xff0c;但是都是来…...

隐藏通信隧道技术——防御SSH隧道攻击的思路

隐藏通信隧道技术——防御SSH隧道攻击的思路 ​ 在内网中建立一个稳定、可靠的数据通道&#xff0c;对渗透测试工作来说具有重要的意义。应用层的隧道通信技术主要利用应用软件提供的端口来发送数据。常用的隧道协议有SSH、HTTP/HTTPS和DNS。 SSH协议 在一般情况下&#xff…...

UE-近战战斗系统学习笔记一

文章目录 一、介绍1&#xff09;选择paragon资产下载2&#xff09;用UE 5.0版本创建额外项目迁移到5.1版本的项目3&#xff09;由于后面要装备武器和盾牌&#xff0c;所以引入一个空手人物模型 二、创建目标系统1&#xff09;用导入的角色资产代替UE默认的人物第三人称角色资产…...

使用 Layui 的 template 模块来动态加载select选项

可以使用 Layui 的 template 模块来动态加载选项&#xff0c;如下所示&#xff1a; <!DOCTYPE html> <html> <head><meta charset"utf-8"><title>Layui 动态模板示例</title><link rel"stylesheet" href"pat…...

《数据分析-JiMuReport》积木报表详细入门教程

积木报表详细入门教程 一、JimuReport部署入门介绍 积木报表可以通过源码部署、SpringBoot集成、Docker部署以及各种成熟框架部署&#xff0c;具体可查看积木官方文档 当前采用源码部署&#xff0c;首先下载Jimureport-example-1.5.6 1 jimureport-example目录查看 使用ID…...

React面试题:React.Component和React.PureComponent的区别?

回答思路&#xff1a;什么是PureComponent-->Component更新过程-->PureComponent更新过程-->PureComponent的优点 什么是PureComponent&#xff1a;pure&#xff1a;纯净的&#xff0c;即为纯组件&#xff0c;可以用来优化React程序&#xff0c;减少render函数执行的…...

力扣:203. 移除链表元素(Python3)

题目&#xff1a; 给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回 新的头节点 。 来源&#xff1a;力扣&#xff08;LeetCode&#xff09; 链接&#xff1a;力扣&#xff08;LeetCode&#xff09;官网 …...

微信小程序-选择和分割打开地图选择位置的信息

一、 前言 废话不多说&#xff0c;单刀直入。 本文要实现的功能是微信小程序中打开地图选择位置&#xff0c;以及将返回的位置信息分割。 例如返回的位置信息是&#xff1a;广东省深圳市龙岗区xxxxx小区 分割后变成&#xff1a; {province: "广东省",city: "深…...

Flink Table API 与 SQL 编程整理

Flink API总共分为4层这里主要整理Table API的使用 Table API是流处理和批处理通用的关系型API&#xff0c;Table API可以基于流输入或者批输入来运行而不需要进行任何修改。Table API是SQL语言的超集并专门为Apache Flink设计的&#xff0c;Table API是Scala和Java语言集成式…...

华为OS与麒麟OS:华为自研操作系统的对决

导言 在移动操作系统领域&#xff0c;华为OS和麒麟OS代表了华为在自主研发方面的努力。本文将深入探讨这两个操作系统的特点、竞争关系以及它们在用户体验、生态系统建设等方面的差异。 1. 背景与起源 华为OS的诞生&#xff1a; 华为OS是华为公司为应对外部环境而自主…...

Java解决比特维位计数

Java解决比特维位计数 01 题目 给你一个整数 n &#xff0c;对于 0 < i < n 中的每个 i &#xff0c;计算其二进制表示中 1 的个数 &#xff0c;返回一个长度为 n 1 的数组 ans 作为答案。 示例 1&#xff1a; 输入&#xff1a;n 2 输出&#xff1a;[0,1,1] 解释&a…...

【深度学习目标检测】九、基于yolov5的路标识别(python,目标检测)

YOLOv5是目标检测领域一种非常优秀的模型&#xff0c;其具有以下几个优势&#xff1a; 1. 高精度&#xff1a;YOLOv5相比于其前身YOLOv4&#xff0c;在目标检测精度上有了显著的提升。YOLOv5使用了一系列的改进&#xff0c;如更深的网络结构、更多的特征层和更高分辨率的输入图…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

linux arm系统烧录

1、打开瑞芯微程序 2、按住linux arm 的 recover按键 插入电源 3、当瑞芯微检测到有设备 4、松开recover按键 5、选择升级固件 6、点击固件选择本地刷机的linux arm 镜像 7、点击升级 &#xff08;忘了有没有这步了 估计有&#xff09; 刷机程序 和 镜像 就不提供了。要刷的时…...

Nuxt.js 中的路由配置详解

Nuxt.js 通过其内置的路由系统简化了应用的路由配置&#xff0c;使得开发者可以轻松地管理页面导航和 URL 结构。路由配置主要涉及页面组件的组织、动态路由的设置以及路由元信息的配置。 自动路由生成 Nuxt.js 会根据 pages 目录下的文件结构自动生成路由配置。每个文件都会对…...

【python异步多线程】异步多线程爬虫代码示例

claude生成的python多线程、异步代码示例&#xff0c;模拟20个网页的爬取&#xff0c;每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程&#xff1a;允许程序同时执行多个任务&#xff0c;提高IO密集型任务&#xff08;如网络请求&#xff09;的效率…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...

七、数据库的完整性

七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...

三分算法与DeepSeek辅助证明是单峰函数

前置 单峰函数有唯一的最大值&#xff0c;最大值左侧的数值严格单调递增&#xff0c;最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值&#xff0c;最小值左侧的数值严格单调递减&#xff0c;最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 &#x1f3af; 今日目标 理解类&#xff08;class&#xff09;和对象&#xff08;object&#xff09;的关系学会定义类的属性、方法和构造函数&#xff08;init&#xff09;掌握对象的创建与使用初识封装、继承和多态的基本概念&#xff08;预告&#xff09; &a…...

ArcGIS Pro+ArcGIS给你的地图加上北回归线!

今天来看ArcGIS Pro和ArcGIS中如何给制作的中国地图或者其他大范围地图加上北回归线。 我们将在ArcGIS Pro和ArcGIS中一同介绍。 1 ArcGIS Pro中设置北回归线 1、在ArcGIS Pro中初步设置好经纬格网等&#xff0c;设置经线、纬线都以10间隔显示。 2、需要插入背会归线&#xf…...

深入解析光敏传感技术:嵌入式仿真平台如何重塑电子工程教学

一、光敏传感技术的物理本质与系统级实现挑战 光敏电阻作为经典的光电传感器件&#xff0c;其工作原理根植于半导体材料的光电导效应。当入射光子能量超过材料带隙宽度时&#xff0c;价带电子受激发跃迁至导带&#xff0c;形成电子-空穴对&#xff0c;导致材料电导率显著提升。…...