搭建PyTorch神经网络进行气温预测(手写+调包两种方法)(保证学会!)+找到神经网络的最优情况

代码上有注释!!!!!!

本篇主要包括三大部分:

第一部分:导入数据集+导入第三方库+数据集简单介绍与可视化+数据集简单预处理

第二部分:手写神经网络代码实现气温预测(手写)

第三部分:调包搭建神经网络实现气温预测(调包)+找到最优网络模型及其参数

​​​​​​​

目录

第一部分  准备数据

(一)导入第三方库

(二) 导入数据集

(三)数据可视化

​编辑

 (四)独热编码处理

 (五)数据标准化

第二部分 人工手写神经网络 

(一)将数据转换成tensor形式

 (二)权重、偏置初始化

(三)设置学习率

(四) 训练网络

第三部分 调包实现神经网络预测气温

(一)设置参数

(二)调用torch.nn中的Sequential序列模块

 (三)损失函数

(四)优化器

(五)训练网络

(六)预测结果

 (七)预测结果和真实标签进行可视化对比

 (八)找到最优模型及其参数


第一部分  准备数据

(一)导入第三方库

import numpy as np
import pandas as pd 
import matplotlib.pyplot as plt
import torch
import torch.optim as optim
import warnings
warnings.filterwarnings("ignore")
%matplotlib inline

①import warnings 和  warnings.filterwarnings("ignore"):

导入Python的warnings模块,用于处理警告信息。设置忽略警告信息,这样在后续运行代码时不会显示警告。主要是排除版本不同时的警告。


②%matplotlib inline:

这是Jupyter Notebook的魔术命令,用于在Notebook中显示matplotlib绘制的图形,而不是弹出新窗口显示图形。

(二) 导入数据集

features = pd.read_csv('temps.csv')#看看数据长什么样子
features.head()

 前五行数据如下:

数据表中

  • year,moth,day,week分别表示的具体的时间
  • temp_2:前天的最高温度值
  • temp_1:昨天的最高温度值
  • average:在历史中,每年这一天的平均最高温度值
  • actual:这就是我们的标签值了,当天的真实最高温度
  • friend:这一列是凑热闹的,猜测的可能值,不用管这一列
print('数据维度:', features.shape)

说明数据中一共有348个样本,9个特征。

(三)数据可视化

# 处理时间数据
import datetime
# 分别得到年,月,日
years = features['year']
months = features['month']
days = features['day']# datetime格式
dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]
dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in dates]
dates[:5]

打印一下dates[:5],查看前五行数据,结果如下:

两个零分别代表小时和分钟

# 准备画图
# 指定默认风格
plt.style.use('fivethirtyeight')# 设置布局
fig, ((ax1, ax2), (ax3, ax4)) = plt.subplots(nrows=2, ncols=2, figsize = (10,10))
#subplots就是画子图2*2,((ax1, ax2), (ax3, ax4))分别是四个子图
fig.autofmt_xdate(rotation = 45)#x轴标签旋转度# 标签值
ax1.plot(dates, features['actual'])#表示第一个子图里边x轴和y轴分别是什么
ax1.set_xlabel(''); ax1.set_ylabel('Temperature'); ax1.set_title('Max Temp')
#在这x轴没画值,因为和子图3是一样的y轴,y轴的名称是Temperature,图的名字是Max Temp# 昨天
ax2.plot(dates, features['temp_1'])
ax2.set_xlabel(''); ax2.set_ylabel('Temperature'); ax2.set_title('Previous Max Temp')# 前天
ax3.plot(dates, features['temp_2'])
ax3.set_xlabel('Date'); ax3.set_ylabel('Temperature'); ax3.set_title('Two Days Prior Max Temp')#猜测的数值
ax4.plot(dates, features['friend'])
ax4.set_xlabel('Date'); ax4.set_ylabel('Temperature'); ax4.set_title('Friend Estimate')plt.tight_layout(pad=2)#每个子图之间的间隔

结果如下:

 (四)独热编码处理

# 独热编码 one-hot
# features = pd.get_dummies(features)#帮你判断哪一列是字符串,自动地帮你把字符串直接展开
features = pd.get_dummies(features).astype(int)#输出打印体会一下加不加.astype(int)的区别
features.head(5)

前五行数据如下: 

# 标签
labels = np.array(features['actual'])# 在特征中去掉标签
features= features.drop('actual', axis = 1)#把标签这一列踢出去# 名字单独保存一下,以备后患
feature_list = list(features.columns)# 转换成合适的格式
features = np.array(features)
features.shape

 

 (五)数据标准化

#标准化
from sklearn import preprocessing
#preprocessing预处理模块
input_features = preprocessing.StandardScaler().fit_transform(features)

 结果如下:

如上: 现在所有的值都是数组的结构,但torch要tensor的格式结构,所以下面要将数组形式转换成tensor的形式。

第二部分 人工手写神经网络 

(一)将数据转换成tensor形式

#把要用的数据转换成tensor的格式
x = torch.tensor(input_features, dtype = float)
y = torch.tensor(labels, dtype = float)

x就作为输入数据,是348*14的维度 

 (二)权重、偏置初始化

# 权重参数初始化
#w,b都是随机初始化
weights = torch.randn((14, 128), dtype = float, requires_grad = True) 
biases = torch.randn(128, dtype = float, requires_grad = True) 
weights2 = torch.randn((128, 1), dtype = float, requires_grad = True) 
biases2 = torch.randn(1, dtype = float, requires_grad = True) 

requires_grad = True:进行计算梯度

 在这里构建了两个隐藏层,权重w和偏置b都是进行的随机初始化

由于输入数据的维度是384*14

故第一个隐藏层的权重weights是14*128的矩阵,偏置biases长度为128

第二个隐藏层的权重weights2是128*1的行向量,偏置biases2长度为1

因为这里是做回归,也就是预测某一时刻的温度,最终输出的是一个值,故最终的权重weights的维度是128*1

 

这里补充一点:

输入数据x的维度是348*14,第一个隐藏层的权重weights维度为14*128,那么x*weights做矩阵运算后的结果维度是348*128,但是偏置biases的维度是torch.Size([128]),相当于可以看作是有128个元素的行向量,那么一个348*128的矩阵,怎么和一个1*128的行向量进行加法运算呢?

在这种情况下,PyTorch会自动将大小为 [128] 的张量 biases扩展为大小为 [348, 128] 的张量,使得两个张量的形状相匹配,然后再进行逐元素的加法运算。具体来说,PyTorch会将大小为 [128] 的行向量biases 在第二维上进行复制,扩展为大小为 [348, 128] 的矩阵,然后再与x*weights的结果进行逐元素相加。

(三)设置学习率

learning_rate = 0.001 

学习率是可以自己设置的

更新参数的话,我们要沿着一个方向进行参数更新,这个学习率就是告诉我们要沿着这个方向走多大的距离

一般来说,学习率要相对小一点,如果太大了,模型可能做的就相对没有那么好了

(四) 训练网络

losses = []#损失
#迭代更新1000次
for i in range(1000):# 计算隐层hidden = x.mm(weights) + biases#x.mm就是一个矩阵乘法  x*w+b#一般计算好隐藏层后,都要进行一个非线性映射#非线性映射里边也有很多函数,比如这里就用到了rule,小于0的时候都等于0,大于0的时候都等于x,y=x# 加入激活函数hidden = torch.relu(hidden)#得到实际隐藏层结果# 预测结果predictions = hidden.mm(weights2) + biases2#计算损失loss = torch.mean((predictions - y) ** 2) #计算的是均方误差#现在loss是tensor的格式,如果要画图的话,需要的是数组的格式losses.append(loss.data.numpy())# 打印损失值#每隔一百次打印一次损失if i % 100 == 0:print('loss:', loss)#返向传播计算loss.backward()#更新参数w,b#在这里这么理解一下,一会其实可以调包的weights.data.add_(- learning_rate * weights.grad.data)  #weights.grad.data取这一次反向传播的梯度值#沿着梯度的反方向进行更新,所以有这个-负号biases.data.add_(- learning_rate * biases.grad.data)weights2.data.add_(- learning_rate * weights2.grad.data)biases2.data.add_(- learning_rate * biases2.grad.data)# 每次迭代都得记得清空#每一次迭代都应该是独立的,和上一次没关系#torch如果没有清零,它会累加weights.grad.data.zero_()biases.grad.data.zero_()weights2.grad.data.zero_()biases2.grad.data.zero_()

 通过下边的结果,可以发现它的losse是随着迭代次数的增加不断降低的,最终趋于平稳。

 结果如下:

 下边是迭代结束后第一个隐藏层权重和偏置的参数,明显和初始随机初始化的参数不同,说明参数进行了梯度更新。

 注意:

循环结束后打印的参数值是最后一次迭代后的参数值,但不一定是最优参数值。要获取最优参数值,需要在训练过程中记录并比较每次迭代的性能,从而找到最佳的参数。

第三部分 调包实现神经网络预测气温

(一)设置参数

input_size = input_features.shape[1]#输入特征的个数  14个
hidden_size = 128#隐藏层 可以自己改
output_size = 1#输出值 一个
batch_size = 16

input_size表示输入特征的个数,这里是14个

hidden_size = 128:隐藏层有128个隐藏单元。

output_size = 1:这行代码定义了输出值的大小,即模型输出一个标量值。

batch_size:表示每个批次包含16个样本

(二)调用torch.nn中的Sequential序列模块

在调包环节中,和我们第二部分手写神经网络代码不同,权重参数、偏置参数是自动帮我们初始化的

#下边就是调包环节了
#torch.nn中的一个Sequential序列模块,就是按顺序,先执行第一个,再执行第二个,以此类推
#我定义的序列叫做my_nn
my_nn = torch.nn.Sequential(torch.nn.Linear(input_size, hidden_size),#全连接层,权重参数是自动帮我们初始化的torch.nn.Sigmoid(),#nn.ReLu()#激活函数torch.nn.Linear(hidden_size, output_size),
)

 (三)损失函数

cost = torch.nn.MSELoss(reduction='mean')#损失函数

 torch.nn.MSELoss:这是 PyTorch 中用于计算均方误差的类。
reduction='mean':这是 torch.nn.MSELoss 类的一个参数,用于指定损失的计算方式。
在这里,设置为 'mean' 表示计算所有样本的均方误差后再取平均值作为最终损失值

(四)优化器

optimizer = torch.optim.Adam(my_nn.parameters(), lr = 0.001)

Adam优化器效率高 效果好

my_nn.parameters()表示将神经网络模型my_nn的所有参数传递给优化器,以便优化这些参数。lr=0.001表示学习率为0.001,即Adam优化器在更新参数时所采用的学习率。

(五)训练网络

# 训练网络
losses = []
for i in range(1000):batch_loss = []# MINI-Batch方法来进行训练for start in range(0, len(input_features), batch_size):end = start + batch_size if start + batch_size < len(input_features) else len(input_features)
# 如果 start + batch_size 的结果小于 input_features 的长度(即 len(input_features)),则将 end 的值设为 start + batch_size。
# 否则,如果 start + batch_size 的结果大于或等于 input_features 的长度,那么 end 的值将设为 len(input_features)xx = torch.tensor(input_features[start:end], dtype = torch.float, requires_grad = True)yy = torch.tensor(labels[start:end], dtype = torch.float, requires_grad = True)prediction = my_nn(xx)loss = cost(prediction, yy)optimizer.zero_grad()#梯度清零loss.backward(retain_graph=True)#反向传播optimizer.step()#反向传播之后再进行参数更新batch_loss.append(loss.data.numpy())#print(len(batch_loss))#结果是22 len(input_features)=348  batch_size=16,21*16+12=348# 打印损失,每更新迭代一百次打印一次损失if i % 100==0:losses.append(np.mean(batch_loss))
#         print(losses)print(i, np.mean(batch_loss))

结果如下:

 

在这段代码中,通过迭代训练神经网络来降低损失函数值,使得神经网络的预测结果更接近真实标签。在每次迭代过程中,会计算一个 mini-batch 的损失值,并根据这个 mini-batch 更新神经网络的参数。
最终目的是通过不断迭代训练,使得损失函数值逐渐减小,达到一个较好的模型效果。


# 在代码中,损失值逐渐减小的原因可能有以下几点:

梯度下降优化算法:通过调用 optimizer.step() 方法,使用梯度下降算法来更新神经网络的参数,使得损失值逐渐减小。

学习率调整:在梯度下降算法中,学习率的设置对模型训练的效果有很大影响。合适的学习率能够使得模型更快地收敛到最优解。

迭代次数:在迭代次数足够多的情况下,模型有更多的机会逐渐优化参数,从而使得损失值逐渐减小。

Mini-batch 训练:使用 mini-batch 训练方法,可以更有效地利用计算资源,同时也有助于模型的收敛。

综合以上因素,随着迭代次数的增加,损失值逐渐减小是一个正常的训练过程。当损失值趋于稳定时,可以认为模型已经收敛到一个较好的状态。

(六)预测结果

x = torch.tensor(input_features, dtype = torch.float)
predict = my_nn(x).data.numpy() #每一个样本,也就是每一天的预测值

 预测结果如下:

 (七)预测结果和真实标签进行可视化对比

# 转换日期格式
dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]
dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in dates]# 创建一个表格来存日期和其对应的标签数值
true_data = pd.DataFrame(data = {'date': dates, 'actual': labels})

# 同理,再创建一个来存日期和其对应的模型预测值
months = features[:, feature_list.index('month')]
days = features[:, feature_list.index('day')]
years = features[:, feature_list.index('year')]test_dates = [str(int(year)) + '-' + str(int(month)) + '-' + str(int(day)) for year, month, day in zip(years, months, days)]test_dates = [datetime.datetime.strptime(date, '%Y-%m-%d') for date in test_dates]predictions_data = pd.DataFrame(data = {'date': test_dates, 'prediction': predict.reshape(-1)}) 

# 真实值
plt.plot(true_data['date'], true_data['actual'], 'b-', label = 'actual')# 预测值
plt.plot(predictions_data['date'], predictions_data['prediction'], 'ro', label = 'prediction')
plt.xticks(rotation = 60)
plt.legend()#添加图例# 图名
plt.xlabel('Date'); plt.ylabel('Maximum Temperature (F)'); plt.title('Actual and Predicted Values');

结果如下:

 (八)找到最优模型及其参数

我们试想,上边预测出来的结果,是在最优参数模型情况下吗?其实并不是的,是在最后一次迭代结束后的参数基础上进行的预测。

下边我们一起学习一下寻找最优模型及其参数的过程。

# 训练网络
losses = []
# 初始化 best_loss 为一个很大的值,确保第一次比较不会出错
best_loss = float('inf')
import copyfor i in range(1000):batch_loss = []# MINI-Batch方法来进行训练for start in range(0, len(input_features), batch_size):end = start + batch_size if start + batch_size < len(input_features) else len(input_features)
# 如果 start + batch_size 的结果小于 input_features 的长度(即 len(input_features)),则将 end 的值设为 start + batch_size。
# 否则,如果 start + batch_size 的结果大于或等于 input_features 的长度,那么 end 的值将设为 len(input_features)xx = torch.tensor(input_features[start:end], dtype = torch.float, requires_grad = True)yy = torch.tensor(labels[start:end], dtype = torch.float, requires_grad = True)prediction = my_nn(xx)#print(prediction)loss = cost(prediction, yy)optimizer.zero_grad()#梯度清零loss.backward(retain_graph=True)#反向传播optimizer.step()#反向传播之后再进行参数更新batch_loss.append(loss.data.numpy())#print(len(batch_loss))#结果是22 len(input_features)=348  batch_size=16,21*16+12=348# 计算整体损失xx_val = torch.tensor(input_features, dtype=torch.float)yy_val = torch.tensor(labels, dtype=torch.float)prediction_val = my_nn(xx_val)loss_val = cost(prediction_val, yy_val)val_loss = loss_val.data.numpy()# 如果当前epoch的验证损失更低,则保存当前模型的权重if val_loss < best_loss:best_loss = val_lossbest_model_weights = copy.deepcopy(my_nn.state_dict())#     # 打印损失
#     if i % 100==0:
#         losses.append(np.mean(batch_loss))
# #         print(losses)
#         print(i, np.mean(batch_loss))

这里,我们在原先的代码上,做了一点小改动。

best_loss = float('inf'):表示最优损失,初始化 best_loss 为一个很大的值,确保第一次比较不会出错。

要得到最优情况下的模型,需要在训练过程中保存性能最好的模型权重。这可以通过在每次迭代结束时计算损失,并将其与之前的最佳损失进行比较来实现。如果当前迭代的损失更低,则保存当前模型的权重。

best_model_weights = copy.deepcopy(my_nn.state_dict()):执行这行代码,你可以保存当前神经网络模型的参数状态,以便在后续的训练过程中使用或恢复模型的状态。

最优参数如下:

<All keys matched successfully>的运行结果表示成功地将最佳模型的权重加载到了神经网络模型中。这意味着load_state_dict()方法成功地将最佳模型的权重参数与当前神经网络模型的相应参数进行匹配,并将最佳模型的权重参数加载到了当前模型中。

因此,<All keys matched successfully>的输出表明加载权重的过程顺利完成,当前模型已经成功地更新为最佳模型的状态,可以继续使用这个模型进行预测或其他任务。

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

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

相关文章

论文学习D2UNet:用于地震图像超分辨率重建的双解码器U-Net

标题&#xff1a;&#xff1a;Dual Decoder U-Net for Seismic Image Super-Resolution Reconstruction ——D2UNet&#xff1a;用于地震图像超分辨率重建的双解码器U-Net 期刊&#xff1a;IEEE Transactions on Geoscience and Remote Sensing 摘要&#xff1a;从U-Net派生…

linux中rpm包与deb包的区别及使用

文章目录 1. rpm与deb的区别2. deb软件包的格式和使用2.1 deb软件包命令遵行如下约定2.2 dpkg命令2.3 apt-命令 3. Unix和Linux的区别Reference 1. rpm与deb的区别 有的系统只支持使用rpm包安装&#xff0c;有的只支持deb包安装&#xff0c;混乱安装会导致系统问题。 关于rpm和…

手拉手安装启动Kafka2.13

启动Kafka本地环境需Java 8以上 Kafka是一种高吞吐量的分布式发布订阅消息系统&#xff0c;它可以处理消费者在网站中的所有动作流数据。 这种动作&#xff08;网页浏览&#xff0c;搜索和其他用户的行动&#xff09;是在现代网络上的许多社会功能的一个关键因素。 Kafka启动…

【ubuntu20.04】安装GeographicLib

下载地址 GeographicLib: Installing GeographicLib 我们是ubuntu20.04 &#xff0c;所以下载第一个 GeographicLib-2.3.tar.gz 接着跟着官方步骤安装&#xff0c;会出错&#xff01;&#xff01;&#xff01;&#xff01;马的 官方错误示例&#xff1a;tar xfpz Geographi…

无重复字符串的最长子串

题目描述&#xff1a;给定一个字符串 s &#xff0c;请你找出其中不含有重复字符的 最长子串的长度。 第一次提交记录 class Solution:def lengthOfLongestSubstring(self, s: str) -> int:if not s:return 0lookup set()left res 0for right in range(len(s)):while s…

基于Springboot的箱包存储系统(有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的箱包存储系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&…

一辆新能源汽车需要多少颗传感器?

随着科技的发展和环保意识的日益提高&#xff0c;新能源汽车&#xff08;包括纯电动汽车、混合动力汽车等&#xff09;在全球范围内越来越受到欢迎。这些汽车不仅减少了碳排放&#xff0c;还推动了汽车产业的创新。然而&#xff0c;这些高科技汽车的背后&#xff0c;隐藏着许多…

9.vector的使用介绍和模拟实现

1.vector的介绍及使用 1.1 vector的介绍 vector的文档介绍 vector是表示可变大小数组的序列容器。 就像数组一样&#xff0c;vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vector的元素进行访问&#xff0c;和数组一样高效。但是又不像数组&#xff0c…

Another Redis Desktop Manager下载安装使用

天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物。 每个人都有惰性&#xff0c;但不断学习是好好生活的根本&#xff0c;共勉&#xff01; 文章均为学习整理笔记&#xff0c;分享记录为主&#xff0c;如有错误请指正&#xff0c;共同学习进步。…

基因组组装:Hifiasm 使用教程

简介 Hifiasm[1] 是一个快速的单倍型解析 de novo 组装软件&#xff0c;最初设计用于 PacBio HiFi 读取。其最新版本可以通过利用超长的 Oxford Nanopore 读取支持端粒到端粒的组装。Hifiasm 可以生成单样本端粒到端粒的组装&#xff0c;结合了 HiFi、超长和 Hi-C 读取&#xf…

【XR806开发板试用】自带mqtt的调试教学

1、下载代码 mkdir xr806_openharmony cd xr806_openharmony repo init -u ssh://gitgitee.com/openharmony-sig/manifest.git -b OpenHarmony_1.0.1_release --no-repo-verify -m devboard_xr806.xml repo sync -c repo forall -c git lfs pull **最近仓库在整合&#xff…

[Classifier-Guided] Diffusion Models Beat GANs on Image Synthesis

1、介绍 针对diffusion models不如GAN的原因进行改进&#xff1a; 1&#xff09;充分探索网络结构 2&#xff09;在diversity和fidelity之间进行trade off 2、改进 1&#xff09;在采样步数更少的情况下&#xff0c;方差设置为固定值并非最优。需要将表示为网络预测的v ​​​…

前端开发攻略---Vue通过自定义指令实现元素平滑上升的动画效果(可以自定义动画时间、动画效果、动画速度等等)。

1、演示 2、介绍 这个指令不是原生自带的&#xff0c;需要手动去书写&#xff0c;但是这辈子只需要编写这一次就好了&#xff0c;后边可以反复利用。 3、关键API IntersectionObserver IntersectionObserver 是一个用于监测元素是否进入或离开视口&#xff08;viewport&#x…

08 - 镜像管理之:镜像仓库harbor介绍

本文参考&#xff1a;原文1 1 Harbor仓库介绍 Docker容器应用的开发和运行离不开可靠的镜像管理&#xff0c;虽然Docker官方也提供了公共的镜像仓库&#xff0c;但是从安全和效率等方面考虑&#xff0c;部署我们私有环境内的Registry 也是非常必要的。 之前介绍了Docker私有仓…

priority_queue的使用以及模拟实现

前言 上一期我们对stack和queue进行了使用的介绍&#xff0c;以及对底层的模拟实现&#xff01;以及容器适配器做了介绍&#xff0c;本期我们在来介绍一个容器适配器priority_queue&#xff01; 本期内容介绍 priority_queue的使用 仿函数介绍 priority_queue的模拟实现 什么…

自动驾驶规划方法综述

自动驾驶规划方法综述 附赠自动驾驶学习资料和量产经验&#xff1a;链接 最近看到一篇非常好的关于自动驾驶规划方法的综述&#xff08;A Review of Motion Planning Techniques for Automated Vehicles&#xff09;&#xff0c;写的非常好&#xff0c;总结了近几十年来总动驾…

YOLOv5实战记录06 Gradio搭建Web GUI

个人打卡&#xff0c;慎看。 指路大佬&#xff1a;【手把手带你实战YOLOv5-入门篇】YOLOv5 Gradio搭建Web GUI_哔哩哔哩_bilibili 先放一张效果图&#xff1a; 零、虚拟环境激活 之前up说要激活环境时&#xff0c;我没当回事儿&#xff0c;今天突然想&#xff0c;激活环境然后…

LangChain教程 | 实践过程报错集 | 持续更新

这是本人最近在做langchain教程过程中的遇到的报错&#xff0c;不分先后顺序。 报错&#xff1a;TypeError: NoneType object is not iterable 这个报错很常见&#xff0c;咱们要看原始报错的位置是哪里&#xff0c;下面是我的截图&#xff1a; 找到源头之后&#xff0c;就在源…

缝合的作品(并查集/逆序)

、思路&#xff1a;首先是并查集来做&#xff0c;首先给给每个单词一个id&#xff0c;然后把它放到ans[i]处。 对于操作1&#xff1a;把a单词换为单词b&#xff0c;就相当于a、b两个集合结合。然后再给a单词赋一个新的id&#xff0c;用来进行操作2&#xff0c;因为之后的操作2…

蓝桥杯-【二分】肖恩的苹果林

思路:有点类似于找最大值的最小化。 代码及解析 常规的模板引用40% #include <bits/stdc.h> using namespace std; #define ll long long const ll N1e53; ll a[N]; ll m,n; ll chack(ll mid) {int res1,last0;for(int i1;i<n;i){ if(a[i]-a[last]>mid){res;las…