强化学习实战2:动手写迷宫环境

迷宫环境介绍与创建

迷宫环境图示如下:

在这里插入图片描述

如图所示,其为一个 三乘三 的网格世界,我们要让 agent 从 S0 采取策略出发,然后走到 S8,图中红线部分表示障碍不能逾越,其中 S1 和 S4 之间有一个障碍,S3 和 S4 之间有一个障碍,S3 和 S6 之间有一个障碍,S5 和 S8 之间有一个障碍。

这就是我们的迷宫环境。

代码如下:

import matplotlib.pyplot as plt# 创建一个新的图形对象,并设置其大小为 5x5 英寸
fig = plt.figure(figsize=(5, 5))# 获取当前图形对象的轴对象
ax = plt.gca()# 设置坐标轴的范围
ax.set_xlim(0, 3)
ax.set_ylim(0, 3)# 绘制红色的方格边界,表示迷宫的结构
plt.plot([2, 3], [1, 1], color='red', linewidth=2)
plt.plot([0, 1], [1, 1], color='red', linewidth=2)
plt.plot([1, 1], [1, 2], color='red', linewidth=2)
plt.plot([1, 2], [2, 2], color='red', linewidth=2)# 在指定位置添加文字标签,表示每个状态(S0-S8)、起点和终点
plt.text(0.5, 2.5, 'S0', size=14, ha='center')
plt.text(1.5, 2.5, 'S1', size=14, ha='center')
plt.text(2.5, 2.5, 'S2', size=14, ha='center')
plt.text(0.5, 1.5, 'S3', size=14, ha='center')
plt.text(1.5, 1.5, 'S4', size=14, ha='center')
plt.text(2.5, 1.5, 'S5', size=14, ha='center')
plt.text(0.5, 0.5, 'S6', size=14, ha='center')
plt.text(1.5, 0.5, 'S7', size=14, ha='center')
plt.text(2.5, 0.5, 'S8', size=14, ha='center')
plt.text(0.5, 2.3, 'Start', ha='center')
plt.text(2.5, 0.3, 'Goal', ha='center')# 设置坐标轴的显示参数,使得坐标轴不显示
plt.tick_params(axis='both', which='both',bottom=False, top=False,right=False, left=False,labelbottom=False, labelleft=False)# 在起点位置绘制一个绿色的圆形表示当前位置
line, = ax.plot([0.5], [2.5], marker='o', color='g', markersize=60)# 显示图形
plt.show()

运行结果如下:

在这里插入图片描述

agent 的动作策略设计

如下图所示:

在这里插入图片描述

不难看出,state 总共有九个,也就是离散(discrete)且有限(finite)的三乘三网格世界。

而动作空间共有上下左右四个选择,用一个数组来表示。

而 Π 就是我们的策略了,可以看见其有一个下标 θ,这是参数的意思,在神经网络参与的算法中这个策略参数由神经网络确定,而在本节中尚未提及神经网络,因此使用一个 table ,也就是一个 状态-行为 矩阵来确定策略。

下面开始来刻画环境需要的边界和障碍信息:

# 刻画环境:边界border 和 障碍barrier
theta_0 = np.array([[np.nan, 1, 1, np.nan],  # 表示S0时的策略,即agent不能往上、不能往左走,但可以往右和下走[np.nan, 1, np.nan, 1],  # S1[np.nan, np.nan, 1, 1],  # S2[1, np.nan, np.nan, np.nan],  # S3[np.nan, 1, 1, np.nan],  # S4[1, np.nan, np.nan, 1],  # S5[np.nan, 1, np.nan, np.nan],  # S6[1, 1, np.nan, 1],  # S7# S8 已经是终点了,因此不再需要上下左右到处走了
])

然后需要将上述的参数矩阵给转换成策略 Π 的值,也就是采取各个 action 的概率值:

# 将 theta_0 转换为 策略 Π,而 Π 其实就是概率值嘛
def cvt_theta_0_to_pi(theta):m, n = theta.shapepi = np.zeros((m, n))for r in range(m):# pi[r, :]这是一个赋值操作的左侧表达式,它使用了NumPy的索引机制。# 在这里,pi 应该是一个二维数组(矩阵),r 表示行索引,: 表示选择该行的所有列。# 因此,这一部分指定了 pi 矩阵中的第 r 行的所有列。# np.nansum() 这是一个NumPy函数调用。np.nansum() 用于计算数组中元素的总和,忽略 NaN 值。# theta[r, :] 提供了一个一维数组作为函数的参数,表示对 theta 矩阵中第 r 行的所有元素进行求和。# 因此下面这一行代码是一个按元素的除法操作。# 它将 theta 矩阵中第 r 行的每个元素分别除以该行所有元素的和(忽略 NaN 值)。# 这样做可以将该行的元素归一化为一个概率分布,确保它们的总和为 1。pi[r, :] = theta[r, :] / np.nansum(theta[r, :])return np.nan_to_num(pi)pi = cvt_theta_0_to_pi(theta_0)
# 先打印一下看是什么样子的结果
print(pi)

运行结果如下:

在这里插入图片描述

可以看见此时的 state-action 矩阵就已经构建好了。

下面构建动作空间列表以及状态转移函数:

# 动作空间:0表示向上,1表示向右,2表示向下,3表示向左
actions = list(range(4))# 状态转移函数
def step(state, action):if action == 0:state -= 3elif action == 1:state += 1elif action == 2:state += 3elif action == 3:state -= 1return state

策略测试

那么接下来我们就可以进行测试了,使用上述构建的环境和配置,可以进行路径的搜索了:

state = 0
action_history = []
state_history = [state]
while True:"""对下面这一行代码进行的解释:np.random.choice:这是 NumPy 库中的一个函数,用于从给定的一维数组或类似序列中随机选择元素。在这里,我们将从 actions 数组中随机选择一个元素。actions:这是一个包含可选动作的一维数组或列表。np.random.choice 将从这个数组中进行选择。p=pi[state, :]:这是 np.random.choice 函数的一个参数,用于指定每个元素被选择的概率。在这里,pi 是一个二维数组(矩阵),state 是当前状态的索引,: 表示选择该行的所有列。因此,pi[state, :] 提供了一个概率分布,用于指定在选择时每个动作的相对概率。赋值操作:action = ... 将 np.random.choice 的结果赋值给变量 action。这意味着 action 将是从 actions 数组中随机选择的一个元素,选择的概率由 pi[state, :] 给出。"""action = np.random.choice(actions, p=pi[state, :])state = step(state, action)if state == 8:state_history.append(8)breakaction_history.append(action)state_history.append(state)print(len(state_history))
print(state_history)

运行结果如下:

在这里插入图片描述

可以看到在这一次运行中,agent 走了 38 步才到达 S8,所走过的路径如上图所示。

动画可视化搜索过程

直接上代码:

from matplotlib import animation
from IPython.display import HTMLdef init():line.set_data([], [])return (line, )def animate(i):state = state_history[i]x = (state % 3) + 0.5y = 2.5 - int(state / 3)line.set_data(x, y)anim = animation.FuncAnimation(fig, animate, init_func=init, frames=len(state_history), interval=200, repeat=False)
anim.save('maze_0.mp4')
# 视频观测有时候不太友好,我们还可以使用 IPython 提供的 HTML 的交互式工具
# 由于 PyCharm 不支持显示 IPython 的交互式输出,因此我们这里将 IPython 的输出转换为 HTML 文件再打开
with open('animation.html', 'w') as f:f.write(anim.to_jshtml())

运行结果如下:

在这里插入图片描述

比起直接观看视频,这种交互式的过程更能帮助我们从细节上一点一点看清楚 agent 的运行轨迹。

总结

上面的代码是为了讲清楚各部分的功能和实现细节,全部代码合在一起就是下面这样:

import matplotlib.pyplot as plt
import numpy as np# 创建一个新的图形对象,并设置其大小为 5x5 英寸
fig = plt.figure(figsize=(5, 5))# 获取当前图形对象的轴对象
ax = plt.gca()# 设置坐标轴的范围
ax.set_xlim(0, 3)
ax.set_ylim(0, 3)# 绘制红色的方格边界,表示迷宫的结构
plt.plot([2, 3], [1, 1], color='red', linewidth=2)
plt.plot([0, 1], [1, 1], color='red', linewidth=2)
plt.plot([1, 1], [1, 2], color='red', linewidth=2)
plt.plot([1, 2], [2, 2], color='red', linewidth=2)# 在指定位置添加文字标签,表示每个状态(S0-S8)、起点和终点
plt.text(0.5, 2.5, 'S0', size=14, ha='center')
plt.text(1.5, 2.5, 'S1', size=14, ha='center')
plt.text(2.5, 2.5, 'S2', size=14, ha='center')
plt.text(0.5, 1.5, 'S3', size=14, ha='center')
plt.text(1.5, 1.5, 'S4', size=14, ha='center')
plt.text(2.5, 1.5, 'S5', size=14, ha='center')
plt.text(0.5, 0.5, 'S6', size=14, ha='center')
plt.text(1.5, 0.5, 'S7', size=14, ha='center')
plt.text(2.5, 0.5, 'S8', size=14, ha='center')
plt.text(0.5, 2.3, 'Start', ha='center')
plt.text(2.5, 0.3, 'Goal', ha='center')# 设置坐标轴的显示参数,使得坐标轴不显示
plt.tick_params(axis='both', which='both',bottom=False, top=False,right=False, left=False,labelbottom=False, labelleft=False)# 在起点位置绘制一个绿色的圆形表示当前位置
line, = ax.plot([0.5], [2.5], marker='o', color='g', markersize=60)# 显示图形
# plt.show()# 刻画环境:边界border 和 障碍barrier
theta_0 = np.array([[np.nan, 1, 1, np.nan],  # 表示S0时的策略,即agent不能往上、不能往左走,但可以往右和下走[np.nan, 1, np.nan, 1],[np.nan, np.nan, 1, 1],[1, np.nan, np.nan, np.nan],[np.nan, 1, 1, np.nan],[1, np.nan, np.nan, 1],[np.nan, 1, np.nan, np.nan],[1, 1, np.nan, 1],# S8 已经是终点了,因此不再需要上下左右到处走了
])# 将 theta_0 转换为 策略 Π,而 Π 其实就是概率值嘛
def cvt_theta_0_to_pi(theta):m, n = theta.shapepi = np.zeros((m, n))for r in range(m):# pi[r, :]这是一个赋值操作的左侧表达式,它使用了NumPy的索引机制。# 在这里,pi 应该是一个二维数组(矩阵),r 表示行索引,: 表示选择该行的所有列。# 因此,这一部分指定了 pi 矩阵中的第 r 行的所有列。# np.nansum() 这是一个NumPy函数调用。np.nansum() 用于计算数组中元素的总和,忽略 NaN 值。# theta[r, :] 提供了一个一维数组作为函数的参数,表示对 theta 矩阵中第 r 行的所有元素进行求和。# 因此下面这一行代码是一个按元素的除法操作。# 它将 theta 矩阵中第 r 行的每个元素分别除以该行所有元素的和(忽略 NaN 值)。# 这样做可以将该行的元素归一化为一个概率分布,确保它们的总和为 1。pi[r, :] = theta[r, :] / np.nansum(theta[r, :])return np.nan_to_num(pi)pi = cvt_theta_0_to_pi(theta_0)# 动作空间
actions = list(range(4))
print(actions)# 状态转移函数
def step(state, action):if action == 0:state -= 3elif action == 1:state += 1elif action == 2:state += 3elif action == 3:state -= 1return statestate = 0
action_history = []
state_history = [state]
while True:"""对下面这一行代码进行的解释:np.random.choice:这是 NumPy 库中的一个函数,用于从给定的一维数组或类似序列中随机选择元素。在这里,我们将从 actions 数组中随机选择一个元素。actions:这是一个包含可选动作的一维数组或列表。np.random.choice 将从这个数组中进行选择。p=pi[state, :]:这是 np.random.choice 函数的一个参数,用于指定每个元素被选择的概率。在这里,pi 是一个二维数组(矩阵),state 是当前状态的索引,: 表示选择该行的所有列。因此,pi[state, :] 提供了一个概率分布,用于指定在选择时每个动作的相对概率。赋值操作:action = ... 将 np.random.choice 的结果赋值给变量 action。这意味着 action 将是从 actions 数组中随机选择的一个元素,选择的概率由 pi[state, :] 给出。"""action = np.random.choice(actions, p=pi[state, :])state = step(state, action)if state == 8:state_history.append(8)breakaction_history.append(action)state_history.append(state)print(len(state_history))
print(state_history)from matplotlib import animation
from IPython.display import HTMLdef init():line.set_data([], [])return (line, )def animate(i):state = state_history[i]x = (state % 3) + 0.5y = 2.5 - int(state / 3)line.set_data(x, y)anim = animation.FuncAnimation(fig, animate, init_func=init, frames=len(state_history), interval=200, repeat=False)
anim.save('maze_0.mp4')
# 视频观测有时候不太友好,我们还可以使用 IPython 提供的 HTML 的交互式工具
# 由于 PyCharm 不支持显示 IPython 的交互式输出,因此我们这里将 IPython 的输出转换为 HTML 文件再打开
with open('animation.html', 'w') as f:f.write(anim.to_jshtml())

封装迷宫环境 API

上面的代码虽然已经完成了环境的编写了,但是过于混乱,因此这一节我们仿照 Gym 的格式将其封装一下。

主要就是两个部分,一个是 环境,还有一个是 Agent。

对于环境其最重要的就是 step 函数,step 函数接收一个 action 然后返回一个新的状态以及 reward 等各种信息。

对于 Agent 而言其最重要的是一个动作策略的选取。

基本结构如下:

import gym
import numpy as np
import matplotlib.pyplot as pltclass MazeEnv(gym.Env):def __init__(self):passdef reset(self):passdef step(self, action):passclass Agent:def __init__(self):passdef choose_action(self, state):pass

封装如下:

import gym
import numpy as np
import matplotlib.pyplot as plt
from matplotlib import animation
from IPython.display import HTML# MazeEnv 类维护着状态,以及 step 函数的返回
class MazeEnv(gym.Env):def __init__(self):self.state = 0def reset(self):self.state = 0return self.statedef step(self, action):if action == 0:self.state -= 3elif action == 1:self.state += 1elif action == 2:self.state += 3elif action == 3:self.state -= 1done = Falseif self.state == 8:done = True# 1 表示 reward, done 表示是否结束# {} 是一个空的字典字面量,表示返回的第四个值是一个空字典。return self.state, 1, done, {}# Agent 类基于当前环境中的状态选择动作形成策略
class Agent:def __init__(self):# action spaceself.actions = list(range(4))# 刻画环境:边界 border 和 障碍 barrierself.theta_0 = np.array([[np.nan, 1, 1, np.nan],  # 表示S0时的策略,即agent不能往上、不能往左走,但可以往右和下走[np.nan, 1, np.nan, 1],[np.nan, np.nan, 1, 1],[1, np.nan, np.nan, np.nan],[np.nan, 1, 1, np.nan],[1, np.nan, np.nan, 1],[np.nan, 1, np.nan, np.nan],[1, 1, np.nan, 1],# S8 已经是终点了,因此不再需要上下左右到处走了])# 策略 Πself.pi = self._cvt_theta_0_to_pi(self.theta_0)# 将 theta_0 转换为 策略 Π,而 Π 其实就是概率值嘛def _cvt_theta_0_to_pi(self, theta):m, n = theta.shapepi = np.zeros((m, n))for r in range(m):pi[r, :] = theta[r, :] / np.nansum(theta[r, :])return np.nan_to_num(pi)def choose_action(self, state):action = np.random.choice(self.actions, p=self.pi[state, :])return action# MazeAnimation 类封装了可视化展示代码的 API
class MazeAnimation:def __init__(self):# 创建一个新的图形对象,并设置其大小为 5x5 英寸self.fig = plt.figure(figsize=(5, 5))# 获取当前图形对象的轴对象self.ax = plt.gca()# 设置坐标轴的范围self.ax.set_xlim(0, 3)self.ax.set_ylim(0, 3)# 绘制红色的方格边界,表示迷宫的结构plt.plot([2, 3], [1, 1], color='red', linewidth=2)plt.plot([0, 1], [1, 1], color='red', linewidth=2)plt.plot([1, 1], [1, 2], color='red', linewidth=2)plt.plot([1, 2], [2, 2], color='red', linewidth=2)# 在指定位置添加文字标签,表示每个状态(S0-S8)、起点和终点plt.text(0.5, 2.5, 'S0', size=14, ha='center')plt.text(1.5, 2.5, 'S1', size=14, ha='center')plt.text(2.5, 2.5, 'S2', size=14, ha='center')plt.text(0.5, 1.5, 'S3', size=14, ha='center')plt.text(1.5, 1.5, 'S4', size=14, ha='center')plt.text(2.5, 1.5, 'S5', size=14, ha='center')plt.text(0.5, 0.5, 'S6', size=14, ha='center')plt.text(1.5, 0.5, 'S7', size=14, ha='center')plt.text(2.5, 0.5, 'S8', size=14, ha='center')plt.text(0.5, 2.3, 'Start', ha='center')plt.text(2.5, 0.3, 'Goal', ha='center')# 设置坐标轴的显示参数,使得坐标轴不显示plt.tick_params(axis='both', which='both',bottom=False, top=False,right=False, left=False,labelbottom=False, labelleft=False)# 在起点位置绘制一个绿色的圆形表示当前位置self.line, = self.ax.plot([0.5], [2.5], marker='o', color='g', markersize=60)# state_history 是状态历史数组def save_as_mp4_html(self, state_history):def init():self.line.set_data([], [])return (self.line,)def animate(i):state = state_history[i]x = (state % 3) + 0.5y = 2.5 - int(state / 3)self.line.set_data(x, y)anim = animation.FuncAnimation(self.fig, animate, init_func=init, frames=len(state_history), interval=200,repeat=False)anim.save('maze.mp4')with open('maze_animation.html', 'w') as f:f.write(anim.to_jshtml())# -------------------------------测试代码---------------------------------# 创建迷宫环境
env = MazeEnv()
# 重置迷宫环境到初始状态
state = env.reset()
# 创建 agent
agent = Agent()
# 结束标志 done
done = False
# 动作历史
action_history = []
# 状态历史,含一开始位于 S0 的状态
state_history = [state]
# 一个循环就是一个 episode
while not done:action = agent.choose_action(state)state, reward, done, _ = env.step(action)state_history.append(state)action_history.append(action)# 打印状态历史长度
print(len(state_history))
# 可视化展示
# 创建封装好的可视化对象
show = MazeAnimation()
# 调用该对象中的可视化展示函数
show.save_as_mp4_html(state_history)

运行结果和之前一样,不再赘述。

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

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

相关文章

C语言有哪些特点?

C语言是一种结构化语言,它有着清晰的层次,可按照模块的方式对程序进行编写,十分有利于程序的调试,且c语言的处理和表现能力都非常的强大,依靠非常全面的运算符和多样的数据类型,可以轻易完成各种数据结构的…

Kotlin MultiPlatform(KMP)

Kotlin MultiPlatform 1.KMP 是什么 Kotlin Multiplatform 是一个工具,它让我们用同一种编程语言(Kotlin)写代码,这些代码可以同时在不同的设备上运行,比如手机、电脑和网页。这样做可以节省时间,因为你不…

1、项目目录设计

文章目录 前言一、项目目录设计 前言 本项目我们将会完成一个Go项目开发框架,该项目不会包含具体的CRUD业务代码,而是从头搭建一个工作中实用的开发框架。让开发者能够熟悉整个项目的搭建流程,能够独立完成项目从0到1的搭建,而且…

【RHCE】实验(HTTP,DNS,SELinux,firewalld的运用)

一、题目 二、主服务器配置 1.下载HTTP服务,DNS服务 [rootlocalhost ~]# yum install -y httpd bind 2.开启防火墙,放行服务 # 开启防火墙 [rootlocalhost ~]# systemctl start firewalld # 放行服务 [rootlocalhost ~]# firewall-cmd --add-service…

上班摸鱼吗?一文详解代码生成神器-Velocity

引言 “我不是在教你学坏,而是教你如何提高生产效率。” ----------- 牛顿 人类社会能够一直进步发展出现在的文明世界,最大的一个原因就是这个世界上懒人居多,懒人为了偷懒就需要提高生产效率,效率提高节省下来的时间才能创造出艺术、娱乐以及更高效率的科学技术。程序员…

MySQL DDL

数据库 1 创建数据库 CREATE DATABASE 数据库名 CREATE DATABASE IF NOT EXISTS 数据库名;(判断是否存在) CREATE DATABASE 数据库名 CHARACTER SET 字符 2 查看数据库 SHOW DATABASES; 查看某个数据库的信息 SHOW CAEATE DATABASE 数据库名 3 修改数据库 …

信息学奥赛初赛天天练-44-CSP-J2020基础题-排列组合、乘法原理、捆绑法、隔板法、排除法示例及应用

PDF文档公众号回复关键字:20240711 2020 CSP-J 选择题 单项选择题(共15题,每题2分,共计30分:每题有且仅有一个正确选项) 10.有5 个小朋友并排站成一列,其中有两个小朋友是双胞胎,如果要求这…

dev小熊猫,clion设置模版教程

首先点击工具 然后进入设置 ,找到代码模版 然后点击c模版,进入之后直接输入模版之后,(还没有结束!!!),先点击应用,然后是确定!!&#…

【js面试题】深入理解浏览器对象模型(BOM)

面试题:请你说说对bom的理解,常见的bom对象你了解哪些 引言: 浏览器对象模型(BOM)是JavaScript中用于与浏览器窗口及其内容进行交互的一组对象和方法。 BOM的核心是window对象,它代表了浏览器窗口本身&…

【SQL】DML、DDL、ROLLBACK 、COMMIT详解

DML DML(Data Manipulation Language)数据操作语言,是用于对数据库中的数据进行基本操作的一种编程语言。DML是数据库管理系统(DBMS)中的一个重要部分,它允许用户或应用程序对数据库中的数据进行增、删、改…

探索GitHub上的两个革命性开源项目

在数字世界中,总有一些项目能够以其创新性和实用性脱颖而出,吸引全球开发者的目光。今天,我们将深入探索GitHub上的两个令人惊叹的开源项目:Comic Translate和GPTPDF,它们不仅改变了我们处理信息的方式,还极大地丰富了我们的数字生活体验。 01 漫画爱好者的福音:Comi…

PostgreSQl 物化视图

物化视图(Materialized View)是 PostgreSQL 提供的一个扩展功能,它是介于视图和表之间的一种对象。 物化视图和视图的最大区别是它不仅存储定义中的查询语句,而且可以像表一样存储数据。物化视图和表的最大区别是它不支持 INSERT…

Windows 电脑查看 WiFi 密码的方法都有哪些?

从设置面板中查看 当你使用的是笔记本电脑并且连接 WiFi 之后可以在设置面板中查看 WiFi 密码,首先打开设置界面,然后点击网络和 Internet,找到 WiFi 之后点击进入,然后点击管理已知网络。 然后点击已经连接好的无线网络。 进入之…

SpringBoot 3.3 【一】手把手讲解-使用Eclipse创建第一个SpringBoot应用程序

简单动作,深刻联结。在这技术海洋,我备好舟,等你扬帆。启航吧! 🌟点击【关注】,解锁定期的技术惊喜,让灵感与知识的源泉不断涌动。 👍一个【点赞】,如同心照不宣的默契&a…

AI工具,如何通过 GPT-4o 提高工作效率

文章目录 引言一、理解GPT-4o及其功能二、如何利用GPT-4o提高工作效率1. 代码生成与优化2. 自动化测试与调试3. 技术文档撰写与知识管理 三、实际案例与成功应用1. GitHub 协作与问题解决2. 敏捷开发与迭代优化 四、GPT-4o的挑战与应对策略五、未来展望与发展方向六、结论 &…

保护企业数据资产的策略与实践:数据安全治理技术之实战篇!

在上篇文章中,我们深入讨论了数据安全治理技术的前期准备工作,包括从建立数据安全运维体系、敏感数据识别、数据的分类与分级到身份认等方面的详细规划和设计。这些准备工作是实现数据安全治理的基础,它们为企业建立起一套系统化、标准化的数…

二进制补码计算

基本知识 原码(Sign and Magnitude):原码是一种最简单的表示法,使用符号位和数值位来表示整数。 符号位:最高位是符号位,0表示正数,1表示负数。 数值位:剩下的位表示数值的大小。反码&#xf…

windows11下vscode配置C/C++(过程记录)

一、概述 一直想在Windows11系统下使用vscode运行C/C程序,如果使用visual studio的话需要占用大量内存,且每次启动较慢。vscode则可以省去大多数烦恼。 二、具体配置过程 (一)参考博客 主要参考两篇博客,分别如下所示…

kubernetes集群如何更改所有节点IP

kubernetes集群如何更改所有节点IP 情景描述更换IP前的准备工作更换IP后的工作--master更换IP后的工作--node节点重新部署之前那些服务 情景描述 我有三台服务器,想要将其组成了一个kubernetes集群,在部署之前,我就对其进行了固定IP的操作&a…

ARM功耗管理之多核处理器启动

安全之安全(security)博客目录导读 思考:SecureBoot?多核处理器启动流程?PSCI启动方式? 一般嵌入式系统使用的都是对称多处理器(Symmetric Multi-Processor, SMP)系统,包含了多个cpu, 这几个cp…