news 2026/10/31 15:12:23

股票交易最大收益算法:动态规划与贪心实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
股票交易最大收益算法:动态规划与贪心实战

1. 问题背景与核心需求

股票买卖时机选择是量化交易和算法设计中的经典问题。给定一个长度为n的价格数组prices,其中prices[i]表示第i天的股票价格,我们需要设计算法计算能够获得的最大收益。这个问题看似简单,但蕴含着动态规划和贪心算法这两种重要算法思想的精妙应用。

在实际交易场景中,这个算法可以用于:

  • 单次交易的最大收益计算(对应BM80问题)
  • 多次交易的最大收益计算(对应BM81问题)
  • 作为更复杂交易策略的基础组件

2. 单次交易最优解(BM80问题)

2.1 暴力解法分析

最直观的解法是双重循环遍历所有可能的买卖组合:

def maxProfit(prices): max_profit = 0 for i in range(len(prices)): for j in range(i+1, len(prices)): profit = prices[j] - prices[i] if profit > max_profit: max_profit = profit return max_profit

这种方法时间复杂度O(n²),在数据量大时性能较差。

2.2 动态规划解法

更优的解法是使用动态规划,将问题分解为子问题:

  1. 定义状态:dp[i]表示前i天的最低价格
  2. 状态转移方程: dp[i] = min(dp[i-1], prices[i])
  3. 最大利润: max_profit = max(max_profit, prices[i] - dp[i])

实现代码:

def maxProfit(prices): if not prices: return 0 min_price = prices[0] max_profit = 0 for price in prices[1:]: max_profit = max(max_profit, price - min_price) min_price = min(min_price, price) return max_profit

这种方法将时间复杂度优化到O(n),空间复杂度O(1)。

2.3 贪心算法解法

贪心算法的思路是:

  • 维护一个当前最小值
  • 每次计算当前价格与最小值的差
  • 始终保持追踪最大差值

实现上与动态规划类似,但思考角度不同:

def maxProfit(prices): if len(prices) < 2: return 0 min_price = prices[0] max_profit = 0 for price in prices: if price < min_price: min_price = price elif price - min_price > max_profit: max_profit = price - min_price return max_profit

3. 多次交易最优解(BM81问题)

3.1 问题描述

现在允许进行多次交易(买入卖出),但不能同时参与多笔交易(必须在再次买入前卖出之前的股票),求最大收益。

3.2 贪心算法解法

关键观察:所有上升区间的累计和就是最大利润。

实现方案:

def maxProfit(prices): profit = 0 for i in range(1, len(prices)): if prices[i] > prices[i-1]: profit += prices[i] - prices[i-1] return profit

这种方法时间复杂度O(n),空间复杂度O(1),是最优解法。

3.3 动态规划解法

定义状态:

  • dp[i][0]:第i天结束时未持有股票的最大利润
  • dp[i][1]:第i天结束时持有股票的最大利润

状态转移方程:

dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i]) dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])

实现代码:

def maxProfit(prices): if not prices: return 0 n = len(prices) dp = [[0]*2 for _ in range(n)] dp[0][0] = 0 dp[0][1] = -prices[0] for i in range(1, n): dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i]) dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i]) return dp[n-1][0]

可以进一步优化空间复杂度到O(1)。

4. 算法选择与性能对比

4.1 单次交易场景

算法时间复杂度空间复杂度适用场景
暴力O(n²)O(1)小数据集
DPO(n)O(1)通用方案
贪心O(n)O(1)最优方案

4.2 多次交易场景

算法时间复杂度空间复杂度适用场景
贪心O(n)O(1)最优方案
DPO(n)O(n)可扩展

5. 实际应用与扩展

5.1 交易费用考虑

现实交易中存在手续费,可以修改状态转移方程:

dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i] - fee) dp[i][1] = max(dp[i-1][1], dp[i-1][0] - prices[i])

5.2 冷却期限制

卖出后需要等待一天才能买入:

dp[i][0] = max(dp[i-1][0], dp[i-1][1] + prices[i]) dp[i][1] = max(dp[i-1][1], dp[i-2][0] - prices[i])

5.3 交易次数限制

对于最多k次交易的通用解法,状态需要增加交易次数的维度。

6. 常见问题与调试技巧

6.1 边界条件处理

常见错误包括:

  • 空输入数组
  • 单元素数组
  • 单调递减价格序列

提示:始终先检查输入有效性,添加边界条件处理。

6.2 状态初始化

动态规划中初始状态的设置很关键:

  • dp[0][0] = 0 (第一天不持有)
  • dp[0][1] = -prices[0] (第一天持有)

6.3 性能优化

对于大规模数据:

  • 优先选择贪心算法
  • 动态规划可以优化空间复杂度
  • 考虑并行计算可能

7. 实战案例演示

使用akshare获取真实股票数据测试:

import akshare as ak # 获取股票历史数据 stock_data = ak.stock_zh_a_daily(symbol="sh600519", adjust="hfq") # 计算最大单次交易收益 prices = stock_data['close'].values print("单次交易最大收益:", maxProfit(prices)) # 计算多次交易最大收益 print("多次交易最大收益:", maxProfit_multiple(prices))

8. 算法选择建议

  1. 单次交易:优先使用贪心/DP的O(n)解法
  2. 多次无限制交易:贪心算法最优
  3. 有交易限制:使用动态规划
  4. 有额外约束(手续费、冷却期):扩展动态规划模型

在实际量化交易系统中,这些算法通常作为基础组件,与风险管理、仓位控制等模块结合使用。

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

t分布表精确完整图:t检验、自由度与p值查表指南

1. 先把 t 分布这件事想明白 "t分布表精确完整图"这个关键词被反复搜出来&#xff0c;多半是有人正在赶一份报告、写一份课程作业&#xff0c;或者刚跑完一组对照实验要做显著性判断。翻遍手边的教材附录&#xff0c;发现那张 t分布表 只有寥寥几行&#xff0c;单尾…

作者头像 李华
网站建设 2026/10/31 15:09:40

Golang测试框架详解:从基础到高级实践

1. Golang测试基础概念解析Go语言内置的测试框架是其工具链中最强大的特性之一。与许多其他语言不同&#xff0c;Go不需要额外的测试库或复杂的配置就能开始编写有效的单元测试。测试文件通常与被测试的代码文件放在同一目录下&#xff0c;并以_test.go结尾。测试函数需要遵循特…

作者头像 李华
网站建设 2026/10/31 15:08:58

UnifoLM-VLA-0大模型如何提升人形机器人直觉思维

1. 项目概述&#xff1a;UnifoLM-VLA-0如何重塑人形机器人的"直觉思维"去年冬天第一次看到宇树G1机器人完成跨障碍取物任务时&#xff0c;我注意到它的动作流畅度明显优于同类产品——这不是简单的路径规划优化&#xff0c;而是对物理交互本质的理解。这种差异正是Un…

作者头像 李华
网站建设 2026/10/31 15:08:25

FLAVA三塔与五损失实战:多模态预训练复现落地避坑

手里同时压着三件事的时候&#xff0c;人最容易做的一个动作就是"再加一套模型"。我去年就干过这么一回&#xff1a;项目里既要给内容打图像标签、又要做图文检索、还要回答关于图片的问题&#xff0c;结果一口气养了三个模型&#xff0c;三个训练脚本、三份数据管线…

作者头像 李华
网站建设 2026/10/31 15:04:28

32位Office拦64位ACE:改MSI安装条件解冲突

简介&#xff1a;这是一份面向在64位Windows系统上同时使用32位Office 2007与64位Access Database Engine 2010的用户整理的实战排错文档&#xff0c;专门针对两者版本位数不匹配导致的安装拦截问题。文档围绕ACE引擎组件的兼容性冲突展开&#xff0c;说明了如何借助7-Zip提取安…

作者头像 李华
网站建设 2026/10/31 15:02:42

多语言实时流数据监控架构设计与优化实践

1. 多语言实时流数据监控的核心挑战在分布式系统和大数据时代&#xff0c;实时流数据监控已成为保障业务连续性的关键基础设施。不同编程语言构建的服务需要统一的监控视角&#xff0c;这对技术架构提出了三大核心挑战&#xff1a;1.1 异构语言环境的指标统一Python服务使用Pro…

作者头像 李华