python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python Excel生成动态规划表

Python+Excel脚本实现一键生成动态规划表

作者:IT小本本

这篇文章主要为大家详细介绍了 Python Excel如何通过脚本实现一键生成动态规划表,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下

导读:刷算法题总被“画DP状态表”折磨?手推容易错,Excel拉公式又容易串列… 今天分享一段不到50行的Python脚本,从Excel读取参数 → 自动跑完二维DP+一维滚动数组快照 → Pandas一键输出高清报表。算法党、数据分析师、面试备考者必藏!

为什么“手动推演DP”是反 人类设计?

动态规划(DP)是算法面试的“重灾区”,但90%的初学者都卡在状态表推演这一步:

破局思路:把“参数配置”交给 Excel,把“状态推演”交给 Python,把“可视化展示”交给 Pandas。数据与逻辑彻底解耦,推演过程透明可追溯!

核心代码拆解:50行搞定DP全自动推演

from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
import openpyxl
import pandas as pd

# 1️⃣ 精准读取:从 Excel 剥离业务参数
df_items = pd.read_excel("input_data.xlsx", usecols=[0, 1, 2]).dropna()
df_config = pd.read_excel("input_data.xlsx", usecols=[5, 6]).dropna()

item_names = df_items["物品名称"].tolist()
weights = df_items["物品大小 w[i]"].astype(int).tolist()
values = df_items["物品价值 v[i]"].astype(int).tolist()
max_capacity = int(df_config.loc[df_config["配置项"] == "最大容量 max_capacity", "参数值"].values[0])

# 2️⃣ 二维 DP 推演:完整记录状态转移轨迹
n = len(weights)
dp_2d = [[0] * (max_capacity + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
    w, v = weights[i - 1], values[i - 1]
    for j in range(max_capacity + 1):
        if j < w:
            dp_2d[i][j] = dp_2d[i - 1][j]
        else:
            dp_2d[i][j] = max(dp_2d[i - 1][j], dp_2d[i - 1][j - w] + v)

# 3️⃣ 一维滚动数组 + 历史快照:空间优化 O(C),过程全记录
dp_1d = [0] * (max_capacity + 1)
dp_1d_history = [list(dp_1d)]
for i in range(n):
    w, v = weights[i], values[i]
    for j in range(max_capacity, w - 1, -1):
        dp_1d[j] = max(dp_1d[j], dp_1d[j - w] + v)
    dp_1d_history.append(list(dp_1d))

# 4️⃣ Pandas 格式化输出:告别裸 print,表格即报表
columns = [str(j) for j in range(max_capacity + 1)]
index_labels = ["无物品"] + item_names

df_2d = pd.DataFrame(dp_2d, index=index_labels, columns=columns)
df_1d = pd.DataFrame(dp_1d_history, index=index_labels, columns=columns)
print(df_2d.to_string())
print(df_1d.to_string())

为什么这段写法“降维打击”

二维表 vs 一维快照:教学与实战的完美结合

数据读取“零污染”

df_config.loc[df_config["配置项"] == "最大容量 max_capacity", "参数值"].values[0]

精准定位配置单元格,不依赖固定行号。Excel模板随便挪,Python照样抓得准。

Pandas 一键转报表

index_labelscolumns 动态生成,索引自带“无物品”占位,列名直接映射容量 0~max_capacity。输出结果可直接 to_excel() 导出,无缝对接汇报材料。

真实业务能怎么用

场景DP 映射逻辑业务价值
项目预算分配容量=总预算,重量=项目成本,价值=预期收益自动找出 ROI 最高的项目组合
仓储装载优化容量=货车载重/容积,重量=货物体积,价值=运费/利润单次发车利润最大化
服务器资源调度容量=CPU/内存上限,重量=任务资源占用,价值=SLA优先级任务排队策略自动推演

实战避坑 & 进阶玩法

坑点解决方案
Excel含空行/非数字字符dropna() + .astype(int) 前置清洗
想看具体选了哪些物品?在二维表基础上加反向回溯逻辑(从 dp[n][C] 逆推)
需要带高亮样式的 Excel 报表?代码已导入 openpyxl.styles,可用 worksheet.cell().fill = PatternFill(...) 给最大值加金色背景
容量/物品数超 1000?改用 numpy 数组替代原生 list,内存连续访问提速 5~10 倍

结语:算法不是玄学,是工程

很多初学者觉得 DP 抽象,是因为缺乏状态可视化工具。把参数抽离到 Excel,把推演交给 Python,把展示交给 Pandas,你不仅是在写脚本,更是在搭建一套可复用、可审计、可交付的算法引擎

附完整代码:

from openpyxl.styles import Font, PatternFill, Alignment, Border, Side
import openpyxl
import pandas as pd

# ==============================================================================
# 1.输入参数的 Excel 文件 (input_data.xlsx)
# ==============================================================================
# 在这里原始数据表,
input_file = "input_data.xlsx"



# ==============================================================================
# 2. 读取与计算阶段:完全从 Excel 中加载数据,并计算生成最终的 DP 状态表
# ==============================================================================
# ---- A. 从 Excel 中读取数据 ----
df_read_items = pd.read_excel(input_file, usecols=[0, 1, 2]).dropna()
df_read_config = pd.read_excel(input_file, usecols=[5, 6]).dropna()

# 从读取到的 DataFrame 中还原出变量列表
item_names = df_read_items["物品名称"].tolist()
weights = df_read_items["物品大小 w[i]"].astype(int).tolist()
values = df_read_items["物品价值 v[i]"].astype(int).tolist()

# 从配置区精准提取最大容量数字
max_capacity = int(df_read_config.loc[df_read_config["配置项"] == "最大容量 max_capacity", "参数值"].values[0])


# ---- B. 核心动态规划算法核心逻辑 ----
n = len(weights)
# 1. 计算二维 DP 状态表
dp_2d = [[0] * (max_capacity + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
    w, v = weights[i - 1], values[i - 1]
    for j in range(max_capacity + 1):
        if j < w:
            dp_2d[i][j] = dp_2d[i - 1][j]
        else:
            dp_2d[i][j] = max(dp_2d[i - 1][j], dp_2d[i - 1][j - w] + v)

# 2. 计算一维滚动数组并截取每轮的历史快照
dp_1d = [0] * (max_capacity + 1)
dp_1d_history = [list(dp_1d)]
for i in range(n):
    w, v = weights[i], values[i]
    for j in range(max_capacity, w - 1, -1):
        dp_1d[j] = max(dp_1d[j], dp_1d[j - w] + v)
    dp_1d_history.append(list(dp_1d))


# ---- C. 使用 Pandas 格式化输出最终内容 ----
columns = [str(j) for j in range(max_capacity + 1)]
index_labels = ["无物品"] + item_names

print("="*43 + " 最终输出 1:二维 DP 状态表 " + "="*43)
df_output_2d = pd.DataFrame(dp_2d, index=index_labels, columns=columns)
df_output_2d.index.name = "物品名称"
print(df_output_2d.to_string())

print("\n" + "="*41 + " 最终输出 2:一维滚动数组快照表 " + "="*41)
df_output_1d = pd.DataFrame(dp_1d_history, index=index_labels, columns=columns)
df_output_1d.index.name = "物品名称"
print(df_output_1d.to_string())

到此这篇关于 Python+Excel脚本实现一键生成动态规划表的文章就介绍到这了,更多相关Python Excel生成动态规划表内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文