news 2026/9/30 5:18:17

无蜂窝大规模MIMO与无人机通信:DQN资源调度实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
无蜂窝大规模MIMO与无人机通信:DQN资源调度实战

简介:这份文档面向无线通信、6G与无人机网络方向的研究生及科研人员,聚焦无蜂窝大规模MIMO场景下偏远地区覆盖不足的问题,系统讲解如何用深度强化学习完成无人机辅助通信与资源调度。内容围绕两跳协作机制展开:第1跳将AP功率分配与无人机服务区选择建模为双动作马尔可夫决策过程,采用基于CNN的DQN求解;第2跳将用户调度转化为0-1优化问题并分解求解。文中还涉及有限状态马尔可夫信道、DDPG三维轨迹与频带分配、多智能体强化学习动态资源分配等知识点,并给出可达速率与总吞吐量的优化思路。资源包为1个docx文档,约409KB,结构完整、公式与系统模型清晰,适合作为论文写作、算法复现与课题选题的参考材料。目前已有226人学习下载。

1. 无蜂窝大规模MIMO遇上无人机:为什么单靠传统优化解不动了

地面基站被高楼遮挡、热点区域容量告急、应急场景下临时通信需求暴涨——这些场景下,把无人机当成空中基站来辅助通信,已经是业界比较认可的思路。但真正动手做的人很快会发现一个问题:当无人机在空中移动、地面又是无蜂窝大规模MIMO(Cell-Free Massive MIMO)架构时,资源调度这件事变得极其难解。无蜂窝架构的特点是大量接入点(AP)通过回传链路连到中央处理单元,共同服务少量用户,用户不再绑定某个“小区”,干扰结构跟传统蜂窝完全不同。再叠加无人机的三维移动,信道随时间快速变化,优化变量包括无人机轨迹、功率分配、AP选择、波束成形等,维度高、耦合强、非凸,传统凸优化或启发式方法要么假设太强,要么求解时间根本跟不上信道变化。

深度强化学习(DRL)在这里的价值,是把序贯决策问题建模成马尔可夫决策过程,让智能体在与环境交互中学习调度策略,而不依赖精确的凸模型。DQN作为其中最早成熟的一类算法,适合动作空间离散的场景,比如“选哪个AP”“用哪个功率档位”“往哪个方向飞”。这篇笔记就围绕这个标题,把无蜂窝大规模MIMO下无人机辅助通信与资源调度的完整落地路径拆开:先讲清楚问题建模和选型理由,再给可复现的仿真环境和DQN实现,最后把踩过的坑和调参经验摊开。适合已经了解强化学习基础、想把这个方向做成论文或原型系统的读者。

2. 把通信调度写成MDP:状态、动作、奖励怎么定才不翻车

2.1 无蜂窝大规模MIMO的信道模型与速率计算

动手写代码前,必须先把速率公式落到可计算的表达式。无蜂窝架构下,所有AP通过回传连接到CPU,用户k的下行可达速率通常写成:

R_k = B * log2(1 + SINR_k)

其中SINR_k由有用信号功率除以干扰加噪声得到。在无蜂窝大规模MIMO中,常用做法是采用最大比合并(MRC)或最小均方误差(MMSE)接收,AP与用户之间的信道包含大尺度衰落和小尺度衰落。大尺度衰落用三段式路径损耗模型,小尺度用瑞利或莱斯分布。无人机在空中时,还要区分视距(LoS)和非视距(NLoS)概率,通常用仰角相关的概率模型:

P_LoS = 1 / (1 + a * exp(-b * (theta - a)))

theta是无人机到用户的仰角。这个概率直接影响路径损耗,进而影响SINR。很多论文在这里偷懒,直接假设全LoS,结果仿真出来的调度策略在实际场景中根本不能用。我一般会在仿真里显式实现LoS/NLoS概率加权,虽然计算量增加,但策略的鲁棒性会好很多。

下面是一个简化的信道增益计算代码,用于后续DQN环境:

import numpy as np def channel_gain(ap_pos, uav_pos, user_pos, fc=2e9, bw=20e6): """ 计算AP-用户和UAV-用户链路的信道增益 ap_pos: (num_ap, 3) uav_pos: (3,) user_pos: (num_user, 3) fc: 载波频率 bw: 带宽 返回: 信道增益矩阵 (num_ap+1, num_user) """ c = 3e8 lambda_ = c / fc num_ap = ap_pos.shape[0] num_user = user_pos.shape[0] # AP到用户的距离和仰角 d_au = np.linalg.norm(ap_pos[:, None, :] - user_pos[None, :, :], axis=2) # 无人机到用户的距离和仰角 d_uu = np.linalg.norm(uav_pos[None, :] - user_pos, axis=1) h_uav = uav_pos[2] theta = np.degrees(np.arcsin(h_uav / np.maximum(d_uu, 1e-3))) # LoS概率 a, b = 9.61, 0.16 p_los = 1 / (1 + a * np.exp(-b * (theta - a))) # 路径损耗 (简化三段式) def pathloss(d, p_los_val): pl_los = 20 * np.log10(4 * np.pi * fc / c) + 20 * np.log10(np.maximum(d, 1)) pl_nlos = pl_los + 20 # NLoS额外损耗 return p_los_val * pl_los + (1 - p_los_val) * pl_nlos pl_au = pathloss(d_au, 1.0) # AP通常有固定LoS条件,简化处理 pl_uu = pathloss(d_uu, p_los) # 小尺度衰落 (瑞利) small_scale_au = (np.random.randn(num_ap, num_user) + 1j*np.random.randn(num_ap, num_user)) / np.sqrt(2) small_scale_uu = (np.random.randn(num_user) + 1j*np.random.randn(num_user)) / np.sqrt(2) # 信道增益 (含天线增益简化) gain_au = np.abs(small_scale_au)**2 * 10**(-pl_au/10) gain_uu = np.abs(small_scale_uu)**2 * 10**(-pl_uu/10) return np.vstack([gain_au, gain_uu[None, :]])

这段代码里,p_los用仰角计算,pathloss函数把LoS和NLoS按概率加权。参数a=9.61, b=0.16来自常见的城市环境实测拟合,不同场景要调整。fc=2e9是载波频率,bw=20e6是带宽。实际写环境时,这个函数每个时隙调用一次,返回的信道增益用于计算SINR和速率。

2.2 状态空间设计:别把原始信道直接塞进DQN

DQN的输入维度直接决定训练难度。最朴素的做法是把所有AP到所有用户的信道增益拉平成一个向量作为状态,但无蜂窝大规模MIMO的AP数量通常几十甚至上百,用户数几十,状态维度轻松上千,DQN根本训不动。我一般会做特征压缩,状态里只保留:

  • 每个用户当前的平均SINR(num_user维)
  • 无人机当前位置和速度(6维)
  • 每个AP的剩余回传容量(num_ap维,可归一化)
  • 上一时隙各用户的速率(num_user维)

这样状态维度控制在几十到一百左右。如果AP数量特别大,还可以用AP分簇后的簇头信息代替全部AP。注意,状态里不要放原始复数信道,DQN处理复数需要拆成实部虚部,维度翻倍且信息冗余。用速率、SINR这类标量特征更稳。

2.3 动作空间与奖励函数:离散化是DQN的前提

DQN只能处理离散动作,所以必须把连续变量离散化。常见的动作设计有两种:

第一种是联合动作:无人机移动方向(比如8个方向)+ 功率档位(比如3档)+ AP选择(比如从K个簇里选1个)。动作总数8×3×K,K=4时是96个动作,DQN还能接受。

第二种是分解动作:用多个DQN分别输出移动、功率、AP选择,但这样会破坏动作之间的关联性,收敛更慢。我建议新手先用联合动作,动作数控制在200以内。

奖励函数直接决定策略学出来有没有用。最直接的是用系统和速率:

reward = sum(R_k) - penalty

penalty包括:无人机飞出边界、碰撞、功率超限、用户速率低于门限的惩罚。注意奖励要归一化,否则DQN的Q值会爆炸。我一般把速率除以一个参考速率(比如100Mbps),让奖励在0到1之间。

def compute_reward(rate, uav_pos, power, user_rates, min_rate=1e6): """ rate: 各用户速率 (num_user,) uav_pos: 无人机位置 power: 发射功率 user_rates: 历史速率用于公平性 """ sum_rate = np.sum(rate) / 1e8 # 归一化 # 公平性惩罚 fairness_penalty = np.std(rate) / (np.mean(rate) + 1e-6) * 0.1 # 边界惩罚 boundary_penalty = 0 if uav_pos[0] < 0 or uav_pos[0] > 1000 or uav_pos[1] < 0 or uav_pos[1] > 1000: boundary_penalty = 1.0 # 低速率惩罚 low_rate_penalty = np.sum(rate < min_rate) * 0.5 # 功率惩罚 power_penalty = 0.01 * power / 10 # 假设最大10W reward = sum_rate - fairness_penalty - boundary_penalty - low_rate_penalty - power_penalty return reward

奖励里的fairness_penalty用速率标准差除以均值,鼓励调度器不要只服务信道好的用户。boundary_penalty防止无人机飞出区域。low_rate_penalty对低于门限的用户施加惩罚。这些系数需要根据仿真结果微调,没有万能值。

3. 用DQN跑通训练:从环境封装到收敛判断

3.1 仿真环境搭建:Gym接口与无蜂窝速率计算

为了让DQN代码能直接复用,建议把环境封装成Gym风格,实现reset()和step(action)。下面是一个最小可用的环境骨架:

import gym from gym import spaces import numpy as np class CellFreeUAVEnv(gym.Env): def __init__(self, num_ap=16, num_user=8, area=1000): super().__init__() self.num_ap = num_ap self.num_user = num_user self.area = area # 动作: 8方向 + 3功率档 + 4个AP簇 = 96 self.action_space = spaces.Discrete(8 * 3 * 4) # 状态: 用户SINR(8) + 无人机位置速度(6) + AP容量(16) + 上一时隙速率(8) self.obs_dim = num_user + 6 + num_ap + num_user self.observation_space = spaces.Box(low=-np.inf, high=np.inf, shape=(self.obs_dim,), dtype=np.float32) self.ap_pos = np.random.rand(num_ap, 3) * area self.ap_pos[:, 2] = 30 # AP高度30m self.user_pos = np.random.rand(num_user, 3) * area self.user_pos[:, 2] = 1.7 self.uav_pos = np.array([area/2, area/2, 100.0]) self.uav_vel = np.zeros(3) self.prev_rate = np.zeros(num_user) self.step_count = 0 def reset(self): self.uav_pos = np.array([self.area/2, self.area/2, 100.0]) self.uav_vel = np.zeros(3) self.prev_rate = np.zeros(self.num_user) self.step_count = 0 return self._get_obs() def _get_obs(self): # 简化: 用距离反比近似SINR d_uu = np.linalg.norm(self.uav_pos[None, :] - self.user_pos, axis=1) sinr_approx = 1e6 / (d_uu**2 + 1e-6) sinr_approx = sinr_approx / (np.max(sinr_approx) + 1e-6) ap_cap = np.ones(self.num_ap) * 0.8 # 简化固定值 obs = np.concatenate([sinr_approx, self.uav_pos, self.uav_vel, ap_cap, self.prev_rate]) return obs.astype(np.float32) def step(self, action): # 解析动作 move_idx = action // 12 power_idx = (action % 12) // 4 ap_cluster = action % 4 # 移动 angle = move_idx * np.pi / 4 speed = 20.0 # m/s self.uav_vel = np.array([speed * np.cos(angle), speed * np.sin(angle), 0]) self.uav_pos += self.uav_vel * 1.0 # 1秒时隙 # 功率档位 power = [0.1, 1.0, 5.0][power_idx] # 计算速率 (简化) d_uu = np.linalg.norm(self.uav_pos[None, :] - self.user_pos, axis=1) rate = 20e6 * np.log2(1 + power * 1e6 / (d_uu**2 + 1e-6)) rate = np.clip(rate, 0, 1e8) reward = compute_reward(rate, self.uav_pos, power, self.prev_rate) self.prev_rate = rate / 1e8 self.step_count += 1 done = self.step_count >= 200 return self._get_obs(), reward, done, {}

这个环境里,_get_obs用距离反比近似SINR,实际项目中应该替换成2.1节的完整信道计算。step里动作解析成移动方向、功率、AP簇,速率计算也是简化版。重点是接口结构:状态是固定长度向量,动作是离散整数,奖励是标量。DQN代码可以不改动直接对接。

3.2 DQN网络结构与关键超参数

DQN的核心是用神经网络近似Q值函数。对于这个场景,输入维度约38,输出维度96,两层隐藏层各256个神经元就够了。下面是用PyTorch实现的DQN:

import torch import torch.nn as nn import torch.optim as optim import random from collections import deque class QNetwork(nn.Module): def __init__(self, obs_dim, action_dim, hidden=256): super().__init__() self.net = nn.Sequential( nn.Linear(obs_dim, hidden), nn.ReLU(), nn.Linear(hidden, hidden), nn.ReLU(), nn.Linear(hidden, action_dim) ) def forward(self, x): return self.net(x) class DQNAgent: def __init__(self, obs_dim, action_dim, lr=1e-3, gamma=0.95, epsilon_start=1.0, epsilon_end=0.05, epsilon_decay=5000, buffer_size=100000, batch_size=64, target_update=200): self.action_dim = action_dim self.gamma = gamma self.epsilon = epsilon_start self.epsilon_end = epsilon_end self.epsilon_decay = epsilon_decay self.batch_size = batch_size self.target_update = target_update self.step_count = 0 self.q_net = QNetwork(obs_dim, action_dim) self.target_net = QNetwork(obs_dim, action_dim) self.target_net.load_state_dict(self.q_net.state_dict()) self.optimizer = optim.Adam(self.q_net.parameters(), lr=lr) self.buffer = deque(maxlen=buffer_size) def select_action(self, obs): self.epsilon = self.epsilon_end + (1.0 - self.epsilon_end) * \ np.exp(-self.step_count / self.epsilon_decay) self.step_count += 1 if random.random() < self.epsilon: return random.randrange(self.action_dim) with torch.no_grad(): obs_t = torch.FloatTensor(obs).unsqueeze(0) q_values = self.q_net(obs_t) return q_values.argmax().item() def store(self, obs, action, reward, next_obs, done): self.buffer.append((obs, action, reward, next_obs, done)) def train(self): if len(self.buffer) < self.batch_size: return batch = random.sample(self.buffer, self.batch_size) obs, actions, rewards, next_obs, dones = zip(*batch) obs = torch.FloatTensor(np.array(obs)) actions = torch.LongTensor(actions).unsqueeze(1) rewards = torch.FloatTensor(rewards).unsqueeze(1) next_obs = torch.FloatTensor(np.array(next_obs)) dones = torch.FloatTensor(dones).unsqueeze(1) q_values = self.q_net(obs).gather(1, actions) with torch.no_grad(): next_q = self.target_net(next_obs).max(1, keepdim=True)[0] target = rewards + self.gamma * next_q * (1 - dones) loss = nn.MSELoss()(q_values, target) self.optimizer.zero_grad() loss.backward() # 梯度裁剪,防止Q值爆炸 nn.utils.clip_grad_norm_(self.q_net.parameters(), 10.0) self.optimizer.step() if self.step_count % self.target_update == 0: self.target_net.load_state_dict(self.q_net.state_dict())

关键参数说明:gamma=0.95是折扣因子,通信调度场景下不宜太高,否则智能体会过度关注远期速率而忽略当前约束。epsilon_decay=5000控制探索衰减速度,太小会导致探索不足,太大会收敛慢。target_update=200是目标网络更新频率,太小训练不稳定,太大收敛慢。buffer_size=100000经验回放池,太小会遗忘早期经验,太大则训练慢。梯度裁剪clip_grad_norm_是必须的,DQN在奖励尺度没调好时Q值容易爆炸。

3.3 训练循环与收敛判断:看什么曲线

训练循环把环境和智能体串起来:

env = CellFreeUAVEnv() agent = DQNAgent(env.obs_dim, env.action_space.n) episode_rewards = [] for episode in range(2000): obs = env.reset() total_reward = 0 done = False while not done: action = agent.select_action(obs) next_obs, reward, done, _ = env.step(action) agent.store(obs, action, reward, next_obs, done) agent.train() obs = next_obs total_reward += reward episode_rewards.append(total_reward) if episode % 50 == 0: avg = np.mean(episode_rewards[-50:]) print(f"Episode {episode}, Avg Reward: {avg:.4f}, Epsilon: {agent.epsilon:.3f}")

判断收敛不要只看奖励曲线。我一般同时看三个指标:每50回合平均奖励是否稳定上升并趋于平台;epsilon是否降到0.1以下;Q值均值是否在合理范围(比如0到10之间)。如果奖励震荡剧烈,先检查奖励归一化;如果Q值持续增大,检查gamma和奖励尺度;如果策略始终不移动无人机,检查动作空间里移动动作的奖励差异是否被其他惩罚淹没。

4. 避坑与排查:训练不收敛、策略学废的5个血泪教训

4.1 现象:奖励曲线剧烈震荡,Q值爆炸

原因:奖励没有归一化,速率量级在1e8,DQN的Q值直接冲到1e10以上,梯度爆炸。解决:奖励必须除以参考值,让单步奖励在0到1之间。同时加梯度裁剪,clip_grad_norm_设为10。如果还震荡,把学习率从1e-3降到1e-4。

4.2 现象:无人机原地不动或反复撞边界

原因:移动动作的奖励差异太小,被边界惩罚或功率惩罚淹没。解决:检查奖励函数里各项系数的量级。边界惩罚设为1.0,而速率归一化后可能只有0.5,智能体宁愿不动也不冒险。我一般把边界惩罚降到0.3,同时给移动动作加一个小的探索奖励,鼓励智能体尝试不同方向。

4.3 现象:训练初期奖励上升,后期突然崩掉

原因:经验回放池里早期低质量经验太多,或者目标网络更新频率太低导致Q值过估计。解决:把target_update从200降到100,或者用Double DQN。Double DQN的改动很小,把目标Q值计算改成用当前网络选动作、目标网络算值:

with torch.no_grad(): next_actions = self.q_net(next_obs).argmax(1, keepdim=True) next_q = self.target_net(next_obs).gather(1, next_actions) target = rewards + self.gamma * next_q * (1 - dones)

这个改动几乎不增加计算量,但能明显缓解Q值过估计。

4.4 现象:策略只服务信道最好的用户,其他用户速率极低

原因:奖励函数只用了和速率,没有公平性约束。解决:在奖励里加公平性惩罚,用速率标准差除以均值,系数从0.1开始调。如果公平性还是差,改用比例公平奖励:sum(log(rate)),这个函数天然鼓励公平。

4.5 现象:仿真里表现很好,换一组用户位置就废了

原因:状态里没有包含用户位置信息,或者训练时用户位置固定。解决:每次reset()时随机化用户位置,状态里加入用户相对无人机的方位角或距离。如果状态维度不允许,至少加入用户距离的统计量(均值、方差)。另外,训练时要用多个随机种子,确保策略泛化。

5. 进阶技巧:用优先经验回放和动作掩码把收敛速度提上去

5.1 优先经验回放:让DQN多学“难样本”

普通经验回放均匀采样,但通信调度里有些状态(比如用户速率骤降、无人机接近边界)的样本更有学习价值。优先经验回放(PER)按TD误差给样本加权,TD误差大的样本被采样概率高。实现上,把deque换成带优先级的缓冲区,采样时按概率抽。核心代码:

class PrioritizedBuffer: def __init__(self, capacity, alpha=0.6): self.capacity = capacity self.alpha = alpha self.buffer = [] self.priorities = np.zeros(capacity, dtype=np.float32) self.pos = 0 def store(self, transition, td_error): max_priority = self.priorities.max() if self.buffer else 1.0 if len(self.buffer) < self.capacity: self.buffer.append(transition) else: self.buffer[self.pos] = transition self.priorities[self.pos] = max_priority self.pos = (self.pos + 1) % self.capacity def sample(self, batch_size, beta=0.4): if len(self.buffer) == self.capacity: priorities = self.priorities else: priorities = self.priorities[:len(self.buffer)] probs = priorities ** self.alpha probs /= probs.sum() indices = np.random.choice(len(self.buffer), batch_size, p=probs) samples = [self.buffer[i] for i in indices] # 重要性采样权重 total = len(self.buffer) weights = (total * probs[indices]) ** (-beta) weights /= weights.max() return samples, indices, weights

alpha=0.6控制优先级程度,0是均匀采样,1是完全按优先级。beta=0.4到1.0线性增长,用于修正偏差。PER能让收敛速度提升30%到50%,但实现复杂度增加,建议先跑通普通DQN再加。

5.2 动作掩码:把非法动作直接屏蔽

通信调度里有些动作是物理上不可行的,比如无人机已经到边界还往外飞、功率超过硬件上限。与其用惩罚让智能体慢慢学,不如在动作选择时直接屏蔽非法动作。实现上,在select_action里加一个掩码:

def select_action(self, obs, action_mask=None): if random.random() < self.epsilon: if action_mask is not None: valid_actions = np.where(action_mask == 1)[0] return np.random.choice(valid_actions) return random.randrange(self.action_dim) with torch.no_grad(): q_values = self.q_net(torch.FloatTensor(obs).unsqueeze(0)) if action_mask is not None: q_values[0, action_mask == 0] = -1e9 return q_values.argmax().item()

action_mask是一个长度等于动作数的0/1向量,1表示合法。这个技巧在无人机边界控制和功率约束上特别有效,能减少大量无效探索。

5.3 验证方法:用固定测试集对比基线

训练完之后,不要只看训练奖励。我一般会固定10组用户位置和信道实现,分别跑DQN策略、随机策略、贪心策略(选瞬时速率最大的AP和功率),对比平均和速率和公平性。如果DQN比贪心策略只高5%以内,说明策略没学到东西,大概率是状态设计有问题。如果DQN在测试集上波动很大,检查训练时用户位置是否随机化。最后,把训练好的模型在不同用户数(比如8、12、16)下测试,看泛化能力。这些验证做完,才能判断这个方案值不值得继续投入。

我自己的习惯是:每次改奖励函数或状态设计,先跑500回合看趋势,不要一上来就训几千回合。DQN调参是个耐心活,状态和奖励设计对了,收敛是自然而然的事。希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/30 5:17:58

Codex接入Jev模型:从配置到排错的完整实战指南

给Codex配上Jev&#xff0c;这句话最近在编程社区里传得很快。Codex是OpenAI在终端场景里放出的重武器&#xff0c;能自己读代码、跑命令、改文件、盯日志&#xff0c;一条龙把开发任务带走&#xff1b;Jev则是另一种定位的模型服务&#xff0c;主打推理能力和OpenAI兼容接口&a…

作者头像 李华
网站建设 2026/9/30 5:16:49

玩家真机 Profiler 自研指南:从线上掉帧到帧耗时归因的完整实现

做性能优化的朋友应该都有过这种体验&#xff1a;线上玩家反馈“新副本卡成幻灯片”&#xff0c;测试机却完美跑到 60 帧&#xff0c;开发环境里怎么复现都复现不了。我入职做游戏客户端优化时&#xff0c;第一周就撞上这种问题&#xff0c;当时的解决办法很原始&#xff1a;让…

作者头像 李华
网站建设 2026/9/30 5:16:16

轻量级金融K线图实战:lightweight-charts 选型、定制与性能优化

在 Github 上翻项目翻到第 87 期的时候&#xff0c;lightweight-charts 这个仓库让我停下来多看了两眼。原因很直接&#xff1a;我手头正好有一个行情列表页面&#xff0c;需要在一个不到 300px 高的卡片里塞进几万根K线&#xff0c;还得保证手机端滑动不掉帧。ECharts 能画&am…

作者头像 李华
网站建设 2026/9/30 5:16:09

中小型企业DeepSeek业务落地指南:API接入与避坑实践

简介&#xff1a;这份PDF文档面向中小型企业技术负责人、数字化转型决策者以及希望将DeepSeek落地到实际业务中的开发者&#xff0c;系统讲解从技术原理到业务场景适配的完整路径。内容涵盖DeepSeek核心技术架构、数据处理流程、模型训练与评估&#xff0c;并针对客户服务、市场…

作者头像 李华
网站建设 2026/9/30 5:14:55

Windows下C/C++递归栈溢出?四大环境编译期调大栈空间全攻略

不知道你有没有经历过这种邪门时刻&#xff1a;同一个DFS递归算法&#xff0c;在Linux服务器上跑得好好的&#xff0c;拷回Windows本地编译一运行&#xff0c;报错0xC00000FD&#xff0c;直接Stack overflow。我当时在Windows上用CLion刷算法题&#xff0c;一个40000层的深搜&a…

作者头像 李华