第86步 时间序列建模实战:Transformer回归建模

news2024/11/16 21:51:40

基于WIN10的64位系统演示

一、写在前面

这一期,我们介绍Transformer回归。

同样,这里使用这个数据:

《PLoS One》2015年一篇题目为《Comparison of Two Hybrid Models for Forecasting the Incidence of Hemorrhagic Fever with Renal Syndrome in Jiangsu Province, China》文章的公开数据做演示。数据为江苏省2004年1月至2012年12月肾综合症出血热月发病率。运用2004年1月至2011年12月的数据预测2012年12个月的发病率数据。

二、Transformer回归

(1)原理

Transformer框架原本是为NLP任务,特别是机器翻译而设计的。但由于其独特的自注意力机制,Transformer在处理顺序数据时表现出色,因此被广泛应用于各种序列数据任务,包括回归任务。

(a)回归任务中的Transformer:

(a1)在回归任务中,Transformer可以捕捉数据中的长期依赖关系。例如,在时间序列数据中,Transformer可以捕捉时间点之间的关系,即使这些时间点相隔很远。

(a2)为回归任务使用Transformer时,通常需要稍微调整模型结构,特别是模型的输出部分。原始的Transformer用于生成序列,但在回归任务中,我们通常需要一个单一的实数作为输出。

(b)Transformer的优点:

(b1)自注意力机制:可以捕捉序列中的任意位置间的依赖关系,而不像RNN那样依赖于前面的信息。

(b2)并行计算:与RNN或LSTM不同,Transformer不需要按顺序处理数据,因此更容易并行处理,提高训练速度。

(b3)可扩展性:可以通过堆叠多个Transformer层来捕捉复杂的模式和关系。

模型解释性:由于自注意力机制,我们可以可视化哪些输入位置对于特定输出最为重要,这增加了模型的解释性。

(c)Transformer的缺点:

(c1)计算需求:尽管可以并行化,但Transformer模型,特别是大型模型,仍然需要大量的计算资源。

(c2)过拟合:在小型数据集上,特别是没有足够的正则化时,Transformer可能会过拟合。

(c3)长序列的挑战:尽管Transformer可以处理长序列,但由于自注意力机制的复杂性,处理非常长的序列仍然是一个挑战。为此,研究人员已经提出了许多变种,例如Reformer。

总体而言,Transformer提供了一个强大的框架来处理各种序列数据任务。

(2)单步滚动预测

import pandas as pd
import numpy as np
from sklearn.metrics import mean_absolute_error, mean_squared_error
from tensorflow.python.keras.models import Sequential
from tensorflow.python.keras import layers, models, optimizers
from tensorflow.python.keras.optimizers import adam_v2

# 读取数据
data = pd.read_csv('data.csv')

# 将时间列转换为日期格式
data['time'] = pd.to_datetime(data['time'], format='%b-%y')

# 创建滞后期特征
lag_period = 6
for i in range(lag_period, 0, -1):
    data[f'lag_{i}'] = data['incidence'].shift(lag_period - i + 1)

# 删除包含 NaN 的行
data = data.dropna().reset_index(drop=True)

# 划分训练集和验证集
train_data = data[(data['time'] >= '2004-01-01') & (data['time'] <= '2011-12-31')]
validation_data = data[(data['time'] >= '2012-01-01') & (data['time'] <= '2012-12-31')]

# 定义特征和目标变量
X_train = train_data[['lag_1', 'lag_2', 'lag_3', 'lag_4', 'lag_5', 'lag_6']].values
y_train = train_data['incidence'].values
X_validation = validation_data[['lag_1', 'lag_2', 'lag_3', 'lag_4', 'lag_5', 'lag_6']].values
y_validation = validation_data['incidence'].values

# 对于Transformer,我们需要将输入数据重塑为 [samples, timesteps, features]
X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], 1)
X_validation = X_validation.reshape(X_validation.shape[0], X_validation.shape[1], 1)

# Transformer的一些参数设置
d_model = 128
num_heads = 4

# 构建Transformer回归模型
input_layer = layers.Input(shape=(X_train.shape[1], 1))

# Linear Embedding
x = layers.Dense(d_model)(input_layer)

# Multi Head Self Attention
x = layers.MultiHeadAttention(num_heads=num_heads, key_dim=d_model)(x, x)

# Feed Forward Neural Networks
x = layers.GlobalAveragePooling1D()(x)
x = layers.Dropout(0.1)(x)
x = layers.Dense(50, activation='relu')(x)
x = layers.Dropout(0.1)(x)
output_layer = layers.Dense(1)(x)

model = models.Model(inputs=input_layer, outputs=output_layer)

model.compile(optimizer=adam_v2.Adam(learning_rate=0.001), loss='mse')

# 训练模型
history = model.fit(X_train, y_train, epochs=200, batch_size=32, validation_data=(X_validation, y_validation), verbose=0)

# 单步滚动预测函数
def rolling_forecast(model, initial_features, n_forecasts):
    forecasts = []
    current_features = initial_features.copy()

    for i in range(n_forecasts):
        # 使用当前的特征进行预测
        forecast = model.predict(current_features.reshape(1, len(current_features), 1)).flatten()[0]
        forecasts.append(forecast)

        # 更新特征,用新的预测值替换最旧的特征
        current_features = np.roll(current_features, shift=-1)
        current_features[-1] = forecast

    return np.array(forecasts)

# 使用训练集的最后6个数据点作为初始特征
initial_features = X_train[-1].flatten()

# 使用单步滚动预测方法预测验证集
y_validation_pred = rolling_forecast(model, initial_features, len(X_validation))

# 计算训练集上的MAE, MAPE, MSE 和 RMSE
mae_train = mean_absolute_error(y_train, model.predict(X_train).flatten())
mape_train = np.mean(np.abs((y_train - model.predict(X_train).flatten()) / y_train))
mse_train = mean_squared_error(y_train, model.predict(X_train).flatten())
rmse_train = np.sqrt(mse_train)

# 计算验证集上的MAE, MAPE, MSE 和 RMSE
mae_validation = mean_absolute_error(y_validation, y_validation_pred)
mape_validation = np.mean(np.abs((y_validation - y_validation_pred) / y_validation))
mse_validation = mean_squared_error(y_validation, y_validation_pred)
rmse_validation = np.sqrt(mse_validation)

print("验证集:", mae_validation, mape_validation, mse_validation, rmse_validation)
print("训练集:", mae_train, mape_train, mse_train, rmse_train)

看结果:

(3)多步滚动预测-vol. 1

import pandas as pd
import numpy as np
from sklearn.metrics import mean_absolute_error, mean_squared_error
import tensorflow as tf
from tensorflow.python.keras.models import Model
from tensorflow.python.keras.layers import Input, MultiHeadAttention, Dense, Dropout, LayerNormalization, Flatten
from tensorflow.python.keras.optimizers import adam_v2

# 读取数据
data = pd.read_csv('data.csv')
data['time'] = pd.to_datetime(data['time'], format='%b-%y')

n = 6
m = 2

# 创建滞后期特征
for i in range(n, 0, -1):
    data[f'lag_{i}'] = data['incidence'].shift(n - i + 1)

data = data.dropna().reset_index(drop=True)

train_data = data[(data['time'] >= '2004-01-01') & (data['time'] <= '2011-12-31')]
validation_data = data[(data['time'] >= '2012-01-01') & (data['time'] <= '2012-12-31')]

# 准备训练数据
X_train = []
y_train = []

for i in range(len(train_data) - n - m + 1):
    X_train.append(train_data.iloc[i+n-1][[f'lag_{j}' for j in range(1, n+1)]].values)
    y_train.append(train_data.iloc[i+n:i+n+m]['incidence'].values)

X_train = np.array(X_train)
y_train = np.array(y_train)
X_train = X_train.astype(np.float32)
y_train = y_train.astype(np.float32)

# 构建Transformer模型
inputs = Input(shape=(n, 1))

x = MultiHeadAttention(num_heads=8, key_dim=64)(inputs, inputs)
x = Dropout(0.1)(x)
x = LayerNormalization(epsilon=1e-6)(x + inputs)

x = Flatten()(x) # 新增的Flatten层
x = Dense(50, activation='relu')(x)
x = Dropout(0.1)(x)
outputs = Dense(m)(x)

model = Model(inputs=inputs, outputs=outputs)

model.compile(optimizer=adam_v2.Adam(learning_rate=0.001), loss='mse')

# 训练模型
model.fit(X_train, y_train, epochs=200, batch_size=32, verbose=0)

def transformer_rolling_forecast(data, model, n, m):
    y_pred = []

    for i in range(len(data) - n):
        input_data = data.iloc[i+n-1][[f'lag_{j}' for j in range(1, n+1)]].values.astype(np.float32).reshape(1, n, 1)
        pred = model.predict(input_data)
        y_pred.extend(pred[0])

    for i in range(1, m):
        for j in range(len(y_pred) - i):
            y_pred[j+i] = (y_pred[j+i] + y_pred[j]) / 2

    return np.array(y_pred)

# Predict for train_data and validation_data
y_train_pred_transformer = transformer_rolling_forecast(train_data, model, n, m)[:len(y_train)]
y_validation_pred_transformer = transformer_rolling_forecast(validation_data, model, n, m)[:len(validation_data) - n]

# Calculate performance metrics for train_data
mae_train = mean_absolute_error(train_data['incidence'].values[n:len(y_train_pred_transformer)+n], y_train_pred_transformer)
mape_train = np.mean(np.abs((train_data['incidence'].values[n:len(y_train_pred_transformer)+n] - y_train_pred_transformer) / train_data['incidence'].values[n:len(y_train_pred_transformer)+n]))
mse_train = mean_squared_error(train_data['incidence'].values[n:len(y_train_pred_transformer)+n], y_train_pred_transformer)
rmse_train = np.sqrt(mse_train)

# Calculate performance metrics for validation_data
mae_validation = mean_absolute_error(validation_data['incidence'].values[n:len(y_validation_pred_transformer)+n], y_validation_pred_transformer)
mape_validation = np.mean(np.abs((validation_data['incidence'].values[n:len(y_validation_pred_transformer)+n] - y_validation_pred_transformer) / validation_data['incidence'].values[n:len(y_validation_pred_transformer)+n]))
mse_validation = mean_squared_error(validation_data['incidence'].values[n:len(y_validation_pred_transformer)+n], y_validation_pred_transformer)
rmse_validation = np.sqrt(mse_validation)

print("训练集:", mae_train, mape_train, mse_train, rmse_train)
print("验证集:", mae_validation, mape_validation, mse_validation, rmse_validation)

结果:

(4)多步滚动预测-vol. 2

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_absolute_error, mean_squared_error
from tensorflow.python.keras.models import Sequential, Model
from tensorflow.python.keras.layers import Dense, Conv1D, Flatten, MaxPooling1D, Input, MultiHeadAttention, LayerNormalization, Dropout
from tensorflow.python.keras.optimizers import adam_v2

# Loading and preprocessing the data
data = pd.read_csv('data.csv')
data['time'] = pd.to_datetime(data['time'], format='%b-%y')

n = 6
m = 2

# 创建滞后期特征
for i in range(n, 0, -1):
    data[f'lag_{i}'] = data['incidence'].shift(n - i + 1)

data = data.dropna().reset_index(drop=True)

train_data = data[(data['time'] >= '2004-01-01') & (data['time'] <= '2011-12-31')]
validation_data = data[(data['time'] >= '2012-01-01') & (data['time'] <= '2012-12-31')]

# 只对X_train、y_train、X_validation取奇数行
X_train = train_data[[f'lag_{i}' for i in range(1, n+1)]].iloc[::2].reset_index(drop=True).values
X_train = X_train.reshape(X_train.shape[0], X_train.shape[1], 1)

y_train_list = [train_data['incidence'].shift(-i) for i in range(m)]
y_train = pd.concat(y_train_list, axis=1)
y_train.columns = [f'target_{i+1}' for i in range(m)]
y_train = y_train.iloc[::2].reset_index(drop=True).dropna().values[:, 0]

X_validation = validation_data[[f'lag_{i}' for i in range(1, n+1)]].iloc[::2].reset_index(drop=True).values
X_validation = X_validation.reshape(X_validation.shape[0], X_validation.shape[1], 1)

y_validation = validation_data['incidence'].values

# Building the Transformer model
inputs = Input(shape=(n, 1))
x = MultiHeadAttention(num_heads=8, key_dim=64)(inputs, inputs)
x = Dropout(0.1)(x)
x = LayerNormalization(epsilon=1e-6)(x + inputs)
x = Flatten()(x)
x = Dense(50, activation='relu')(x)
outputs = Dense(1)(x)

model = Model(inputs=inputs, outputs=outputs)
optimizer = adam_v2.Adam(learning_rate=0.001)
model.compile(optimizer=optimizer, loss='mse')

# Train the model
model.fit(X_train, y_train, epochs=200, batch_size=32, verbose=0)

# Predict on validation set
y_validation_pred = model.predict(X_validation).flatten()

# Compute metrics for validation set
mae_validation = mean_absolute_error(y_validation[:len(y_validation_pred)], y_validation_pred)
mape_validation = np.mean(np.abs((y_validation[:len(y_validation_pred)] - y_validation_pred) / y_validation[:len(y_validation_pred)]))
mse_validation = mean_squared_error(y_validation[:len(y_validation_pred)], y_validation_pred)
rmse_validation = np.sqrt(mse_validation)

# Predict on training set
y_train_pred = model.predict(X_train).flatten()

# Compute metrics for training set
mae_train = mean_absolute_error(y_train, y_train_pred)
mape_train = np.mean(np.abs((y_train - y_train_pred) / y_train))
mse_train = mean_squared_error(y_train, y_train_pred)
rmse_train = np.sqrt(mse_train)

print("验证集:", mae_validation, mape_validation, mse_validation, rmse_validation)
print("训练集:", mae_train, mape_train, mse_train, rmse_train)

结果:

(5)多步滚动预测-vol. 3

import pandas as pd
import numpy as np
from sklearn.metrics import mean_absolute_error, mean_squared_error
from tensorflow.python.keras.models import Sequential, Model
from tensorflow.python.keras.layers import Dense, Flatten, Input, MultiHeadAttention, LayerNormalization, Dropout
from tensorflow.python.keras.optimizers import adam_v2

# 数据读取和预处理
data = pd.read_csv('data.csv')
data_y = pd.read_csv('data.csv')
data['time'] = pd.to_datetime(data['time'], format='%b-%y')
data_y['time'] = pd.to_datetime(data_y['time'], format='%b-%y')

n = 6

for i in range(n, 0, -1):
    data[f'lag_{i}'] = data['incidence'].shift(n - i + 1)

data = data.dropna().reset_index(drop=True)
train_data = data[(data['time'] >= '2004-01-01') & (data['time'] <= '2011-12-31')]
X_train = train_data[[f'lag_{i}' for i in range(1, n+1)]]
m = 3

X_train_list = []
y_train_list = []

for i in range(m):
    X_temp = X_train
    y_temp = data_y['incidence'].iloc[n + i:len(data_y) - m + 1 + i]
    
    X_train_list.append(X_temp)
    y_train_list.append(y_temp)

for i in range(m):
    X_train_list[i] = X_train_list[i].iloc[:-(m-1)].values
    X_train_list[i] = X_train_list[i].reshape(X_train_list[i].shape[0], X_train_list[i].shape[1], 1)
    y_train_list[i] = y_train_list[i].iloc[:len(X_train_list[i])].values

# 模型训练
models = []
for i in range(m):
    # Building the Transformer model
    inputs = Input(shape=(n, 1))
    x = MultiHeadAttention(num_heads=8, key_dim=64)(inputs, inputs)
    x = Dropout(0.1)(x)
    x = LayerNormalization(epsilon=1e-6)(x + inputs)
    x = Flatten()(x)
    x = Dense(50, activation='relu')(x)
    outputs = Dense(1)(x)

    model = Model(inputs=inputs, outputs=outputs)
    optimizer = adam_v2.Adam(learning_rate=0.001)
    model.compile(optimizer=optimizer, loss='mse')
    model.fit(X_train_list[i], y_train_list[i], epochs=200, batch_size=32, verbose=0)
    models.append(model)

validation_start_time = train_data['time'].iloc[-1] + pd.DateOffset(months=1)
validation_data = data[data['time'] >= validation_start_time]
X_validation = validation_data[[f'lag_{i}' for i in range(1, n+1)]].values
X_validation = X_validation.reshape(X_validation.shape[0], X_validation.shape[1], 1)

y_validation_pred_list = [model.predict(X_validation) for model in models]
y_train_pred_list = [model.predict(X_train_list[i]) for i, model in enumerate(models)]

def concatenate_predictions(pred_list):
    concatenated = []
    for j in range(len(pred_list[0])):
        for i in range(m):
            concatenated.append(pred_list[i][j])
    return concatenated

y_validation_pred = np.array(concatenate_predictions(y_validation_pred_list))[:len(validation_data['incidence'])]
y_train_pred = np.array(concatenate_predictions(y_train_pred_list))[:len(train_data['incidence']) - m + 1]
y_validation_pred = y_validation_pred.flatten()
y_train_pred = y_train_pred.flatten()

mae_validation = mean_absolute_error(validation_data['incidence'], y_validation_pred)
mape_validation = np.mean(np.abs((validation_data['incidence'] - y_validation_pred) / validation_data['incidence']))
mse_validation = mean_squared_error(validation_data['incidence'], y_validation_pred)
rmse_validation = np.sqrt(mse_validation)

mae_train = mean_absolute_error(train_data['incidence'][:-(m-1)], y_train_pred)
mape_train = np.mean(np.abs((train_data['incidence'][:-(m-1)] - y_train_pred) / train_data['incidence'][:-(m-1)]))
mse_train = mean_squared_error(train_data['incidence'][:-(m-1)], y_train_pred)
rmse_train = np.sqrt(mse_train)

print("验证集:", mae_validation, mape_validation, mse_validation, rmse_validation)
print("训练集:", mae_train, mape_train, mse_train, rmse_train)

结果:

三、数据

链接:https://pan.baidu.com/s/1EFaWfHoG14h15KCEhn1STg?pwd=q41n

提取码:q41n

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

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

相关文章

Casdoor系统static任意文件读取漏洞

文章目录 Casdoor系统static任意文件读取漏洞复现0x01 前言0x02 漏洞描述0x03 影响平台0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 Casdoor系统static任意文件读取漏洞复现 0x01 前言 免责声明&#xff1a;请勿利用文章内的相关技术从事非法测试&#xff0c;由…

郁金香2021年游戏辅助技术中级班(七)

郁金香2021年游戏辅助技术中级班&#xff08;七&#xff09; 058-C,C写代码HOOK分析封包数据格式A059-C,C写代码HOOK分析封包数据格式B-detours劫持060-C,C写代码HOOK分析封包数据格式C-过滤和格式化061-C,C写代码HOOK分析封包数据格式D-写入配置文件062-C,C写代码HOOK分析封包…

容器运行elasticsearch安装ik分词非root权限安装报错问题

有些应用默认不允许root用户运行&#xff0c;来确保应用的安全性&#xff0c;这也会导致我们使用docker run后一些操作问题&#xff0c;用es安装ik分词器举例&#xff08;es版本8.9.0&#xff0c;analysis-ik版本8.9.0&#xff09; 1. 容器启动elasticsearch 如挂载方式&…

第二证券:A股“业绩底”已现?两大板块被看好

9月&#xff0c;A股商场经历了一段明显的缩量下跌&#xff0c;成交量持续萎缩&#xff0c;增量资金不足&#xff0c;商场“痛感”激烈。跟着国庆十一长假结束&#xff0c;2023年四季度正式敞开&#xff0c;大都分析人士和私募安排都认为&#xff0c;国内经济预期转好将为A股商场…

蓝桥杯每日一题2023.10.7

跑步锻炼 - 蓝桥云课 (lanqiao.cn) 题目描述 题目分析 简单枚举&#xff0c;对于2的情况特判即可 #include<bits/stdc.h> using namespace std; int num, ans, flag; int m[13] {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; bool is_ren(int n) {if((n %…

3d渲染农场全面升级,好用的渲染平台值得了解

什么是渲染农场&#xff1f; 渲染农场是专门从事 3D 渲染的大型机器集合&#xff0c;称为渲染节点&#xff0c;这些机器组合在一起执行一项任务&#xff08;渲染 3D 帧和动画&#xff09;。通过将渲染工作分配给数百台机器&#xff0c;可以显着减少渲染时间&#xff0c;从而使…

STM32F030在使用内部参考电压 (VREFINT)时与STM32G070的区别

背景&#xff1a; 之前使用过STM32G070的内部参考电压来提升ADC采集的准确度&#xff08;STM32使用内部参考电压提高ADC采集准确度&#xff09;&#xff0c;所以本次使用STM32F030的芯片时直接把之前G070的代码拿过来用了&#xff0c;但是出现了问题。 查找资料发现两者不同&am…

go语言判断管道是否关闭的误区

前言 本文是探讨的是"在Go语言中&#xff0c;我们是否可以使用读取管道时的第二个返回值来判断管道是否关闭?" 样例 在Go语言中&#xff0c;我们是否可以使用读取管道时的第二个返回值来判断管道是否关闭? 可以看下面的代码 package mainimport "fmt"…

步进电机S曲线驱动模块

一、电路 带有CAN及485接收&#xff0c;三个光耦接口&#xff0c;TMC2660电机驱动芯片&#xff0c;stm32f103的主控芯片 二、协议 一般来说&#xff0c;板子之间的通信协议格式通常为&#xff1a; 内容 帧头 长度 类型1 类型2 Data 校验 帧尾 字节数 1 1 1 1 N 2 1 帧头为0xB…

二叉树--二叉树最大深度

文章前言&#xff1a;如果有小白同学还是对于二叉树不太清楚&#xff0c;作者推荐&#xff1a;二叉树的初步认识_加瓦不加班的博客-CSDN博客 二叉树最大深度-力扣 104 题 &#xff08;不知道“后序遍历”的小白同学&#xff0c;请先看&#xff1a;二叉树的初步认识_加瓦不加班…

组件的挂载和渲染

React的挂载和渲染 React的生命周期中包括三个主要的阶段&#xff1a;挂载、渲染以及卸载。 很多小伙伴包括我自己可能对挂载和渲染的概念比较模糊&#xff0c;今天这篇文章主要的目的是为了解答我们的这个小疑惑~ 这张图是从其他地方搬运过来的&#xff0c;这张图中描述的主…

直播间自动点赞第一章:MouseEvent 实现根据坐标X,Y自动点击浏览器的效果

最终项目 制作一个自动点赞的浏览器插件&#xff0c;可以根据用户指定一个浏览器区域&#xff0c;进行自动化点击&#xff0c;其中可以设置参数&#xff1a;点击频率、指定区域。 本章节效果 指定了一块区域&#xff0c;进行点击&#xff0c;这边是模拟直播间实现自动化点击 …

【Java 进阶篇】JDBC数据库连接池Druid工具类详解

在Java应用程序中&#xff0c;数据库连接是一种重要的资源&#xff0c;因为每次创建和销毁数据库连接都会产生开销&#xff0c;降低了系统性能。为了高效地管理数据库连接&#xff0c;降低资源消耗&#xff0c;常常使用数据库连接池。Druid是一个功能强大的数据库连接池&#x…

成品短视频App源码:10个最热门的功能模块详解

作为成品短视频App源码领域的专家&#xff0c;我将为您揭开成品短视频App的神秘面纱。在这篇文章中&#xff0c;我将详细介绍这热门应用背后的10个最受欢迎的功能模块。无论您是想开发一款创新的短视频App&#xff0c;还是寻找适合您业务的现成解决方案&#xff0c;本文都会为您…

递归

欢迎来到Cefler的博客&#x1f601; &#x1f54c;博客主页&#xff1a;那个传说中的man的主页 &#x1f3e0;个人专栏&#xff1a;题目解析 &#x1f30e;推荐文章&#xff1a;题目大解析&#xff08;3&#xff09; 目录 &#x1f449;&#x1f3fb;汉诺塔 &#x1f449;&…

C#Winform新建工程

C#Winform新建工程 选择创建新项目 搜索窗体 填写工程名称和位置

第四课 递归、分治

文章目录 第四课 递归、分治lc78.子集--中等题目描述代码展示 lc77.组合--中等题目描述代码展示 lc46.全排列--中等题目描述代码展示 lc47.全排列II--中等题目描述代码展示 lc226.翻转二叉树--简单题目描述代码展示 lc98.验证二叉搜索树--中等题目描述代码展示 lc104.二叉树的最…

八、Thymeleaf链接表达式

链接表达式使用&#xff20;符开头&#xff0c;用于描述一个URL&#xff0c;url可以是相对的&#xff0c;也可以是绝对的。当为相对路径时&#xff0c;此表达式用于在指定的URI前拼接项目的根路径&#xff0c;相当于request.getContextPath()。当为绝对路径时&#xff0c;路径按…

纳百川冲刺创业板上市:计划募资约8亿元,宁德时代为主要合作方

近日&#xff0c;纳百川新能源股份有限公司&#xff08;下称“纳百川”&#xff09;向深交所创业板递交的上市申请材料获得受理&#xff0c;浙商证券为其独家保荐人。 本次冲刺上市&#xff0c;纳百川计划募资8.29亿元&#xff0c;将用于纳百川&#xff08;滁州&#xff09;新能…

【力扣-每日一题】901. 股票价格跨度

暴力解法&#xff1a; class StockSpanner { private:vector<int> pri; public:StockSpanner() {}int next(int price) {pri.emplace_back(price);int count0;for(int ipri.size()-1;i>0;i--){if(pri[i]<price)count;else break;}return count;} };/*** Your Stoc…