SAC代码 pytorch框架,2023年了还在用假的SAC?

news2024/9/23 0:05:57

呀他温,博主这次真要红温了,中路一个红温兰博请求对线!!!!!!

莫烦老师的强化学习视频不出SAC,我只能去看看别的程序员讲解SAC算法。结果。。。。

唉,,,别说了,,,,这年头程序员的质量参差不齐,假的SAC代码训练出来的收敛图能有多逆天,请看下图,下图是SAC玩gym的Pendulum-v0游戏环境。SAC训练的效果比DDPG还差,难道写出这SAC代码的作者自己都不觉得奇怪吗?都不怀疑一下为什么这SAC的收敛图比DDPG还要差吗?Pendulum游戏环境总奖励一会-100.1的,一会-2124.5的,跳变的这么厉害,意识不到不对劲吗?

频繁反复横跳的奖励值

假SAC:
假SAC收敛图

假SAC的代码是我参考这个github代码改来的,假SAC代码如下,我应该没改错吧。。

# -*- coding: utf-8 -*-
#开发者:Bright Fang
#开发时间:2023/2/14 20:10
import torch
import torch.nn as nn
import torch.nn.functional as F
# device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
import numpy as np
import gym
from matplotlib import pyplot as plt
import os
os.environ['KMP_DUPLICATE_LIB_OK'] = 'TRUE'
env = gym.make("Pendulum-v0").unwrapped
'''Pendulum环境状态特征是三个,杆子的sin(角度)、cos(角度)、角速度,(状态是无限多个,因为连续),动作值是力矩,限定在[-2,2]之间的任意的小数,所以是连续的(动作也是无限个)'''
state_number=env.observation_space.shape[0]
action_number=env.action_space.shape[0]
max_action = env.action_space.high[0]
min_action = env.action_space.low[0]
RENDER=False
EP_MAX = 500
EP_LEN = 500
GAMMA = 0.9
q_lr = 2e-3
value_lr = 3e-3
policy_lr = 1e-3
BATCH = 128
tau = 1e-2
MemoryCapacity=10000
Switch=0

class ActorNet(nn.Module):
    def __init__(self,inp,outp):
        super(ActorNet, self).__init__()
        self.in_to_y1=nn.Linear(inp,256)
        self.in_to_y1.weight.data.normal_(0,0.1)
        self.y1_to_y2=nn.Linear(256,256)
        self.y1_to_y2.weight.data.normal_(0,0.1)
        self.out=nn.Linear(256,outp)
        self.out.weight.data.normal_(0,0.1)
        self.std_out = nn.Linear(256, outp)
        self.std_out.weight.data.normal_(0, 0.1)

    def forward(self,inputstate):
        inputstate=self.in_to_y1(inputstate)
        inputstate=F.relu(inputstate)
        inputstate=self.y1_to_y2(inputstate)
        inputstate=F.relu(inputstate)
        mean=max_action*torch.tanh(self.out(inputstate))#输出概率分布的均值mean
        log_std=self.std_out(inputstate)#softplus激活函数的值域>0
        log_std=torch.clamp(log_std,-20,2)
        std=log_std.exp()
        return mean,std

class CriticNet(nn.Module):
    def __init__(self,input):
        super(CriticNet, self).__init__()
        self.in_to_y1=nn.Linear(input,256)
        self.in_to_y1.weight.data.normal_(0,0.1)
        self.y1_to_y2=nn.Linear(256,256)
        self.y1_to_y2.weight.data.normal_(0,0.1)
        self.out=nn.Linear(256,1)
        self.out.weight.data.normal_(0,0.1)
    def forward(self,inputstate):
        v=self.in_to_y1(inputstate)
        v=F.relu(v)
        v=self.y1_to_y2(v)
        v=F.relu(v)
        v=self.out(v)
        return v
class QNet(nn.Module):
    def __init__(self,input,output):
        super(QNet, self).__init__()
        self.in_to_y1=nn.Linear(input+output,256)
        self.in_to_y1.weight.data.normal_(0,0.1)
        self.y1_to_y2=nn.Linear(256,256)
        self.y1_to_y2.weight.data.normal_(0,0.1)
        self.out=nn.Linear(256,output)
        self.out.weight.data.normal_(0,0.1)
    def forward(self,s,a):
        inputstate = torch.cat((s, a), dim=1)
        q1=self.in_to_y1(inputstate)
        q1=F.relu(q1)
        q1=self.y1_to_y2(q1)
        q1=F.relu(q1)
        q1=self.out(q1)
        return q1
class Memory():
    def __init__(self,capacity,dims):
        self.capacity=capacity
        self.mem=np.zeros((capacity,dims))
        self.memory_counter=0
    '''存储记忆'''
    def store_transition(self,s,a,r,s_):
        tran = np.hstack((s, [a.squeeze(0),r], s_))  # 把s,a,r,s_困在一起,水平拼接
        index = self.memory_counter % self.capacity#除余得索引
        self.mem[index, :] = tran  # 给索引存值,第index行所有列都为其中一次的s,a,r,s_;mem会是一个capacity行,(s+a+r+s_)列的数组
        self.memory_counter+=1
    '''随机从记忆库里抽取'''
    def sample(self,n):
        assert self.memory_counter>=self.capacity,'记忆库没有存满记忆'
        sample_index = np.random.choice(self.capacity, n)#从capacity个记忆里随机抽取n个为一批,可得到抽样后的索引号
        new_mem = self.mem[sample_index, :]#由抽样得到的索引号在所有的capacity个记忆中  得到记忆s,a,r,s_
        return new_mem
class Actor():
    def __init__(self):
        self.action_net=ActorNet(state_number,action_number)#这只是均值mean
        self.optimizer=torch.optim.Adam(self.action_net.parameters(),lr=policy_lr)

    def choose_action(self,s):
        inputstate = torch.FloatTensor(s)
        mean,std=self.action_net(inputstate)
        dist = torch.distributions.Normal(mean, std)
        action=dist.sample()
        action=torch.clamp(action,min_action,max_action)
        return action.detach().numpy()
    def evaluate(self,s):
        inputstate = torch.FloatTensor(s)
        mean,std=self.action_net(inputstate)
        dist = torch.distributions.Normal(mean, std)
        noise = torch.distributions.Normal(0, 1)
        z = noise.sample()
        action=torch.tanh(mean+std*z)
        action=torch.clamp(action,min_action,max_action)
        action_logprob=dist.log_prob(mean+std*z)-torch.log(1-action.pow(2)+1e-6)
        return action,action_logprob,z,mean,std

    def learn(self,actor_loss):
        loss=actor_loss
        self.optimizer.zero_grad()
        loss.backward()
        self.optimizer.step()

class Critic():
    def __init__(self):
        self.critic_v,self.target_critic_v=CriticNet(state_number),CriticNet(state_number)#改网络输入状态,生成一个Q值
        self.optimizer = torch.optim.Adam(self.critic_v.parameters(), lr=value_lr,eps=1e-5)
        self.lossfunc = nn.MSELoss()
    def soft_update(self):
        for target_param, param in zip(self.target_critic_v.parameters(), self.critic_v.parameters()):
            target_param.data.copy_(target_param.data * (1.0 - tau) + param.data * tau)

    def get_v(self,s):
        return self.critic_v(s)

    def learn(self,expected_v,next_v):
        loss=self.lossfunc(expected_v,next_v.detach())
        self.optimizer.zero_grad()
        loss.backward()
        self.optimizer.step()

class Q_Critic():
    def __init__(self):
        self.q1_net=QNet(state_number,action_number)#改网络输入状态,生成一个Q值
        self.q1_optimizer = torch.optim.Adam(self.q1_net.parameters(), lr=q_lr,eps=1e-5)
        self.lossfunc = nn.MSELoss()
    def get_q(self,s,a):
        return self.q1_net(s,a)
    def learn(self,br,expected_q,target_v):
        next_q = br + GAMMA * target_v
        loss=self.lossfunc(expected_q,next_q.detach())
        self.q1_optimizer.zero_grad()
        loss.backward()
        self.q1_optimizer.step()
if Switch==0:
    print('SAC训练中...')
    actor = Actor()
    critic = Critic()
    q_critic=Q_Critic()
    M = Memory(MemoryCapacity, 2 * state_number + action_number + 1)
    all_ep_r = []
    for episode in range(EP_MAX):
        observation = env.reset()  # 环境重置
        reward_totle = 0
        for timestep in range(EP_LEN):
            if RENDER:
                env.render()
            action = actor.choose_action(observation)
            observation_, reward, done, info = env.step(action)  # 单步交互
            M.store_transition(observation, action, reward, observation_)
            # 记忆库存储
            # 有的2000个存储数据就开始学习
            if M.memory_counter > MemoryCapacity:
                b_M = M.sample(BATCH)
                b_s = b_M[:, :state_number]
                b_a = b_M[:, state_number: state_number + action_number]
                b_r = b_M[:, -state_number - 1: -state_number]
                b_s_ = b_M[:, -state_number:]
                b_s = torch.FloatTensor(b_s)
                b_a = torch.FloatTensor(b_a)
                b_r = torch.FloatTensor(b_r)
                b_s_ = torch.FloatTensor(b_s_)
                expected_q=q_critic.get_q(b_s,b_a)
                expected_v=critic.get_v(b_s)
                new_action, log_prob, z, mean, log_std = actor.evaluate(b_s)
                target_v=critic.target_critic_v(b_s_)
                q_critic.learn(b_r,expected_q,target_v)
                expected_new_q=q_critic.get_q(b_s,new_action)
                next_v=expected_new_q-log_prob
                critic.learn(expected_v,next_v)
                log_prob_target=expected_new_q-expected_v
                actor_loss=(log_prob*(log_prob-log_prob_target).detach()).mean()
                mean_loss=1e-3*mean.pow(2).mean()
                std_loss=1e-3*log_std.pow(2).mean()
                actor_loss+=mean_loss+std_loss
                actor.learn(actor_loss)
                # 软更新
                critic.soft_update()
            observation = observation_
            reward_totle += reward
        print("Ep: {} rewards: {}".format(episode, reward_totle))
        # if reward_totle > -10: RENDER = True
        all_ep_r.append(reward_totle)
        if episode % 20 == 0 and episode > 200:#保存神经网络参数
            save_data = {'net': actor.action_net.state_dict(), 'opt': actor.optimizer.state_dict(), 'i': episode}
            torch.save(save_data, "E:\model_SAC.pth")
    env.close()
    plt.plot(np.arange(len(all_ep_r)), all_ep_r)
    plt.xlabel('Episode')
    plt.ylabel('Moving averaged episode reward')
    plt.show()
else:
    print('SAC测试中...')
    aa=Actor()
    checkpoint_aa = torch.load("E:\model_SAC.pth")
    aa.action_net.load_state_dict(checkpoint_aa['net'])
    for j in range(10):
        state = env.reset()
        total_rewards = 0
        for timestep in range(EP_LEN):
            env.render()
            action = aa.choose_action(state)
            new_state, reward, done, info = env.step(action)  # 执行动作
            total_rewards += reward
            state = new_state
        print("Score:", total_rewards)
    env.close()

所以,这里给出一份经典且标准的SAC代码,用的是pytorch框架,玩的是gym的Pendulum-v0游戏环境,是我翻了一下午从github的这份代码改来的。它的收敛效果图如下:
真SAC收敛图
多么漂亮的收敛图啊,这才是我SAC算法应有的实力嘛!!!!不愧是被大家伙吹上天的好算法啊,SAC的能力确实猛!!

至此,代码如下,拿走不谢,复制即用,不行砍我!

 # -*- coding: utf-8 -*-
#开发者:Bright Fang
#开发时间:2023/2/14 20:10
import torch
import torch.nn as nn
import torch.nn.functional as F
# device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
import numpy as np
import gym
from matplotlib import pyplot as plt
import os
os.environ['KMP_DUPLICATE_LIB_OK'] = 'TRUE'
env = gym.make("Pendulum-v0").unwrapped
'''Pendulum环境状态特征是三个,杆子的sin(角度)、cos(角度)、角速度,(状态是无限多个,因为连续),动作值是力矩,限定在[-2,2]之间的任意的小数,所以是连续的(动作也是无限个)'''
state_number=env.observation_space.shape[0]
action_number=env.action_space.shape[0]
max_action = env.action_space.high[0]
min_action = env.action_space.low[0]
RENDER=False
EP_MAX = 500
EP_LEN = 500
GAMMA = 0.9
q_lr = 3e-4
value_lr = 3e-3
policy_lr = 1e-3
BATCH = 128
tau = 1e-2
MemoryCapacity=10000
Switch=0

class ActorNet(nn.Module):
    def __init__(self,inp,outp):
        super(ActorNet, self).__init__()
        self.in_to_y1=nn.Linear(inp,256)
        self.in_to_y1.weight.data.normal_(0,0.1)
        self.y1_to_y2=nn.Linear(256,256)
        self.y1_to_y2.weight.data.normal_(0,0.1)
        self.out=nn.Linear(256,outp)
        self.out.weight.data.normal_(0,0.1)
        self.std_out = nn.Linear(256, outp)
        self.std_out.weight.data.normal_(0, 0.1)

    def forward(self,inputstate):
        inputstate=self.in_to_y1(inputstate)
        inputstate=F.relu(inputstate)
        inputstate=self.y1_to_y2(inputstate)
        inputstate=F.relu(inputstate)
        mean=max_action*torch.tanh(self.out(inputstate))#输出概率分布的均值mean
        log_std=self.std_out(inputstate)#softplus激活函数的值域>0
        log_std=torch.clamp(log_std,-20,2)
        std=log_std.exp()
        return mean,std

class CriticNet(nn.Module):
    def __init__(self,input,output):
        super(CriticNet, self).__init__()
        #q1
        self.in_to_y1=nn.Linear(input+output,256)
        self.in_to_y1.weight.data.normal_(0,0.1)
        self.y1_to_y2=nn.Linear(256,256)
        self.y1_to_y2.weight.data.normal_(0,0.1)
        self.out=nn.Linear(256,1)
        self.out.weight.data.normal_(0,0.1)
        #q2
        self.q2_in_to_y1 = nn.Linear(input+output, 256)
        self.q2_in_to_y1.weight.data.normal_(0, 0.1)
        self.q2_y1_to_y2 = nn.Linear(256, 256)
        self.q2_y1_to_y2.weight.data.normal_(0, 0.1)
        self.q2_out = nn.Linear(256, 1)
        self.q2_out.weight.data.normal_(0, 0.1)
    def forward(self,s,a):
        inputstate = torch.cat((s, a), dim=1)
        #q1
        q1=self.in_to_y1(inputstate)
        q1=F.relu(q1)
        q1=self.y1_to_y2(q1)
        q1=F.relu(q1)
        q1=self.out(q1)
        #q2
        q2 = self.in_to_y1(inputstate)
        q2 = F.relu(q2)
        q2 = self.y1_to_y2(q2)
        q2 = F.relu(q2)
        q2 = self.out(q2)
        return q1,q2

class Memory():
    def __init__(self,capacity,dims):
        self.capacity=capacity
        self.mem=np.zeros((capacity,dims))
        self.memory_counter=0
    '''存储记忆'''
    def store_transition(self,s,a,r,s_):
        tran = np.hstack((s, [a.squeeze(0),r], s_))  # 把s,a,r,s_困在一起,水平拼接
        index = self.memory_counter % self.capacity#除余得索引
        self.mem[index, :] = tran  # 给索引存值,第index行所有列都为其中一次的s,a,r,s_;mem会是一个capacity行,(s+a+r+s_)列的数组
        self.memory_counter+=1
    '''随机从记忆库里抽取'''
    def sample(self,n):
        assert self.memory_counter>=self.capacity,'记忆库没有存满记忆'
        sample_index = np.random.choice(self.capacity, n)#从capacity个记忆里随机抽取n个为一批,可得到抽样后的索引号
        new_mem = self.mem[sample_index, :]#由抽样得到的索引号在所有的capacity个记忆中  得到记忆s,a,r,s_
        return new_mem
class Actor():
    def __init__(self):
        self.action_net=ActorNet(state_number,action_number)#这只是均值mean
        self.optimizer=torch.optim.Adam(self.action_net.parameters(),lr=policy_lr)

    def choose_action(self,s):
        inputstate = torch.FloatTensor(s)
        mean,std=self.action_net(inputstate)
        dist = torch.distributions.Normal(mean, std)
        action=dist.sample()
        action=torch.clamp(action,min_action,max_action)
        return action.detach().numpy()
    def evaluate(self,s):
        inputstate = torch.FloatTensor(s)
        mean,std=self.action_net(inputstate)
        dist = torch.distributions.Normal(mean, std)
        noise = torch.distributions.Normal(0, 1)
        z = noise.sample()
        action=torch.tanh(mean+std*z)
        action=torch.clamp(action,min_action,max_action)
        action_logprob=dist.log_prob(mean+std*z)-torch.log(1-action.pow(2)+1e-6)
        return action,action_logprob,z,mean,std

    def learn(self,actor_loss):
        loss=actor_loss
        self.optimizer.zero_grad()
        loss.backward()
        self.optimizer.step()

class Entroy():
    def __init__(self):
        self.target_entropy = -action_number
        self.log_alpha = torch.zeros(1, requires_grad=True)
        self.alpha = self.log_alpha.exp()
        self.optimizer = torch.optim.Adam([self.log_alpha], lr=q_lr)

    def learn(self,entroy_loss):
        loss=entroy_loss
        self.optimizer.zero_grad()
        loss.backward()
        self.optimizer.step()

class Critic():
    def __init__(self):
        self.critic_v,self.target_critic_v=CriticNet(state_number,action_number),CriticNet(state_number,action_number)#改网络输入状态,生成一个Q值
        self.optimizer = torch.optim.Adam(self.critic_v.parameters(), lr=value_lr,eps=1e-5)
        self.lossfunc = nn.MSELoss()
    def soft_update(self):
        for target_param, param in zip(self.target_critic_v.parameters(), self.critic_v.parameters()):
            target_param.data.copy_(target_param.data * (1.0 - tau) + param.data * tau)

    def get_v(self,s,a):
        return self.critic_v(s,a)

    def learn(self,current_q1,current_q2,target_q):
        loss = self.lossfunc(current_q1, target_q) + self.lossfunc(current_q2, target_q)
        self.optimizer.zero_grad()
        loss.backward()
        self.optimizer.step()
if Switch==0:
    print('SAC训练中...')
    actor = Actor()
    critic = Critic()
    entroy=Entroy()
    M = Memory(MemoryCapacity, 2 * state_number + action_number + 1)
    all_ep_r = []
    for episode in range(EP_MAX):
        observation = env.reset()  # 环境重置
        reward_totle = 0
        for timestep in range(EP_LEN):
            if RENDER:
                env.render()
            action = actor.choose_action(observation)
            observation_, reward, done, info = env.step(action)  # 单步交互
            M.store_transition(observation, action, reward, observation_)
            # 记忆库存储
            # 有的2000个存储数据就开始学习
            if M.memory_counter > MemoryCapacity:
                b_M = M.sample(BATCH)
                b_s = b_M[:, :state_number]
                b_a = b_M[:, state_number: state_number + action_number]
                b_r = b_M[:, -state_number - 1: -state_number]
                b_s_ = b_M[:, -state_number:]
                b_s = torch.FloatTensor(b_s)
                b_a = torch.FloatTensor(b_a)
                b_r = torch.FloatTensor(b_r)
                b_s_ = torch.FloatTensor(b_s_)
                new_action, log_prob_, z, mean, log_std = actor.evaluate(b_s_)
                target_q1,target_q2=critic.get_v(b_s_,new_action)
                target_q=b_r+GAMMA*(torch.min(target_q1,target_q2)-entroy.alpha*log_prob_)
                current_q1, current_q2 = critic.get_v(b_s, b_a)
                critic.learn(current_q1,current_q2,target_q.detach())
                a,log_prob,_,_,_=actor.evaluate(b_s)
                q1,q2=critic.get_v(b_s,a)
                q=torch.min(q1,q2)
                actor_loss = (entroy.alpha * log_prob - q).mean()
                actor.learn(actor_loss)
                alpha_loss = -(entroy.log_alpha.exp() * (log_prob + entroy.target_entropy).detach()).mean()
                entroy.learn(alpha_loss)
                entroy.alpha=entroy.log_alpha.exp()
                # 软更新
                critic.soft_update()
            observation = observation_
            reward_totle += reward
        print("Ep: {} rewards: {}".format(episode, reward_totle))
        # if reward_totle > -10: RENDER = True
        all_ep_r.append(reward_totle)
        if episode % 20 == 0 and episode > 200:#保存神经网络参数
            save_data = {'net': actor.action_net.state_dict(), 'opt': actor.optimizer.state_dict(), 'i': episode}
            torch.save(save_data, "E:\model_SAC.pth")
    env.close()
    plt.plot(np.arange(len(all_ep_r)), all_ep_r)
    plt.xlabel('Episode')
    plt.ylabel('Moving averaged episode reward')
    plt.show()
else:
    print('SAC测试中...')
    aa=Actor()
    checkpoint_aa = torch.load("E:\model_SAC.pth")
    aa.action_net.load_state_dict(checkpoint_aa['net'])
    for j in range(10):
        state = env.reset()
        total_rewards = 0
        for timestep in range(EP_LEN):
            env.render()
            action = aa.choose_action(state)
            new_state, reward, done, info = env.step(action)  # 执行动作
            total_rewards += reward
            state = new_state
        print("Score:", total_rewards)
    env.close()

代码用法:

先把Switch标志位赋为0,先训练,等待训练结束后画出图形。然后,把Switch标志为赋为1进行测试,就可以看到训练的效果了。神经网络的参数被我们保存在了路径:E盘里。所以,别告诉我,你的电脑没有E盘,没有就自己改路径。

remark:

1.神经网络的参数被保存在了电脑E盘里,别告诉我你的电脑没有E盘。没有自己改代码。

2.我感觉版本信息不重要,但还是给一下以供参考。我用的gym版本:0.19.0;我用的pytorch版本:1.10.0+cu113;python版本:3.8

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

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

相关文章

后端,我是认真的

web框架介绍 1. 什么是web框架 应该叫web应用框架(web application framework)是一种开发框架。 通俗点来说,就是用来开发web应用的程序。 2. 为什么要使用框架来开发 互联网行业流行一句话叫“不要重复造轮子”,特别是对于新手和应用层开发人员。对于w…

TLP5754的代替品SLM343兼容光耦的单通道隔离驱动 应用解决方法

TLP5754的代替品SLM343兼容光耦的单通道隔离驱动应用解决方法是一种光兼容的单通道隔离MOSFET、IGBT具有不同驱动电流能力的栅极驱动器,以及UVLO电压电平。峰值输出电流为4.0A。主要特点和特点带来显著的性能和可靠性。性能亮点包括高共模瞬态抗扰度(CMT…

给 “rm” 命令添加个“回收站”,再也不用担心误删文件了!

1.rm命令解析 rm命令可以删除一个目录中的一个或多个文件或目录,也可以将某个目录及其下属的所有文件及其子目录均删除掉。对于链接文件,只是删除整个链接文件,而原有文件保持不变。 注意:使用rm命令要格外小心。因为一旦删除了…

WebSocket内存马之tomcat-websocket源码实现(内存马系列篇七)

写在前面 这篇主要是分析一下WebSocket协议在Tomcat容器中的源码实现,方便大家在后面能够更好的了解下一篇Websocket型内存马的原理。 这个也是内存马系列第七篇 Websocket 什么是websocket? 首先来了解一下什么是websocket WebSocket全双工通信协…

2023-2-16 刷题情况

神经网络 题目背景 人工神经网络(Artificial Neural Network)是一种新兴的具有自我学习能力的计算系统,在模式识别、函数逼近及贷款风险评估等诸多领域有广泛的应用。对神经网络的研究一直是当今的热门方向,兰兰同学在自学了一本…

Airtest自动化测试工具介绍

官方网站:http://airtest.netease.com/ Airtest IDE: 跨平台的UI自动化测试编辑器,适用于游戏和App,详细参见官网文档:http://airtest.netease.com/docs/cn/index.html 这是Airtest测试工具标配的IDE,目…

Eclipse插件安装全方式介绍(优化版)

Eclipse插件安装方式 Eclipse插件安装有很多种方式,常见的有以下四种: [在线安装] -使用插件地址安装[在线安装] - 通过插件市场查找插件安装[离线安装]- 下载插件文件后复制文件Eclipse目录[离线安装]- 外部引用 本篇以安装Eclipse Tomcat插件为例进…

#8排序算法#

1.排序 1概念 排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起 来的操作。 稳定性:假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排…

AWS攻略——使用ACL限制访问

文章目录确定出口IP修改ACL修改主网络ACL修改入站规则修改子网ACL创建子网ACL新增入站规则新增出站规则关联子网假如我们希望限制只有公司内部的IP可以SSH登录到EC2,则可以考虑使用ACL来实现。 我们延续使用《AWS攻略——创建VPC》的案例,在它的基础上做…

Spring 系列 - AOP

Spring 系列 - AOP Spring 框架从使用到现在已经有相当的长的一段时间了,但总是在使用的时候,感觉一直停留在表面,对框架的底层了解的并不多,最近一段时间,打算好好折腾一下 Spring 的底层,想对 Spring 有…

智能家居项目(二)之工厂模式的实现

目录 一、举例说明:把下面的代码转换成工厂模式的方式来实现 二、用工厂模式的方式来实现 1、创建三个函数的文件 2、创建一个 Animal.h文件,把上述三个函数名都放在这个文件中 3、创建一个main主函数文件 4、用工厂模式创建的文件浏览 一、举例说…

用主动游泳的三维水母模型量化美杜莎的(medusan)机械空间的性能(三)(2017)

文章目录用主动游泳的三维水母模型量化美杜莎的(medusan)机械空间的性能(三)(2017)原文链接:https://doi.org/10.1017/jfm.2017.34. 讨论小结用主动游泳的三维水母模型量化美杜莎的(medusan)机械…

iptables防火墙详解

目录iptables防火墙iptables简介iptables表filter(过滤表)nat(网络地址转换表)mangle(修改表)raw(原始表)security 表处理目标REJECT(拒绝)DNAT(目的网络地址转换)SNAT(源网络地址转换)MASQUERADE(伪装)LOGREDIRECT报文处理流程规则表之间的优先顺序报文规则匹配管理防火墙规则…

单调栈---神奇的栈

我们平时用的栈多,但是我们一般用的是什么呢?用来做有效的括号匹配?还是用来记录我们的二叉树的节点? 通过对栈的理解,我们学习一个新的概念–单调栈。所谓单调栈,就是单调递增或者单调递减的栈。 那么单…

第四届宁波网安市赛初赛

由于赛后官方不给wp(绿盟一向如此),交流群也没有得到其他题解,赛后就根据自己的wp来写了,wp由队友及我共同完成。比赛共解答10题,Web 5道,Misc 2道,Crypto 3道,wp只有一部…

深度学习算法面试常问问题(一)

博主秋招遇到的面试问题以及整理其他面经相关问题,无偿分享~ 项目叙述: 算法需求及应用场景算法的调研和初步方案的制定数据的准备(包括数据标注和数据增强)算法的介绍(包括输入和输出,loss、backbone、训…

做外贸,你不能不懂的外贸流程知识

报关是履行海关进出境手续的必要环节之一,涉及两大类:进出境运输工具、物品和货物。由于性质不同,报关手续也有些不同。今天我就为大家详细介绍一下进出口报关的流程,包括出口货物报关的流程,随报关单提交的运费和商业单据&#x…

Spark中cache、persist、checkpoint三者的比较

原文链接:https://blog.csdn.net/AnameJL/article/details/124362219,再次主要是为了方便查找,把原文章复制一遍 目录 1. 三者的使用 1.1 cache的讲解与使用 1.2 persist的讲解与使用 1.3checkpoint 的讲解与使用 2. 三者的比较 2.1 优…

基于Web的智慧能源可视化管理系统

自工业革命开始,全球能源消耗持续增长,由碳循环体系破坏引发的全球变暖、海平面上升等问题严重影响着人类的可持续发展。得益于数字孪生、物联网、5G、AI识别等技术的不断成熟,以“大数据能源监控、精细化能源管理”为核心的智慧能源解决方案…

【电子学会】2022年12月图形化三级 -- 绘制雷达

绘制雷达 1. 准备工作 (1)绘制黑色背景; (2)删除默认角色小猫,添加角色Pencil。 2. 功能实现 (1)画笔的颜色设为黄色,Pencil的中心点设在笔尖位置,画笔的…