LintCode 558: Sliding Window Matrix Maximum

本文介绍了一种求解滑动窗口中矩阵最大值的方法。针对一个n*m的矩阵,利用大小为k*k的滑动窗口从左上角移动到右下角,计算窗口内各元素的和,并找出所有和中的最大值。提供了两种解决方案:一是通过计算累加和再求子数组的最大值;二是使用动态规划的方法。
  1. Sliding Window Matrix Maximum

Given an array of n * m matrix, and a moving matrix window (size k * k), move the window from top left to botton right at each iteration, find the maximum sum inside the window at each moving.
Return 0 if the answer does not exist.

Example
For matrix

[
[1, 5, 3],
[3, 2, 1],
[4, 1, 9],
]
The moving window size k = 2.
return 13.

At first the window is at the start of the array like this

[
[|1, 5|, 3],
[|3, 2|, 1],
[4, 1, 9],
]
,get the sum 11;
then the window move one step forward.

[
[1, |5, 3|],
[3, |2, 1|],
[4, 1, 9],
]
,get the sum 11;
then the window move one step forward again.

[
[1, 5, 3],
[|3, 2|, 1],
[|4, 1|, 9],
]
,get the sum 10;
then the window move one step forward again.

[
[1, 5, 3],
[3, |2, 1|],
[4, |1, 9|],
]
,get the sum 13;
SO finally, get the maximum from all the sum which is 13.

Challenge
O(n^2) time.

解法1:
思路:先求accums[],即matrix[][]的每k行的累加和。然后对accums[]每行求其固定size的subarray的最大值,即调用maxFixSizeSubArray()。
注意求固定size的subarray的最大值必须用sliding window或deque,跟前面做过的Continuous Subarray(LintCode 402, 403)不一样,那两题没有固定size大小。

代码如下:

class Solution {
public:
    /**
     * @param matrix: an integer array of n * m matrix
     * @param k: An integer
     * @return: the maximum number
     */
    int maxSlidingMatrix(vector<vector<int>> &matrix, int k) {
        int m = matrix.size();
        if (m < k) return 0;
        int n = matrix[0].size();
        if (n < k) return 0;
        vector<vector<int>> accums(m - k + 1, vector<int>(n, 0));
        for (int i = 0; i < k; ++i) {
            for (int j = 0; j < n; ++j) {
                accums[0][j] += matrix[i][j];
            }
        }

        for (int i = 1; i <= m - k; ++i) {
            for (int j = 0; j < n; ++j) {
                accums[i][j] = accums[i - 1][j] - matrix[i - 1][j] + matrix[i + k - 1][j];
            }
        }
        
        int maxSum = INT_MIN;
        for (int i = 0; i < m - k + 1; ++i) {
            maxSum = max(maxSum, maxFixSizeSubArray(accums[i], k));
        }
        return maxSum;
    }

private:
    int maxFixSizeSubArray(vector<int> & nums, int k) {
        int n = nums.size();
        if (n < k) return 0;
        int sum = 0, maxSum = 0;
        for (int i = 0; i < k; ++i) {
            sum += nums[i];
        }
        maxSum = sum;
        for (int i = 1; i < n - k + 1; ++i) {
            sum += nums[k + i - 1] - nums[i - 1];
            maxSum = max(maxSum, sum);
        }
        return maxSum;
    }
    
};

解法2:直接用DP。
代码如下:

class Solution {
public:
    /**
     * @param matrix: an integer array of n * m matrix
     * @param k: An integer
     * @return: the maximum number
     */
    int maxSlidingMatrix(vector<vector<int>> &matrix, int k) {
        int m = matrix.size();
        if (m < k) return 0;
        int n = matrix[0].size();
        if (n < k) return 0;
        vector<vector<int>> sums(m + 1, vector<int>(n + 1, 0));
        
        for (int i = 1; i <= m; ++i) {
            for (int j = 1; j <= n; ++j) {
                sums[i][j] = sums[i][j - 1] + sums[i - 1][j] - sums[i - 1][j - 1] + matrix[i - 1][j - 1];
            }
        }
        
        int result = INT_MIN;
        for (int i = k; i <= m; ++i) {
            for (int j = k; j <= n; ++j) {
                result = max(result, sums[i][j] - sums[i - k][j] - sums[i][j - k] + sums[i - k][j - k]);
            }
        }
        
        return result;
    }
};
### Sliding Window Attention 的 SDPA 实现问题分析 当启用 `Sliding Window Attention` 并遇到错误提示其未在 `scaled_dot_product_attention (SDPA)` 中实现时,通常是因为当前框架版本尚未支持该功能或缺少必要的配置选项。以下是可能的原因及解决方法: #### 1. **确认 PyTorch 版本** PyTorch 的某些高级特性(如滑动窗口注意力机制)依赖于较新的版本支持。如果使用的 PyTorch 版本较低,则可能导致此功能不可用[^2]。 ```python import torch print(torch.__version__) ``` 建议升级到最新稳定版的 PyTorch,例如通过以下命令安装: ```bash pip install --upgrade torch torchvision torchaudio ``` #### 2. **检查是否启用了 FlashAttention 或 Xformers 支持** 部分框架会尝试优先调用高效实现(如 FlashAttention 或 Xformers),但如果这些库未正确安装或初始化,则可能会回退至默认路径并触发不支持警告[^3]。 - 安装所需扩展包: ```bash pip install flash-attn xformers ``` - 在代码中显式加载相关模块以验证可用性: ```python try: import flash_attn use_flash = True except ImportError: try: import xformers.ops as xops use_xformers = True except ImportError: pass ``` #### 3. **调整模型参数设置** 对于特定任务场景下的自定义需求,需确保传递给模型构建器的相关标志位被正确定义。例如,在 Hugging Face Transformers 库中可以通过修改训练参数来控制注意力计算方式的选择逻辑[^4]: ```python from transformers import TrainingArguments training_args = TrainingArguments( ... attention_window=[512], # 设置每层对应的窗口大小 use_cache=False # 如果使用梯度检查点技术则禁用缓存策略 ) ``` 同时注意开启混合精度运算以及分片数据并行处理等性能优化措施可以进一步缓解资源压力从而间接促进复杂算法落地可行性提升[^5]。 --- ### 提供一段伪代码示例帮助理解如何集成上述要素完成最终部署方案设计工作流程如下所示: ```python # 初始化环境变量允许TF32模式提高矩阵乘法速度 torch.backends.cuda.matmul.allow_tf32 = True def train_model(): device = 'cuda' if torch.cuda.is_available() else 'cpu' model = YourModelClass().to(device) optimizer = Adafactor(model.parameters(), lr=1e-3, relative_step=False) scaler = GradScaler(init_scale=2**16, growth_interval=2000) for epoch in range(num_epochs): for batch in dataloader: with autocast(enabled=True): outputs = model(batch['input_ids'].to(device)) loss = compute_loss(outputs, labels=batch['labels']) scaler.scale(loss).backward() scaler.step(optimizer) scaler.update() train_model() ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值