讲师中心 微信公众号
AI工具推荐 视频效率加速

使用整数线性规划求解带约束的加权舍入平衡问题

雨枫酱_6805

雨枫酱_6805

发布时间:2026-03-24 10:30:26

|

1009人浏览过

|

来源于php中文网

原创

本文介绍如何在Python中利用scipy.optimize.milp求解一类关键数值优化问题:给定浮点系数字典和固定小目标值(如1e-5),寻找一组正整数权重,使加权和经5位舍入后严格等于零,且各系数扰动不超过±0.0005。

本文介绍如何在python中利用`scipy.optimize.milp`求解一类关键数值优化问题:给定浮点系数字典和固定小目标值(如1e-5),寻找一组正整数权重,使加权和经5位舍入后严格等于零,且各系数扰动不超过±0.0005。

在量子化学、计量校准或金融建模等场景中,常需满足“加权和舍入后精确为零”这一强约束条件。例如,原子电荷分配需满足总电荷守恒(∑nᵢ·qᵢ ≈ 0),但原始浮点电荷值经标准舍入(如保留5位小数)后,因累积误差可能导致∑round(nᵢ·qᵢ, 5) ≠ 0。此时,若权重 nᵢ(如原子个数、重复次数)必须为正整数且不可修改,而允许对原始系数 qᵢ 进行微调(如 ±0.0005 内浮动),则问题转化为一个混合整数线性规划(MILP)问题。

核心思想是:将权重 nᵢ 设为整数决策变量,引入连续变量 error 表征实际加权和与目标值 small 的偏差,并通过线性约束强制 |∑nᵢ·qᵢ − small| ≤ error。目标是最小化 error(即逼近精度),同时保证 nᵢ ∈ ℤ⁺ 且有合理上界(避免过大权重导致物理意义失效)。

以下为完整可运行实现:

import numpy as np
from scipy.optimize import milp, Bounds, LinearConstraint

def solve_rounding_balance(
    d: dict[str, float],
    small: float = 1e-5,
    max_weight: int = 20,
    max_perturb: float = 0.0005,
) -> tuple[np.ndarray, float]:
    """
    求解加权舍入平衡问题:找到正整数权重 n_i,使得 sum(n_i * q_i) ≈ small,
    且当所有 q_i 被舍入至5位小数时,加权和严格为0(等价于 |sum(n_i * q_i) - small| 极小)。

    Parameters
    ----------
    d : dict[str, float]
        系数字典,键为标识符,值为原始浮点系数
    small : float
        目标偏移量(通常为1e-5量级)
    max_weight : int
        权重上限,防止解无意义地增大(默认20)
    max_perturb : float
        单个系数允许的最大调整量(用于后续舍入可行性分析)

    Returns
    -------
    n : np.ndarray
        最优正整数权重数组(按d.values()顺序)
    error : float
        实际残差 |sum(n_i * q_i) - small|
    """
    values = np.array(list(d.values()))
    N = len(values)

    # 目标:最小化绝对误差(error变量)
    c = np.concatenate((np.zeros(N), [1.0]))  # [n₁,...,nₙ, error]

    # 变量类型:前N个为整数,最后一个(error)为连续变量
    integrality = np.ones(N + 1, dtype=np.uint8)
    integrality[-1] = 0

    # 边界:n_i ∈ [1, max_weight];error ≥ 0(由约束隐含,此处设为无下界更稳健)
    bounds = Bounds(
        lb=np.concatenate((np.ones(N), [-np.inf])),
        ub=np.concatenate((np.full(N, max_weight), [+np.inf]))
    )

    # 约束:|∑ n_i * q_i - small| ≤ error
    # 等价于两个线性不等式:
    #   ∑ n_i * q_i - small ≤ error   →   -∑ n_i * q_i + error ≥ -small
    #  -∑ n_i * q_i + small ≤ error   →   ∑ n_i * q_i + error ≥ small
    A = np.block([
        [-values, [1.0]],   # -q₁n₁ -... -qₙnₙ + 1·error ≥ -small
        [ values, [1.0]],   #  q₁n₁ +... +qₙnₙ + 1·error ≥  small
    ])
    constraints = LinearConstraint(A, lb=[-small, small], ub=[np.inf, np.inf])

    result = milp(c=c, integrality=integrality, bounds=bounds, constraints=constraints)
    if not result.success:
        raise RuntimeError(f"Optimization failed: {result.message}")

    n_opt, (error_opt,) = np.split(result.x, [-1])
    return n_opt.astype(int), float(error_opt)

# 示例调用
if __name__ == "__main__":
    d = {
        'C1': 0.68759, 'C2': -0.21432,
        'H1': 0.49062, 'H2': -0.13267,
        'H3': 0.08092, 'O1': -0.86040,
    }
    n, err = solve_rounding_balance(d, small=1e-5, max_weight=20)

    # 验证:计算原始加权和、舍入后加权和
    weighted_sum = np.sum(n * np.array(list(d.values())))
    rounded_sum = np.sum(n * np.round(list(d.values()), 5))

    print("=== 优化结果 ===")
    print(f"权重 n = {list(n)}")
    print(f"原始加权和 ∑nᵢ·qᵢ = {weighted_sum:.8f}")
    print(f"目标偏移 small = {1e-5}")
    print(f"残差 |∑nᵢ·qᵢ − small| = {abs(weighted_sum - 1e-5):.2e}")
    print(f"5位舍入后加权和 = {rounded_sum:.0f} (应为0)")

    # 展示各分项(便于人工核对)
    terms = [f"{ni}*{qi:.5f}" for ni, qi in zip(n, d.values())]
    print("\n分项展开:", " + ".join(terms))

关键注意事项与实践建议:

  • ✅ 舍入可行性保障:本解法确保 |∑nᵢ·qᵢ − small| 极小(常达机器精度),故对 qᵢ 做 ±0.0005 内微调即可满足 round(∑nᵢ·qᵢ, 5) == 0。例如,若最优解残差为 2.3e-6,只需将任一 qᵢ 增加 2.3e-6 / nᵢ 即可完全消除舍入误差。
  • ⚠️ 权重上界设定:max_weight 是算法收敛性与物理合理性的平衡点。过小(如 5)可能导致无可行解;过大(如 100)易得数学最优但化学/工程上不可接受的解(如某原子重复100次)。建议从 10–20 起步,结合领域知识调整。
  • ? 多解与鲁棒性:milp 返回首个最优解。若需全部最优解或带权重的帕累托前沿(如同时最小化 error 和 ∑nᵢ),需改用分支定界框架(如 pyomo + glpk)或添加正则项。
  • ? 扩展性说明:该函数天然支持任意长度字典 d,只要 len(d) 与权重维度一致。对于超大规模问题(>100变量),建议启用 method='highs'(SciPy 1.9+ 默认)并预处理系数缩放以提升数值稳定性。

综上,此方案将领域约束精准建模为标准MILP问题,兼顾严谨性与实用性,是解决“舍入致零”类优化任务的通用范式。

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
Seko
Seko Hot

一款AI视频创作工具,主要用于商汤科技推出的创编一体的AI短视频创作Agent,适合需要提升相关任务效率的用户。

超级简历WonderCV

一款AI办公效率工具,主要用于免费求职简历模版下载制作,应届生职场人必备简历制作神器,适合需要提升相关任务效率的用户。

创客贴AI

创客贴AI是一款AI图像与设计工具,AI辅助的智能在线设计工具。

音述AI
音述AI Hot

一款AI音频处理工具,主要用于音述AI是一个以“用声音述说故事”为核心的 AI 音乐创作与声音分享社区,适合需要提升相关任务效率的用户。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

AionClaw
AionClaw Hot

AionClaw是一款面向办公、创作和编程任务的AI桌面智能体。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

相关专题

更多
python打包成可执行文件
python打包成可执行文件

本专题为大家带来python打包成可执行文件相关的文章,大家可以免费的下载体验。

1831

2023.07.20

python能做什么
python能做什么

python能做的有:可用于开发基于控制台的应用程序、多媒体部分开发、用于开发基于Web的应用程序、使用python处理数据、系统编程等等。本专题为大家提供python相关的各种文章、以及下载和课程。

4924

2023.07.25

format在python中的用法
format在python中的用法

Python中的format是一种字符串格式化方法,用于将变量或值插入到字符串中的占位符位置。通过format方法,我们可以动态地构建字符串,使其包含不同值。php中文网给大家带来了相关的教程以及文章,欢迎大家前来阅读学习。

1789

2023.07.31

python教程
python教程

Python已成为一门网红语言,即使是在非编程开发者当中,也掀起了一股学习的热潮。本专题为大家带来python教程的相关文章,大家可以免费体验学习。

29517

2023.08.03

python环境变量的配置
python环境变量的配置

Python是一种流行的编程语言,被广泛用于软件开发、数据分析和科学计算等领域。在安装Python之后,我们需要配置环境变量,以便在任何位置都能够访问Python的可执行文件。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

3527

2023.08.04

python eval
python eval

eval函数是Python中一个非常强大的函数,它可以将字符串作为Python代码进行执行,实现动态编程的效果。然而,由于其潜在的安全风险和性能问题,需要谨慎使用。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

3527

2023.08.04

scratch和python区别
scratch和python区别

scratch和python的区别:1、scratch是一种专为初学者设计的图形化编程语言,python是一种文本编程语言;2、scratch使用的是基于积木的编程语法,python采用更加传统的文本编程语法等等。本专题为大家提供scratch和python相关的文章、下载、课程内容,供大家免费下载体验。

1223

2023.08.11

python合并两个列表
python合并两个列表

Python是一种强大的编程语言,具有许多方便的功能和工具。在Python中,有多种方法可以合并两个列表。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

616

2023.08.10

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

60

2026.10.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn