DP地狱训练 挤牛奶

这是一个关于动态规划(DP)的编程挑战,题目描述涉及时间限制和内存限制,要求解决者判断特定情况。虽然题目建议使用Pascal,但指出C++同样可以完成,通过memset初始化数组并在中间部分赋值。来源于博客文章《DP地狱训练》。

1257: [DP地狱训练]挤牛奶

时间限制: 1 Sec  内存限制: 64 MB
提交: 917  解决: 260
[提交][状态][讨论版]

题目描述

小卡卡终于帮农夫John找到了走丢的那一头奶牛,John为了感谢小卡卡,不仅告诉了他在 Pascal山脉上可能存在Pascal圣地最大的宝藏,还说要请小卡卡喝牛奶。可是农夫John发现他家里所储藏的牛奶已经喝光了,所以要临时给奶牛挤奶。小卡卡实在是太好心了,说要帮农夫John一起挤牛奶。John答应了,他把他的n头奶牛中的n/2头(n是个偶数)分给小卡卡挤,他自己挤剩下的n/2头奶牛。但是每一头奶牛都有不同的产奶量,农夫John为了让小卡卡减轻负担,他希望他们两个所挤的牛奶的总量之差最小。小卡卡得知了每头奶牛的产奶情况之后很快就解决了这个问题。

输入

测试数据第一行一个整数n,n为偶数且小于100。表示有n头奶牛。 第二行n个整数分别给出每头奶牛的产奶量(产奶量的总和不超过2000)。

输出

输出小卡卡和农夫所挤的牛奶量的最小差值。

样例输入

6
7 9 2 6 4 2

依旧是判定性dp。

(用pascal书写效果更佳,因为数组下标可以为负数。)

(好吧C++也可以,先memset一块内存然后把某个指针赋值到该块内存的中间部分就行。)

 

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <cstdlib>
 6 #include <vector>
 7  
 8 using namespace std;
 9  
10  
11 /*
12   f[i][j][k] : 前i个奶牛中j个分给了A,i - j个分给了B,A的牛奶量减去B的牛奶量的值为k。
13   f[i][j][k] = or { f[i - 1][j - 1][k - w[i]], f[i - 1][j][k + w[i]] }
14   f[0][0][0] = 1
15   f[i][0][-sum w[i]] = 1
16 */
17  
18 #define N 2500
19  
20 #define B (2 * N)
21  
22 int n, w, f[2][150][N * 5], p, sm;
23  
24 int main(){
25     f[0][0][B + 0] = 1;
26     scanf("%d", &n);
27     for(int i = 1 ; i <= n ; i ++){
28         p ^= 1;
29         scanf("%d", &w);
30         sm += w;
31         memset(f[p], 0, sizeof(f[p]));
32         f[p][0][B - sm] = 1;
33         for(int j = 1 ; j <= i ; j ++){
34             for(int k = -N ; k <= N ; k ++){
35                 f[p][j][B + k] = f[!p][j - 1][B + k - w] | f[!p][j][B + k + w];
36             }
37         }
38     }
39     for(int i = 0 ; i <= N ; i ++){
40         if(f[p][n / 2][B + i] | f[p][n / 2][B - i]){
41             printf("%d", i);
42             break;
43         }
44     }
45 }
View Code

 

转载于:https://www.cnblogs.com/KingSann/articles/7307256.html

在深度学习的分布式训练中,DP(Data Parallel)是一种常见的并行策略,尤其适用于单机多GPU场景。然而,在实际使用过程中,可能会出现训练失败的情况。以下是可能导致 DP 训练失败的原因及相应的解决方法。 ### 3.1 常见原因与解决方案 #### 3.1.1 显存不足 **原因分析:** DP 模式下,每个 GPU 都会复制完整的模型副本,并且前向和反向传播是在各个 GPU 上独立进行的。最终梯度会在主 GPU(通常是 GPU0)上汇总并更新参数。这种机制导致每个 GPU 都需要存储完整的模型参数和梯度,因此显存消耗较大。当模型规模较大时,容易出现显存不足的问题 [^1]。 **解决方法:** - 使用更小的 batch size。 - 简化模型结构或使用轻量级模型变体(如 MobileNet、EfficientNet)。 - 转换为 DDP(Distributed Data Parallel)模式,该模式支持模型并行,更适合大模型训练 [^1]。 #### 3.1.2 数据负载不均衡 **原因分析:** 在 DP 中,数据被平均分配到各个 GPU 上进行处理。如果数据分布不均或某些 GPU 的计算能力较弱,可能导致部分 GPU 处理速度慢,形成瓶颈,进而影响整体训练效率甚至失败。 **解决方法:** - 使用 `torch.utils.data.DistributedSampler` 或自定义采样器来确保数据均匀分布。 - 对于异构设备环境,建议优先使用 DDP,它能更好地支持分布式任务调度 [^1]。 #### 3.1.3 参数同步问题 **原因分析:** DP 在反向传播后将各 GPU 的梯度汇总到主 GPU(GPU0),然后进行参数更新,并将更新后的参数广播回其他 GPU。如果在此过程中发生通信错误或超时,可能导致训练中断。 **解决方法:** - 确保 PyTorch 版本稳定,避免已知的同步 bug。 - 启用 NCCL 后端并检查 CUDA 和 cuDNN 的版本兼容性。 - 若频繁出现同步失败,建议切换至 DDP 模式,其通信机制更为健壮 [^1]。 #### 3.1.4 GIL 锁竞争 **原因分析:** DP 是基于多线程实现的,而 Python 的全局解释器锁(GIL)限制了多线程的并行执行能力,可能在大规模并发训练中造成性能瓶颈。 **解决方法:** - 尽量避免使用 DP,转而采用基于多进程的 DDP 模式,可以有效规避 GIL 的限制 [^1]。 #### 3.1.5 初始化失败或通信异常 **原因分析:** 在分布式训练中,若未正确初始化进程组(如未调用 `torch.distributed.init_process_group`)或网络配置不当(如 IP 地址、端口设置错误),会导致训练失败。 **解决方法:** - 确保所有进程都正确初始化,并使用相同的后端(如 `nccl`、`gloo`)。 - 检查主机之间的网络连接是否正常。 - 设置合理的超时时间,例如通过 `init_method` 和 `timeout` 参数控制初始化过程。 --- ### 3.2 示例代码:DP 初始化与训练片段 ```python import torch import torch.nn as nn from torch.utils.data import DataLoader, TensorDataset # 定义一个简单的模型 model = nn.Linear(10, 2) # 使用 DataParallel 包装模型 if torch.cuda.device_count() > 1: print(f"Using {torch.cuda.device_count()} GPUs") model = nn.DataParallel(model) # 移动模型到 GPU device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model.to(device) # 构造示例数据集 dataset = TensorDataset(torch.randn(100, 10), torch.randint(0, 2, (100,))) dataloader = DataLoader(dataset, batch_size=10, shuffle=True) # 定义损失函数和优化器 criterion = nn.CrossEntropyLoss() optimizer = torch.optim.SGD(model.parameters(), lr=0.01) # 训练循环 for inputs, labels in dataloader: inputs, labels = inputs.to(device), labels.to(device) outputs = model(inputs) loss = criterion(outputs, labels) optimizer.zero_grad() loss.backward() optimizer.step() print(f"Loss: {loss.item()}") ``` --- ### 3.3 推荐做法 由于 DP 存在诸多局限性,目前社区普遍推荐使用 **DDP**(Distributed Data Parallel)进行分布式训练。DDP 支持跨节点训练、更高效的通信机制以及更好的扩展性。对于大规模模型训练,还可以结合 FSDP(Fully Sharded Data Parallel)进一步优化内存使用。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值