[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"similar-khalil-research--PyEPO":3,"tool-khalil-research--PyEPO":64},[4,17,27,35,43,56],{"id":5,"name":6,"github_repo":7,"description_zh":8,"stars":9,"difficulty_score":10,"last_commit_at":11,"category_tags":12,"status":16},3808,"stable-diffusion-webui","AUTOMATIC1111\u002Fstable-diffusion-webui","stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面，旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点，将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。\n\n无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师，还是想要深入探索模型潜力的开发者与研究人员，都能从中获益。其核心亮点在于极高的功能丰富度：不仅支持文生图、图生图、局部重绘（Inpainting）和外绘（Outpainting）等基础模式，还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外，它内置了 GFPGAN 和 CodeFormer 等人脸修复工具，支持多种神经网络放大算法，并允许用户通过插件系统无限扩展能力。即使是显存有限的设备，stable-diffusion-webui 也提供了相应的优化选项，让高质量的 AI 艺术创作变得触手可及。",162132,3,"2026-04-05T11:01:52",[13,14,15],"开发框架","图像","Agent","ready",{"id":18,"name":19,"github_repo":20,"description_zh":21,"stars":22,"difficulty_score":23,"last_commit_at":24,"category_tags":25,"status":16},1381,"everything-claude-code","affaan-m\u002Feverything-claude-code","everything-claude-code 是一套专为 AI 编程助手（如 Claude Code、Codex、Cursor 等）打造的高性能优化系统。它不仅仅是一组配置文件，而是一个经过长期实战打磨的完整框架，旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。\n\n通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能，everything-claude-code 能显著提升 AI 在复杂任务中的表现，帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略，使得模型响应更快、成本更低，同时有效防御潜在的攻击向量。\n\n这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库，还是需要 AI 协助进行安全审计与自动化测试，everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目，它融合了多语言支持与丰富的实战钩子（hooks），让 AI 真正成长为懂上",138956,2,"2026-04-05T11:33:21",[13,15,26],"语言模型",{"id":28,"name":29,"github_repo":30,"description_zh":31,"stars":32,"difficulty_score":23,"last_commit_at":33,"category_tags":34,"status":16},2271,"ComfyUI","Comfy-Org\u002FComfyUI","ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎，专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式，采用直观的节点式流程图界面，让用户通过连接不同的功能模块即可构建个性化的生成管线。\n\n这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景，也能自由组合模型、调整参数并实时预览效果，轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性，不仅支持 Windows、macOS 和 Linux 全平台，还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构，并率先支持 SDXL、Flux、SD3 等前沿模型。\n\n无论是希望深入探索算法潜力的研究人员和开发者，还是追求极致创作自由度的设计师与资深 AI 绘画爱好者，ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能，使其成为当前最灵活、生态最丰富的开源扩散模型工具之一，帮助用户将创意高效转化为现实。",107662,"2026-04-03T11:11:01",[13,14,15],{"id":36,"name":37,"github_repo":38,"description_zh":39,"stars":40,"difficulty_score":23,"last_commit_at":41,"category_tags":42,"status":16},3704,"NextChat","ChatGPTNextWeb\u002FNextChat","NextChat 是一款轻量且极速的 AI 助手，旨在为用户提供流畅、跨平台的大模型交互体验。它完美解决了用户在多设备间切换时难以保持对话连续性，以及面对众多 AI 模型不知如何统一管理的痛点。无论是日常办公、学习辅助还是创意激发，NextChat 都能让用户随时随地通过网页、iOS、Android、Windows、MacOS 或 Linux 端无缝接入智能服务。\n\n这款工具非常适合普通用户、学生、职场人士以及需要私有化部署的企业团队使用。对于开发者而言，它也提供了便捷的自托管方案，支持一键部署到 Vercel 或 Zeabur 等平台。\n\nNextChat 的核心亮点在于其广泛的模型兼容性，原生支持 Claude、DeepSeek、GPT-4 及 Gemini Pro 等主流大模型，让用户在一个界面即可自由切换不同 AI 能力。此外，它还率先支持 MCP（Model Context Protocol）协议，增强了上下文处理能力。针对企业用户，NextChat 提供专业版解决方案，具备品牌定制、细粒度权限控制、内部知识库整合及安全审计等功能，满足公司对数据隐私和个性化管理的高标准要求。",87618,"2026-04-05T07:20:52",[13,26],{"id":44,"name":45,"github_repo":46,"description_zh":47,"stars":48,"difficulty_score":23,"last_commit_at":49,"category_tags":50,"status":16},2268,"ML-For-Beginners","microsoft\u002FML-For-Beginners","ML-For-Beginners 是由微软推出的一套系统化机器学习入门课程，旨在帮助零基础用户轻松掌握经典机器学习知识。这套课程将学习路径规划为 12 周，包含 26 节精炼课程和 52 道配套测验，内容涵盖从基础概念到实际应用的完整流程，有效解决了初学者面对庞大知识体系时无从下手、缺乏结构化指导的痛点。\n\n无论是希望转型的开发者、需要补充算法背景的研究人员，还是对人工智能充满好奇的普通爱好者，都能从中受益。课程不仅提供了清晰的理论讲解，还强调动手实践，让用户在循序渐进中建立扎实的技能基础。其独特的亮点在于强大的多语言支持，通过自动化机制提供了包括简体中文在内的 50 多种语言版本，极大地降低了全球不同背景用户的学习门槛。此外，项目采用开源协作模式，社区活跃且内容持续更新，确保学习者能获取前沿且准确的技术资讯。如果你正寻找一条清晰、友好且专业的机器学习入门之路，ML-For-Beginners 将是理想的起点。",84991,"2026-04-05T10:45:23",[14,51,52,53,15,54,26,13,55],"数据工具","视频","插件","其他","音频",{"id":57,"name":58,"github_repo":59,"description_zh":60,"stars":61,"difficulty_score":10,"last_commit_at":62,"category_tags":63,"status":16},3128,"ragflow","infiniflow\u002Fragflow","RAGFlow 是一款领先的开源检索增强生成（RAG）引擎，旨在为大语言模型构建更精准、可靠的上下文层。它巧妙地将前沿的 RAG 技术与智能体（Agent）能力相结合，不仅支持从各类文档中高效提取知识，还能让模型基于这些知识进行逻辑推理和任务执行。\n\n在大模型应用中，幻觉问题和知识滞后是常见痛点。RAGFlow 通过深度解析复杂文档结构（如表格、图表及混合排版），显著提升了信息检索的准确度，从而有效减少模型“胡编乱造”的现象，确保回答既有据可依又具备时效性。其内置的智能体机制更进一步，使系统不仅能回答问题，还能自主规划步骤解决复杂问题。\n\n这款工具特别适合开发者、企业技术团队以及 AI 研究人员使用。无论是希望快速搭建私有知识库问答系统，还是致力于探索大模型在垂直领域落地的创新者，都能从中受益。RAGFlow 提供了可视化的工作流编排界面和灵活的 API 接口，既降低了非算法背景用户的上手门槛，也满足了专业开发者对系统深度定制的需求。作为基于 Apache 2.0 协议开源的项目，它正成为连接通用大模型与行业专有知识之间的重要桥梁。",77062,"2026-04-04T04:44:48",[15,14,13,26,54],{"id":65,"github_repo":66,"name":67,"description_en":68,"description_zh":69,"ai_summary_zh":69,"readme_en":70,"readme_zh":71,"quickstart_zh":72,"use_case_zh":73,"hero_image_url":74,"owner_login":75,"owner_name":75,"owner_avatar_url":76,"owner_bio":77,"owner_company":77,"owner_location":77,"owner_email":77,"owner_twitter":77,"owner_website":77,"owner_url":78,"languages":79,"stars":88,"forks":89,"last_commit_at":90,"license":91,"difficulty_score":10,"env_os":92,"env_gpu":93,"env_ram":94,"env_deps":95,"category_tags":107,"github_topics":77,"view_count":23,"oss_zip_url":77,"oss_zip_packed_at":77,"status":16,"created_at":108,"updated_at":109,"faqs":110,"releases":140},2876,"khalil-research\u002FPyEPO","PyEPO","A PyTorch-based End-to-End Predict-then-Optimize Library for Linear and Integer Programming","PyEPO 是一款基于 PyTorch 的开源库，专为解决“先预测后优化”（Predict-then-Optimize）问题而设计。在传统流程中，机器学习预测与数学规划求解往往是割裂的，导致最终决策并非全局最优。PyEPO 通过将线性或整数规划模型无缝嵌入神经网络，实现了从数据输入到优化决策的端到端联合训练，让模型能直接以最终决策质量为目标进行优化。\n\n这款工具特别适合人工智能研究人员、运筹学专家以及需要处理复杂决策系统的开发者使用。它支持 Gurobi、COPT、Pyomo、Google OR-Tools 等多种主流求解器，并提供了独特的 GPU 加速亮点：通过集成基于 JAX 的 MPAX 求解器，PyEPO 利用原始 - 对偶混合梯度（PDHG）算法，不仅实现了原生 GPU 求解和批量并行计算，还彻底消除了传统方案中频繁的 CPU-GPU 数据传输瓶颈。这使得大规模优化问题的训练效率显著提升，让用户能够更流畅地构建和部署高效的智能决策系统。","# PyEPO: A PyTorch-based End-to-End Predict-then-Optimize Tool\n\n[![License: MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-MIT-yellow.svg?style=flat-square)](https:\u002F\u002Fopensource.org\u002Flicenses\u002FMIT)\n[![GitHub Stars](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fstars\u002Fkhalil-research\u002FPyEPO?style=flat-square)](https:\u002F\u002Fgithub.com\u002Fkhalil-research\u002FPyEPO\u002Fstargazers)\n[![Tests](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Factions\u002Fworkflow\u002Fstatus\u002Fkhalil-research\u002FPyEPO\u002Ftest.yml?branch=main&style=flat-square&label=tests)](https:\u002F\u002Fgithub.com\u002Fkhalil-research\u002FPyEPO\u002Factions\u002Fworkflows\u002Ftest.yml)\n[![Python](https:\u002F\u002Fimg.shields.io\u002Fpypi\u002Fpyversions\u002Fpyepo.svg?style=flat-square)](https:\u002F\u002Fpypi.org\u002Fproject\u002Fpyepo\u002F)\n![Platform](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fplatform-Linux%20%7C%20macOS%20%7C%20Windows-lightgrey.svg?style=flat-square)\n[![PyPI version](https:\u002F\u002Fimg.shields.io\u002Fpypi\u002Fv\u002Fpyepo.svg?style=flat-square)](https:\u002F\u002Fpypi.org\u002Fproject\u002Fpyepo\u002F)\n[![PyPI Downloads](https:\u002F\u002Fimg.shields.io\u002Fpypi\u002Fdm\u002Fpyepo?style=flat-square)](https:\u002F\u002Fpepy.tech\u002Fproject\u002Fpyepo)\n[![Conda version](https:\u002F\u002Fimg.shields.io\u002Fconda\u002Fvn\u002Fpyepo\u002Fpyepo.svg?style=flat-square)](https:\u002F\u002Fanaconda.org\u002Fpyepo\u002Fpyepo)\n[![Conda Downloads](https:\u002F\u002Fimg.shields.io\u002Fconda\u002Fdn\u002Fpyepo\u002Fpyepo.svg?style=flat-square)](https:\u002F\u002Fanaconda.org\u002Fpyepo\u002Fpyepo)\n[![Docs](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fdocs-online-green.svg?style=flat-square)](https:\u002F\u002Fkhalil-research.github.io\u002FPyEPO)\n[![Paper](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FMPC-10.1007\u002Fs12532--024--00255--x-blue.svg?style=flat-square)](https:\u002F\u002Flink.springer.com\u002Farticle\u002F10.1007\u002Fs12532-024-00255-x)\n\n\u003Cp align=\"center\">\u003Cimg width=\"100%\" src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fkhalil-research_PyEPO_readme_d61071d7b84d.png\" \u002F>\u003C\u002Fp>\n\n\n## Learning Framework\n\n\u003Cp align=\"center\">\u003Cimg width=\"100%\" src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fkhalil-research_PyEPO_readme_5da25559754a.png\" \u002F>\u003C\u002Fp>\n\n\n## Publication\n\nThis repository is the official implementation of the paper:\n[PyEPO: A PyTorch-based End-to-End Predict-then-Optimize Library for Linear and Integer Programming](https:\u002F\u002Flink.springer.com\u002Farticle\u002F10.1007\u002Fs12532-024-00255-x) (Accepted to Mathematical Programming Computation (MPC))\n\nCitation:\n```\n@article{tang2024,\n  title={PyEPO: a PyTorch-based end-to-end predict-then-optimize library for linear and integer programming},\n  author={Tang, Bo and Khalil, Elias B},\n  journal={Mathematical Programming Computation},\n  issn={1867-2957},\n  doi={10.1007\u002Fs12532-024-00255-x},\n  year={2024},\n  month={July},\n  publisher={Springer}\n}\n```\n\n\n## Introduction\n\n``PyEPO`` (PyTorch-based End-to-End Predict-then-Optimize Tool) is a Python-based, open-source software that supports modeling and solving predict-then-optimize problems with linear objective functions. The core capability of ``PyEPO`` is to build optimization models with [GurobiPy](https:\u002F\u002Fwww.gurobi.com\u002F), [COPT](https:\u002F\u002Fshanshu.ai\u002Fcopt), [Pyomo](http:\u002F\u002Fwww.pyomo.org\u002F), [Google OR-Tools](https:\u002F\u002Fdevelopers.google.com\u002Foptimization), [MPAX](https:\u002F\u002Fgithub.com\u002FMIT-Lu-Lab\u002FMPAX) or any other solvers and algorithms, then embed the optimization model into an artificial neural network for the end-to-end training. For this purpose, ``PyEPO`` implements various methods as [PyTorch](https:\u002F\u002Fpytorch.org\u002F) autograd modules.\n\nIn particular, ``PyEPO`` integrates [MPAX](https:\u002F\u002Fgithub.com\u002FMIT-Lu-Lab\u002FMPAX), a JAX-based mathematical programming solver using the PDHG (Primal-Dual Hybrid Gradient) algorithm for GPU-accelerated optimization. MPAX brings three key advantages for end-to-end training: (1) **GPU-native solving** — the first-order PDHG method is inherently parallelizable and runs efficiently on GPU; (2) **batch solving** — an entire mini-batch of optimization instances can be solved simultaneously on GPU via vectorization; and (3) **no GPU–CPU data transfer overhead** — traditional solvers (e.g., Gurobi) run on CPU, requiring costly data transfers between GPU and CPU at every training iteration, whereas MPAX keeps both the neural network and the solver on GPU, eliminating this bottleneck.\n\n\n## Documentation\n\nThe official ``PyEPO`` docs can be found at [https:\u002F\u002Fkhalil-research.github.io\u002FPyEPO](https:\u002F\u002Fkhalil-research.github.io\u002FPyEPO).\n\n## Slides\n\nOur recent tutorial was at the ACC 2024 conference. You can view the talk slides [here](https:\u002F\u002Fgithub.com\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fslides\u002FPyEPO.pdf).\n\n## Tutorial\n\n- [![Open In Colab](https:\u002F\u002Fcolab.research.google.com\u002Fassets\u002Fcolab-badge.svg)](https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fnotebooks\u002F01%20Optimization%20Model.ipynb)**01 Optimization Model:** Build an optimization solver\n- [![Open In Colab](https:\u002F\u002Fcolab.research.google.com\u002Fassets\u002Fcolab-badge.svg)](https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fnotebooks\u002F02%20Optimization%20Dataset.ipynb)**02 Optimization Dataset:** Generate synthetic data and use optDataset\n- [![Open In Colab](https:\u002F\u002Fcolab.research.google.com\u002Fassets\u002Fcolab-badge.svg)](https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fnotebooks\u002F03%20Training%20and%20Testing.ipynb)**03 Training and Testing:** Train and test different approaches\n- [![Open In Colab](https:\u002F\u002Fcolab.research.google.com\u002Fassets\u002Fcolab-badge.svg)](https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fnotebooks\u002F04%202D%20knapsack%20Solution%20Visualization.ipynb)**04 2D knapsack Solution Visualization:** Visualize solutions for the knapsack problem\n- [![Open In Colab](https:\u002F\u002Fcolab.research.google.com\u002Fassets\u002Fcolab-badge.svg)](https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fnotebooks\u002F05%20Warcraft%20Shortest%20Path.ipynb)**05 Warcraft Shortest Path:** Train shortest path models on the Warcraft terrains dataset\n- [![Open In Colab](https:\u002F\u002Fcolab.research.google.com\u002Fassets\u002Fcolab-badge.svg)](https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fnotebooks\u002F06%20Real-World%20Energy%20Scheduling.ipynb)**06 Real-World Energy Scheduling:** Apply PyEPO to real energy data\n- [![Open In Colab](https:\u002F\u002Fcolab.research.google.com\u002Fassets\u002Fcolab-badge.svg)](https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fnotebooks\u002F07%20kNN%20Robust%20Losses.ipynb)**07 kNN Robust Losses:** Use optDatasetKNN for robust losses\n- [![Open In Colab](https:\u002F\u002Fcolab.research.google.com\u002Fassets\u002Fcolab-badge.svg)](https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fnotebooks\u002F08%20Solving%20on%20MPAX%20with%20PDHG.ipynb)**08 Solving on MPAX with PDHG:** Use MPAX for GPU-accelerated batch solving\n\n\n## Experiments\n\nTo **reproduce the experiments** in the original paper, please use the code and follow the instructions in this [branch](https:\u002F\u002Fgithub.com\u002Fkhalil-research\u002FPyEPO\u002Ftree\u002FMPC). Please note that this branch is a very early version.\n\n\n## Features\n\n- Implement **SPO+** [[1]](https:\u002F\u002Fdoi.org\u002F10.1287\u002Fmnsc.2020.3922), **DBB** [[3]](https:\u002F\u002Farxiv.org\u002Fabs\u002F1912.02175), **NID** [[7]](https:\u002F\u002Farxiv.org\u002Fabs\u002F2205.15213), **DPO** [[4]](https:\u002F\u002Fpapers.nips.cc\u002Fpaper\u002F2020\u002Fhash\u002F6bb56208f672af0dd65451f869fedfd9-Abstract.html), **PFYL** [[4]](https:\u002F\u002Fpapers.nips.cc\u002Fpaper\u002F2020\u002Fhash\u002F6bb56208f672af0dd65451f869fedfd9-Abstract.html), **NCE** [[5]](https:\u002F\u002Fwww.ijcai.org\u002Fproceedings\u002F2021\u002F390), **LTR** [[6]](https:\u002F\u002Fproceedings.mlr.press\u002Fv162\u002Fmandi22a.html), **I-MLE** [[8]](https:\u002F\u002Fproceedings.neurips.cc\u002Fpaper_files\u002Fpaper\u002F2021\u002Fhash\u002F7a430339c10c642c4b2251756fd1b484-Abstract.html), **AI-MLE** [[9]](https:\u002F\u002Fojs.aaai.org\u002Findex.php\u002FAAAI\u002Farticle\u002Fview\u002F26103), and **PG** [[11]](https:\u002F\u002Farxiv.org\u002Fabs\u002F2402.03256).\n- Support [Gurobi](https:\u002F\u002Fwww.gurobi.com\u002F), [COPT](https:\u002F\u002Fshanshu.ai\u002Fcopt), [Pyomo](http:\u002F\u002Fwww.pyomo.org\u002F), [Google OR-Tools](https:\u002F\u002Fdevelopers.google.com\u002Foptimization) and [MPAX](https:\u002F\u002Fgithub.com\u002FMIT-Lu-Lab\u002FMPAX) API\n- Support parallel computing for optimization solvers\n- Support solution caching [[5]](https:\u002F\u002Fwww.ijcai.org\u002Fproceedings\u002F2021\u002F390) to speed up training\n- Support kNN robust loss [[10]](https:\u002F\u002Farxiv.org\u002Fabs\u002F2310.04328) to improve decision quality\n\n## Installation\n\n### Clone and Install from this Repo\n\nYou can download ``PyEPO`` from our GitHub repository.\n\n```bash\ngit clone -b main --depth 1 https:\u002F\u002Fgithub.com\u002Fkhalil-research\u002FPyEPO.git\n```\n\nAnd install it.\n\n```bash\npip install PyEPO\u002Fpkg\u002F.\n```\n\n### Pip Install\n\nThe package is now available for installation on [PyPI](https:\u002F\u002Fpypi.org\u002Fproject\u002Fpyepo\u002F). You can easily install `PyEPO` using pip by running the following command:\n\n```bash\npip install pyepo\n```\n\n### Conda Install\n\n`PyEPO` is also available on [Anaconda Cloud](https:\u002F\u002Fanaconda.org\u002Fpyepo\u002Fpyepo). If you prefer to use conda for installation, you can install `PyEPO` with the following command:\n\n```bash\nconda install -c pyepo pyepo\n```\n\n\n## Dependencies\n\n* [NumPy](https:\u002F\u002Fnumpy.org\u002F)\n* [SciPy](https:\u002F\u002Fscipy.org\u002F)\n* [Pathos](https:\u002F\u002Fpathos.readthedocs.io\u002F)\n* [tqdm](https:\u002F\u002Ftqdm.github.io\u002F)\n* [Pyomo](http:\u002F\u002Fwww.pyomo.org\u002F)\n* [Gurobi](https:\u002F\u002Fwww.gurobi.com\u002F)\n* [Scikit Learn](https:\u002F\u002Fscikit-learn.org\u002F)\n* [PyTorch](http:\u002F\u002Fpytorch.org\u002F)\n\n\n## Sample Code\n\n```python\n#!\u002Fusr\u002Fbin\u002Fenv python\n# coding: utf-8\n\nimport gurobipy as gp\nfrom gurobipy import GRB\nimport numpy as np\nimport pyepo\nfrom pyepo.model.grb import optGrbModel\nimport torch\nfrom torch import nn\nfrom torch.utils.data import DataLoader\n\n\n# optimization model\nclass myModel(optGrbModel):\n    def __init__(self, weights):\n        self.weights = np.array(weights)\n        self.num_item = len(weights[0])\n        super().__init__()\n\n    def _getModel(self):\n        # create a model\n        m = gp.Model()\n        # variables\n        x = m.addVars(self.num_item, name=\"x\", vtype=GRB.BINARY)\n        # model sense\n        m.modelSense = GRB.MAXIMIZE\n        # constraints\n        m.addConstr(gp.quicksum([self.weights[0,i] * x[i] for i in range(self.num_item)]) \u003C= 7)\n        m.addConstr(gp.quicksum([self.weights[1,i] * x[i] for i in range(self.num_item)]) \u003C= 8)\n        m.addConstr(gp.quicksum([self.weights[2,i] * x[i] for i in range(self.num_item)]) \u003C= 9)\n        return m, x\n\n\n# prediction model\nclass LinearRegression(nn.Module):\n\n    def __init__(self):\n        super(LinearRegression, self).__init__()\n        self.linear = nn.Linear(num_feat, num_item)\n\n    def forward(self, x):\n        out = self.linear(x)\n        return out\n\n\nif __name__ == \"__main__\":\n\n    # generate data\n    num_data = 1000 # number of data\n    num_feat = 5 # size of feature\n    num_item = 10 # number of items\n    weights, x, c = pyepo.data.knapsack.genData(num_data, num_feat, num_item,\n                                                dim=3, deg=4, noise_width=0.5, seed=135)\n\n    # init optimization model\n    optmodel = myModel(weights)\n\n    # init prediction model\n    predmodel = LinearRegression()\n    # set optimizer\n    optimizer = torch.optim.Adam(predmodel.parameters(), lr=1e-2)\n    # init SPO+ loss\n    spop = pyepo.func.SPOPlus(optmodel, processes=1)\n\n    # build dataset\n    dataset = pyepo.data.dataset.optDataset(optmodel, x, c)\n    # get data loader\n    dataloader = DataLoader(dataset, batch_size=32, shuffle=True)\n\n    # training\n    num_epochs = 10\n    for epoch in range(num_epochs):\n        for data in dataloader:\n            x, c, w, z = data\n            # forward pass\n            cp = predmodel(x)\n            loss = spop(cp, c, w, z)\n            # backward pass\n            optimizer.zero_grad()\n            loss.backward()\n            optimizer.step()\n\n    # eval\n    regret = pyepo.metric.regret(predmodel, optmodel, dataloader)\n    print(\"Regret on Training Set: {:.4f}\".format(regret))\n\n```\n\n\n## Reference\n* [1] [Elmachtoub, A. N., & Grigas, P. (2021). Smart “predict, then optimize”. Management Science.](https:\u002F\u002Fdoi.org\u002F10.1287\u002Fmnsc.2020.3922)\n* [2] [Mandi, J., Stuckey, P. J., & Guns, T. (2020). Smart predict-and-optimize for hard combinatorial optimization problems. In Proceedings of the AAAI Conference on Artificial Intelligence.](https:\u002F\u002Fdoi.org\u002F10.1609\u002Faaai.v34i02.5521)\n* [3] [Vlastelica, M., Paulus, A., Musil, V., Martius, G., & Rolínek, M. (2019). Differentiation of blackbox combinatorial solvers. arXiv preprint arXiv:1912.02175.](https:\u002F\u002Farxiv.org\u002Fabs\u002F1912.02175)\n* [4] [Berthet, Q., Blondel, M., Teboul, O., Cuturi, M., Vert, J. P., & Bach, F. (2020). Learning with differentiable pertubed optimizers. Advances in neural information processing systems, 33, 9508-9519.](https:\u002F\u002Fpapers.nips.cc\u002Fpaper\u002F2020\u002Fhash\u002F6bb56208f672af0dd65451f869fedfd9-Abstract.html)\n* [5] [Mulamba, M., Mandi, J., Diligenti, M., Lombardi, M., Bucarey, V., & Guns, T. (2021). Contrastive losses and solution caching for predict-and-optimize. Proceedings of the Thirtieth International Joint Conference on Artificial Intelligence.](https:\u002F\u002Fwww.ijcai.org\u002Fproceedings\u002F2021\u002F390)\n* [6] [Mandi, J., Bucarey, V., Mulamba, M., & Guns, T. (2022). Decision-focused learning: through the lens of learning to rank. Proceedings of the 39th International Conference on Machine Learning.](https:\u002F\u002Fproceedings.mlr.press\u002Fv162\u002Fmandi22a.html)\n* [7] [Sahoo, S. S., Paulus, A., Vlastelica, M., Musil, V., Kuleshov, V., & Martius, G. (2022). Backpropagation through combinatorial algorithms: Identity with projection works. arXiv preprint arXiv:2205.15213.](https:\u002F\u002Farxiv.org\u002Fabs\u002F2205.15213)\n* [8] [Niepert, M., Minervini, P., & Franceschi, L. (2021). Implicit MLE: backpropagating through discrete exponential family distributions. Advances in Neural Information Processing Systems, 34, 14567-14579.](https:\u002F\u002Fproceedings.neurips.cc\u002Fpaper_files\u002Fpaper\u002F2021\u002Fhash\u002F7a430339c10c642c4b2251756fd1b484-Abstract.html)\n* [9] [Minervini, P., Franceschi, L., & Niepert, M. (2023, June). Adaptive perturbation-based gradient estimation for discrete latent variable models. In Proceedings of the AAAI Conference on Artificial Intelligence (Vol. 37, No. 8, pp. 9200-9208).](https:\u002F\u002Fojs.aaai.org\u002Findex.php\u002FAAAI\u002Farticle\u002Fview\u002F26103)\n* [10] [Schutte, N., Postek, K., & Yorke-Smith, N. (2023). Robust Losses for Decision-Focused Learning. arXiv preprint arXiv:2310.04328.](https:\u002F\u002Farxiv.org\u002Fabs\u002F2310.04328)\n* [11] [Gupta, V., & Huang, M. (2024). Decision-Focused Learning with Directional Gradients. Training, 50(100), 150.](https:\u002F\u002Farxiv.org\u002Fabs\u002F2402.03256)\n","# PyEPO：基于 PyTorch 的端到端预测-优化工具\n\n[![许可证：MIT](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FLicense-MIT-yellow.svg?style=flat-square)](https:\u002F\u002Fopensource.org\u002Flicenses\u002FMIT)\n[![GitHub 星标数](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Fstars\u002Fkhalil-research\u002FPyEPO?style=flat-square)](https:\u002F\u002Fgithub.com\u002Fkhalil-research\u002FPyEPO\u002Fstargazers)\n[![测试](https:\u002F\u002Fimg.shields.io\u002Fgithub\u002Factions\u002Fworkflow\u002Fstatus\u002Fkhalil-research\u002FPyEPO\u002Ftest.yml?branch=main&style=flat-square&label=tests)](https:\u002F\u002Fgithub.com\u002Fkhalil-research\u002FPyEPO\u002Factions\u002Fworkflows\u002Ftest.yml)\n[![Python](https:\u002F\u002Fimg.shields.io\u002Fpypi\u002Fpyversions\u002Fpyepo.svg?style=flat-square)](https:\u002F\u002Fpypi.org\u002Fproject\u002Fpyepo\u002F)\n![平台](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fplatform-Linux%20%7C%20macOS%20%7C%20Windows-lightgrey.svg?style=flat-square)\n[![PyPI 版本](https:\u002F\u002Fimg.shields.io\u002Fpypi\u002Fv\u002Fpyepo.svg?style=flat-square)](https:\u002F\u002Fpypi.org\u002Fproject\u002Fpyepo\u002F)\n[![PyPI 下载量](https:\u002F\u002Fimg.shields.io\u002Fpypi\u002Fdm\u002Fpyepo?style=flat-square)](https:\u002F\u002Fpepy.tech\u002Fproject\u002Fpyepo)\n[![Conda 版本](https:\u002F\u002Fimg.shields.io\u002Fconda\u002Fvn\u002Fpyepo\u002Fpyepo.svg?style=flat-square)](https:\u002F\u002Fanaconda.org\u002Fpyepo\u002Fpyepo)\n[![Conda 下载量](https:\u002F\u002Fimg.shields.io\u002Fconda\u002Fdn\u002Fpyepo\u002Fpyepo.svg?style=flat-square)](https:\u002F\u002Fanaconda.org\u002Fpyepo\u002Fpyepo)\n[![文档](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002Fdocs-online-green.svg?style=flat-square)](https:\u002F\u002Fkhalil-research.github.io\u002FPyEPO)\n[![论文](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FMPC-10.1007\u002Fs12532--024--00255--x-blue.svg?style=flat-square)](https:\u002F\u002Flink.springer.com\u002Farticle\u002F10.1007\u002Fs12532-024-00255-x)\n\n\u003Cp align=\"center\">\u003Cimg width=\"100%\" src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fkhalil-research_PyEPO_readme_d61071d7b84d.png\" \u002F>\u003C\u002Fp>\n\n\n## 学习框架\n\n\u003Cp align=\"center\">\u003Cimg width=\"100%\" src=\"https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fkhalil-research_PyEPO_readme_5da25559754a.png\" \u002F>\u003C\u002Fp>\n\n\n## 出版物\n\n本仓库是以下论文的官方实现：\n[PyEPO：用于线性和整数规划的基于 PyTorch 的端到端预测-优化库](https:\u002F\u002Flink.springer.com\u002Farticle\u002F10.1007\u002Fs12532-024-00255-x)（已被《数学规划计算》(MPC) 接收）\n\n引用：\n```\n@article{tang2024,\n  title={PyEPO: a PyTorch-based end-to-end predict-then-optimize library for linear and integer programming},\n  author={Tang, Bo and Khalil, Elias B},\n  journal={Mathematical Programming Computation},\n  issn={1867-2957},\n  doi={10.1007\u002Fs12532-024-00255-x},\n  year={2024},\n  month={July},\n  publisher={Springer}\n}\n```\n\n\n## 简介\n\n``PyEPO``（基于 PyTorch 的端到端预测-优化工具）是一款基于 Python 的开源软件，支持建模和求解具有线性目标函数的预测-优化问题。``PyEPO`` 的核心功能是利用 [GurobiPy](https:\u002F\u002Fwww.gurobi.com\u002F)、[COPT](https:\u002F\u002Fshanshu.ai\u002Fcopt)、[Pyomo](http:\u002F\u002Fwww.pyomo.org\u002F)、[Google OR-Tools](https:\u002F\u002Fdevelopers.google.com\u002Foptimization)、[MPAX](https:\u002F\u002Fgithub.com\u002FMIT-Lu-Lab\u002FMPAX) 或其他求解器与算法构建优化模型，然后将该优化模型嵌入人工神经网络中进行端到端训练。为此，``PyEPO`` 将多种方法实现为 [PyTorch](https:\u002F\u002Fpytorch.org\u002F) 自动微分模块。\n\n特别地，``PyEPO`` 集成了 [MPAX](https:\u002F\u002Fgithub.com\u002FMIT-Lu-Lab\u002FMPAX)，这是一款基于 JAX 的数学规划求解器，采用 PDHG（原始-对偶混合梯度）算法进行 GPU 加速优化。MPAX 为端到端训练带来了三大优势：(1) **GPU 原生求解** — 一阶 PDHG 方法本身具有并行性，可在 GPU 上高效运行；(2) **批量求解** — 整个 mini-batch 的优化实例可通过向量化在 GPU 上同时求解；以及 (3) **无需 GPU–CPU 数据传输开销** — 传统求解器（如 Gurobi）运行在 CPU 上，每次训练迭代都需要在 GPU 和 CPU 之间进行昂贵的数据传输，而 MPAX 则将神经网络和求解器都保留在 GPU 上，从而消除了这一瓶颈。\n\n\n## 文档\n\n``PyEPO`` 的官方文档可在 [https:\u002F\u002Fkhalil-research.github.io\u002FPyEPO](https:\u002F\u002Fkhalil-research.github.io\u002FPyEPO) 查看。\n\n## 幻灯片\n\n我们最近的教程是在 ACC 2024 大会上进行的。您可以通过此链接查看演讲幻灯片：[https:\u002F\u002Fgithub.com\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fslides\u002FPyEPO.pdf](https:\u002F\u002Fgithub.com\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fslides\u002FPyEPO.pdf)。\n\n## 教程\n\n- [![在 Colab 中打开](https:\u002F\u002Fcolab.research.google.com\u002Fassets\u002Fcolab-badge.svg)](https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fnotebooks\u002F01%20Optimization%20Model.ipynb)**01 优化模型：** 构建优化求解器\n- [![在 Colab 中打开](https:\u002F\u002Fcolab.research.google.com\u002Fassets\u002Fcolab-badge.svg)](https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fnotebooks\u002F02%20Optimization%20Dataset.ipynb)**02 优化数据集：** 生成合成数据并使用 optDataset\n- [![在 Colab 中打开](https:\u002F\u002Fcolab.research.google.com\u002Fassets\u002Fcolab-badge.svg)](https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fnotebooks\u002F03%20Training%20and%20Testing.ipynb)**03 训练与测试：** 训练和测试不同的方法\n- [![在 Colab 中打开](https:\u002F\u002Fcolab.research.google.com\u002Fassets\u002Fcolab-badge.svg)](https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fnotebooks\u002F04%202D%20knapsack%20Solution%20Visualization.ipynb)**04 二维背包问题解可视化：** 可视化背包问题的解\n- [![在 Colab 中打开](https:\u002F\u002Fcolab.research.google.com\u002Fassets\u002Fcolab-badge.svg)](https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fnotebooks\u002F05%20Warcraft%20Shortest%20Path.ipynb)**05 战术争霸最短路径：** 在 Warcraft 地形数据集上训练最短路径模型\n- [![在 Colab 中打开](https:\u002F\u002Fcolab.research.google.com\u002Fassets\u002Fcolab-badge.svg)](https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fnotebooks\u002F06%20Real-World%20Energy%20Scheduling.ipynb)**06 实际能源调度：** 将 PyEPO 应用于真实能源数据\n- [![在 Colab 中打开](https:\u002F\u002Fcolab.research.google.com\u002Fassets\u002Fcolab-badge.svg)](https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fnotebooks\u002F07%20kNN%20Robust%20Losses.ipynb)**07 kNN 鲁棒损失：** 使用 optDatasetKNN 进行鲁棒损失计算\n- [![在 Colab 中打开](https:\u002F\u002Fcolab.research.google.com\u002Fassets\u002Fcolab-badge.svg)](https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fnotebooks\u002F08%20Solving%20on%20MPAX%20with%20PDHG.ipynb)**08 使用 MPAX 和 PDHG 求解：** 使用 MPAX 进行 GPU 加速的批量求解\n\n\n## 实验\n\n要**复现原论文中的实验**，请使用此代码并按照该分支中的说明操作：[https:\u002F\u002Fgithub.com\u002Fkhalil-research\u002FPyEPO\u002Ftree\u002FMPC](https:\u002F\u002Fgithub.com\u002Fkhalil-research\u002FPyEPO\u002Ftree\u002FMPC)。请注意，该分支仍处于非常早期的版本阶段。\n\n## 功能\n\n- 实现 **SPO+** [[1]](https:\u002F\u002Fdoi.org\u002F10.1287\u002Fmnsc.2020.3922)、**DBB** [[3]](https:\u002F\u002Farxiv.org\u002Fabs\u002F1912.02175)、**NID** [[7]](https:\u002F\u002Farxiv.org\u002Fabs\u002F2205.15213)、**DPO** [[4]](https:\u002F\u002Fpapers.nips.cc\u002Fpaper\u002F2020\u002Fhash\u002F6bb56208f672af0dd65451f869fedfd9-Abstract.html)、**PFYL** [[4]](https:\u002F\u002Fpapers.nips.cc\u002Fpaper\u002F2020\u002Fhash\u002F6bb56208f672af0dd65451f869fedfd9-Abstract.html)、**NCE** [[5]](https:\u002F\u002Fwww.ijcai.org\u002Fproceedings\u002F2021\u002F390)、**LTR** [[6]](https:\u002F\u002Fproceedings.mlr.press\u002Fv162\u002Fmandi22a.html)、**I-MLE** [[8]](https:\u002F\u002Fproceedings.neurips.cc\u002Fpaper_files\u002Fpaper\u002F2021\u002Fhash\u002F7a430339c10c642c4b2251756fd1b484-Abstract.html)、**AI-MLE** [[9]](https:\u002F\u002Fojs.aaai.org\u002Findex.php\u002FAAAI\u002Farticle\u002Fview\u002F26103) 以及 **PG** [[11]](https:\u002F\u002Farxiv.org\u002Fabs\u002F2402.03256)。\n- 支持 [Gurobi](https:\u002F\u002Fwww.gurobi.com\u002F)、[COPT](https:\u002F\u002Fshanshu.ai\u002Fcopt)、[Pyomo](http:\u002F\u002Fwww.pyomo.org\u002F)、[Google OR-Tools](https:\u002F\u002Fdevelopers.google.com\u002Foptimization) 和 [MPAX](https:\u002F\u002Fgithub.com\u002FMIT-Lu-Lab\u002FMPAX) 的 API。\n- 支持优化求解器的并行计算。\n- 支持解缓存 [[5]](https:\u002F\u002Fwww.ijcai.org\u002Fproceedings\u002F2021\u002F390)，以加速训练。\n- 支持 kNN 稳健损失 [[10]](https:\u002F\u002Farxiv.org\u002Fabs\u002F2310.04328)，以提高决策质量。\n\n## 安装\n\n### 从本仓库克隆并安装\n\n您可以从我们的 GitHub 仓库下载 `PyEPO`。\n\n```bash\ngit clone -b main --depth 1 https:\u002F\u002Fgithub.com\u002Fkhalil-research\u002FPyEPO.git\n```\n\n然后进行安装：\n\n```bash\npip install PyEPO\u002Fpkg\u002F.\n```\n\n### 使用 pip 安装\n\n该软件包现已在 [PyPI](https:\u002F\u002Fpypi.org\u002Fproject\u002Fpyepo\u002F) 上架。您可以通过运行以下命令轻松使用 pip 安装 `PyEPO`：\n\n```bash\npip install pyepo\n```\n\n### 使用 conda 安装\n\n`PyEPO` 也已在 [Anaconda Cloud](https:\u002F\u002Fanaconda.org\u002Fpyepo\u002Fpyepo) 上发布。如果您更倾向于使用 conda 进行安装，可以使用以下命令安装 `PyEPO`：\n\n```bash\nconda install -c pyepo pyepo\n```\n\n\n## 依赖项\n\n* [NumPy](https:\u002F\u002Fnumpy.org\u002F)\n* [SciPy](https:\u002F\u002Fscipy.org\u002F)\n* [Pathos](https:\u002F\u002Fpathos.readthedocs.io\u002F)\n* [tqdm](https:\u002F\u002Ftqdm.github.io\u002F)\n* [Pyomo](http:\u002F\u002Fwww.pyomo.org\u002F)\n* [Gurobi](https:\u002F\u002Fwww.gurobi.com\u002F)\n* [Scikit Learn](https:\u002F\u002Fscikit-learn.org\u002F)\n* [PyTorch](http:\u002F\u002Fpytorch.org\u002F)\n\n\n## 示例代码\n\n```python\n#!\u002Fusr\u002Fbin\u002Fenv python\n# coding: utf-8\n\nimport gurobipy as gp\nfrom gurobipy import GRB\nimport numpy as np\nimport pyepo\nfrom pyepo.model.grb import optGrbModel\nimport torch\nfrom torch import nn\nfrom torch.utils.data import DataLoader\n\n\n# 优化模型\nclass myModel(optGrbModel):\n    def __init__(self, weights):\n        self.weights = np.array(weights)\n        self.num_item = len(weights[0])\n        super().__init__()\n\n    def _getModel(self):\n        # 创建模型\n        m = gp.Model()\n        # 变量\n        x = m.addVars(self.num_item, name=\"x\", vtype=GRB.BINARY)\n        # 目标函数方向\n        m.modelSense = GRB.MAXIMIZE\n        # 约束条件\n        m.addConstr(gp.quicksum([self.weights[0,i] * x[i] for i in range(self.num_item)]) \u003C= 7)\n        m.addConstr(gp.quicksum([self.weights[1,i] * x[i] for i in range(self.num_item)]) \u003C= 8)\n        m.addConstr(gp.quicksum([self.weights[2,i] * x[i] for i in range(self.num_item)]) \u003C= 9)\n        return m, x\n\n\n# 预测模型\nclass LinearRegression(nn.Module):\n\n    def __init__(self):\n        super(LinearRegression, self).__init__()\n        self.linear = nn.Linear(num_feat, num_item)\n\n    def forward(self, x):\n        out = self.linear(x)\n        return out\n\n\nif __name__ == \"__main__\":\n\n    # 生成数据\n    num_data = 1000 # 数据数量\n    num_feat = 5 # 特征维度\n    num_item = 10 # 项目数量\n    weights, x, c = pyepo.data.knapsack.genData(num_data, num_feat, num_item,\n                                                dim=3, deg=4, noise_width=0.5, seed=135)\n\n    # 初始化优化模型\n    optmodel = myModel(weights)\n\n    # 初始化预测模型\n    predmodel = LinearRegression()\n    # 设置优化器\n    optimizer = torch.optim.Adam(predmodel.parameters(), lr=1e-2)\n    # 初始化 SPO+ 损失函数\n    spop = pyepo.func.SPOPlus(optmodel, processes=1)\n\n    # 构建数据集\n    dataset = pyepo.data.dataset.optDataset(optmodel, x, c)\n    # 获取数据加载器\n    dataloader = DataLoader(dataset, batch_size=32, shuffle=True)\n\n    # 训练\n    num_epochs = 10\n    for epoch in range(num_epochs):\n        for data in dataloader:\n            x, c, w, z = data\n            # 前向传播\n            cp = predmodel(x)\n            loss = spop(cp, c, w, z)\n            # 反向传播\n            optimizer.zero_grad()\n            loss.backward()\n            optimizer.step()\n\n    # 评估\n    regret = pyepo.metric.regret(predmodel, optmodel, dataloader)\n    print(\"训练集上的遗憾值：{:.4f}\".format(regret))\n\n```\n\n## 参考文献\n* [1] [Elmachtoub, A. N., & Grigas, P. (2021). 智能“先预测、后优化”。管理科学。](https:\u002F\u002Fdoi.org\u002F10.1287\u002Fmnsc.2020.3922)\n* [2] [Mandi, J., Stuckey, P. J., & Guns, T. (2020). 面对困难组合优化问题的智能预测-优化方法。收录于AAAI人工智能会议论文集。](https:\u002F\u002Fdoi.org\u002F10.1609\u002Faaai.v34i02.5521)\n* [3] [Vlastelica, M., Paulus, A., Musil, V., Martius, G., & Rolínek, M. (2019). 黑盒组合求解器的差异化。arXiv预印本，arXiv:1912.02175。](https:\u002F\u002Farxiv.org\u002Fabs\u002F1912.02175)\n* [4] [Berthet, Q., Blondel, M., Teboul, O., Cuturi, M., Vert, J. P., & Bach, F. (2020). 基于可微扰动优化器的学习。神经信息处理系统进展，第33卷，页9508–9519。](https:\u002F\u002Fpapers.nips.cc\u002Fpaper\u002F2020\u002Fhash\u002F6bb56208f672af0dd65451f869fedfd9-Abstract.html)\n* [5] [Mulamba, M., Mandi, J., Diligenti, M., Lombardi, M., Bucarey, V., & Guns, T. (2021). 用于预测-优化的对比损失与解缓存技术。第三十届国际人工智能联合会议论文集。](https:\u002F\u002Fwww.ijcai.org\u002Fproceedings\u002F2021\u002F390)\n* [6] [Mandi, J., Bucarey, V., Mulamba, M., & Guns, T. (2022). 以决策为中心的学习：从排序学习的视角看。第三十九届国际机器学习会议论文集。](https:\u002F\u002Fproceedings.mlr.press\u002Fv162\u002Fmandi22a.html)\n* [7] [Sahoo, S. S., Paulus, A., Vlastelica, M., Musil, V., Kuleshov, V., & Martius, G. (2022). 通过组合算法进行反向传播：带投影的恒等映射有效。arXiv预印本，arXiv:2205.15213。](https:\u002F\u002Farxiv.org\u002Fabs\u002F2205.15213)\n* [8] [Niepert, M., Minervini, P., & Franceschi, L. (2021). 隐式最大似然估计：通过离散指数族分布进行反向传播。神经信息处理系统进展，第34卷，页14567–14579。](https:\u002F\u002Fproceedings.neurips.cc\u002Fpaper_files\u002Fpaper\u002F2021\u002Fhash\u002F7a430339c10c642c4b2251756fd1b484-Abstract.html)\n* [9] [Minervini, P., Franceschi, L., & Niepert, M. (2023年6月). 面向离散潜在变量模型的自适应扰动梯度估计。收录于AAAI人工智能会议论文集（第37卷，第8期，页9200–9208）。](https:\u002F\u002Fojs.aaai.org\u002Findex.php\u002FAAAI\u002Farticle\u002Fview\u002F26103)\n* [10] [Schutte, N., Postek, K., & Yorke-Smith, N. (2023). 用于以决策为中心学习的鲁棒损失函数。arXiv预印本，arXiv:2310.04328。](https:\u002F\u002Farxiv.org\u002Fabs\u002F2310.04328)\n* [11] [Gupta, V., & Huang, M. (2024). 基于方向梯度的以决策为中心的学习。培训，第50卷第100期，第150页。](https:\u002F\u002Farxiv.org\u002Fabs\u002F2402.03256)","# PyEPO 快速上手指南\n\nPyEPO 是一个基于 PyTorch 的端到端“预测后优化”（Predict-then-Optimize）工具库。它允许用户将线性或整数规划模型嵌入神经网络中，利用 Gurobi、COPT、OR-Tools 或 MPAX 等求解器进行端到端训练，特别支持 GPU 加速的批量求解。\n\n## 环境准备\n\n### 系统要求\n- **操作系统**：Linux, macOS, Windows\n- **Python 版本**：3.8 及以上\n\n### 前置依赖\n在使用 PyEPO 前，请确保已安装以下核心依赖：\n- **PyTorch**：深度学习框架\n- **求解器**（至少安装其一）：\n  - [Gurobi](https:\u002F\u002Fwww.gurobi.com\u002F) (需配置许可证)\n  - [COPT](https:\u002F\u002Fshanshu.ai\u002Fcopt) (杉数科技)\n  - [Google OR-Tools](https:\u002F\u002Fdevelopers.google.com\u002Foptimization)\n  - [MPAX](https:\u002F\u002Fgithub.com\u002FMIT-Lu-Lab\u002FMPAX) (基于 JAX，支持 GPU 加速)\n- **其他 Python 库**：NumPy, SciPy, Scikit-Learn, Pyomo, Pathos, tqdm\n\n> **提示**：若使用 Gurobi 或 COPT 商业求解器，请提前申请并配置好相应的 License。\n\n## 安装步骤\n\n你可以通过 pip 或 conda 直接安装稳定版，也可以从源码安装最新开发版。\n\n### 方式一：使用 pip 安装（推荐）\n```bash\npip install pyepo\n```\n*国内用户可使用清华源加速：*\n```bash\npip install pyepo -i https:\u002F\u002Fpypi.tuna.tsinghua.edu.cn\u002Fsimple\n```\n\n### 方式二：使用 conda 安装\n```bash\nconda install -c pyepo pyepo\n```\n\n### 方式三：从源码安装\n```bash\ngit clone -b main --depth 1 https:\u002F\u002Fgithub.com\u002Fkhalil-research\u002FPyEPO.git\npip install PyEPO\u002Fpkg\u002F.\n```\n\n## 基本使用\n\n以下示例演示了如何构建一个简单的背包问题优化模型，并结合线性回归神经网络，使用 **SPO+** 损失函数进行端到端训练。\n\n### 1. 导入依赖与定义模型\n```python\n#!\u002Fusr\u002Fbin\u002Fenv python\n# coding: utf-8\n\nimport gurobipy as gp\nfrom gurobipy import GRB\nimport numpy as np\nimport pyepo\nfrom pyepo.model.grb import optGrbModel\nimport torch\nfrom torch import nn\nfrom torch.utils.data import DataLoader\n\n# 定义优化模型 (继承 optGrbModel)\nclass myModel(optGrbModel):\n    def __init__(self, weights):\n        self.weights = np.array(weights)\n        self.num_item = len(weights[0])\n        super().__init__()\n\n    def _getModel(self):\n        m = gp.Model()\n        # 定义变量\n        x = m.addVars(self.num_item, name=\"x\", vtype=GRB.BINARY)\n        # 设置最大化目标\n        m.modelSense = GRB.MAXIMIZE\n        # 添加约束\n        m.addConstr(gp.quicksum([self.weights[0,i] * x[i] for i in range(self.num_item)]) \u003C= 7)\n        m.addConstr(gp.quicksum([self.weights[1,i] * x[i] for i in range(self.num_item)]) \u003C= 8)\n        m.addConstr(gp.quicksum([self.weights[2,i] * x[i] for i in range(self.num_item)]) \u003C= 9)\n        return m, x\n\n# 定义预测模型 (简单的线性回归)\nclass LinearRegression(nn.Module):\n    def __init__(self, num_feat, num_item):\n        super(LinearRegression, self).__init__()\n        self.linear = nn.Linear(num_feat, num_item)\n\n    def forward(self, x):\n        return self.linear(x)\n```\n\n### 2. 数据生成与初始化\n```python\nif __name__ == \"__main__\":\n    # 参数设置\n    num_data = 1000\n    num_feat = 5\n    num_item = 10\n    \n    # 生成合成数据 (背包问题)\n    weights, x, c = pyepo.data.knapsack.genData(num_data, num_feat, num_item,\n                                                dim=3, deg=4, noise_width=0.5, seed=135)\n\n    # 初始化优化模型和预测模型\n    optmodel = myModel(weights)\n    predmodel = LinearRegression(num_feat, num_item)\n    \n    # 设置优化器\n    optimizer = torch.optim.Adam(predmodel.parameters(), lr=1e-2)\n    \n    # 初始化 SPO+ 损失函数\n    spop = pyepo.func.SPOPlus(optmodel, processes=1)\n\n    # 构建数据集和数据加载器\n    dataset = pyepo.data.dataset.optDataset(optmodel, x, c)\n    dataloader = DataLoader(dataset, batch_size=32, shuffle=True)\n```\n\n### 3. 训练与评估\n```python\n    # 训练循环\n    num_epochs = 10\n    for epoch in range(num_epochs):\n        for data in dataloader:\n            x, c, w, z = data\n            # 前向传播\n            cp = predmodel(x)\n            loss = spop(cp, c, w, z)\n            \n            # 反向传播\n            optimizer.zero_grad()\n            loss.backward()\n            optimizer.step()\n\n    # 评估遗憾值 (Regret)\n    regret = pyepo.metric.regret(predmodel, optmodel, dataloader)\n    print(\"Regret on Training Set: {:.4f}\".format(regret))\n```\n\n运行上述代码即可完成一次完整的端到端训练流程。更多高级用法（如使用 MPAX GPU 加速、不同损失函数对比等）请参考官方文档或 Colab 教程。","某大型物流公司的算法团队正在构建智能调度系统，需要根据实时预测的路况和订单量，动态规划货车的最优配送路线以最小化总成本。\n\n### 没有 PyEPO 时\n- **流程割裂导致次优解**：预测模型（如神经网络）与运筹优化求解器（如 Gurobi）分步训练，预测目标仅为降低误差，忽略了最终决策质量，导致“预测很准但路线很贵”。\n- **训练效率低下**：传统求解器运行在 CPU 上，而深度学习在 GPU 上，每次迭代都需要频繁的 GPU-CPU 数据搬运，严重拖慢端到端训练速度。\n- **梯度传递受阻**：由于优化步骤不可微，无法将最终决策的损失直接反向传播给预测网络，只能依赖复杂的代理损失函数，调参难度极大。\n- **难以批量处理**：传统方法难以对迷你批次（Mini-batch）中的数百个调度场景进行并行求解，限制了模型从大规模数据中学习的能力。\n\n### 使用 PyEPO 后\n- **端到端联合优化**：PyEPO 将线性规划嵌入 PyTorch 计算图，直接以“最终调度成本”为损失函数训练预测网络，确保预测结果服务于最优决策。\n- **GPU 原生加速**：通过集成 MPAX 求解器，PyEPO 实现了纯 GPU 环境的推理与求解，消除了数据拷贝开销，训练吞吐量提升数倍。\n- **自动微分支持**：利用 PyTorch Autograd 机制，PyEPO 自动计算优化层关于预测参数的梯度，让模型能直观地学习如何修正预测以改善决策。\n- **高效批量求解**：借助向量化技术，PyEPO 可同时在 GPU 上并行求解整个批次的优化问题，大幅缩短模型收敛时间。\n\nPyEPO 的核心价值在于打破了预测与决策的壁垒，让 AI 模型不再盲目追求预测精度，而是直接为业务结果的最优化负责。","https:\u002F\u002Foss.gittoolsai.com\u002Fimages\u002Fkhalil-research_PyEPO_8605f8ab.png","khalil-research","https:\u002F\u002Foss.gittoolsai.com\u002Favatars\u002Fkhalil-research_0f86aa93.png",null,"https:\u002F\u002Fgithub.com\u002Fkhalil-research",[80,84],{"name":81,"color":82,"percentage":83},"Jupyter Notebook","#DA5B0B",94.5,{"name":85,"color":86,"percentage":87},"Python","#3572A5",5.5,648,85,"2026-03-30T07:20:05","MIT","Linux, macOS, Windows","非必需。基础功能依赖 CPU 求解器（如 Gurobi）；若使用 MPAX 进行 GPU 加速批量求解，则需支持 CUDA 的 NVIDIA GPU（具体型号和显存未说明）。","未说明",{"notes":96,"python":97,"dependencies":98},"该工具核心用于‘预测后优化’任务。默认支持多种求解器（Gurobi, COPT, Pyomo, Google OR-Tools），这些通常在 CPU 上运行。若需利用其集成的 MPAX 模块实现端到端的 GPU 加速训练（无数据拷贝开销），需额外配置 JAX 环境及对应的 GPU 支持。安装 Gurobi 需要单独的许可证。","未说明 (徽章显示支持多种版本，具体需参考 PyPI)",[99,100,101,102,103,104,105,106],"NumPy","SciPy","Pathos","tqdm","Pyomo","Gurobi","Scikit Learn","PyTorch",[13,54],"2026-03-27T02:49:30.150509","2026-04-06T06:51:51.633200",[111,116,121,126,131,136],{"id":112,"question_zh":113,"answer_zh":114,"source_url":115},13298,"SPO+ 和 DBB 函数只返回损失值，如何获取优化解（optimization solution）？","虽然 SPO+ 和 DBB 的前向传播主要返回损失值用于反向传播，但如果你需要在训练过程中显式计算优化解，可以直接利用 `optmodel` 对象。具体做法是在计算损失后，遍历预测的成本向量，调用 `optmodel.setObj()` 设置目标函数，然后使用 `optmodel.solve()` 求解。示例代码如下：\n\n```python\n# 训练循环中\nfor data in dataloader:\n    x, c, w, z = data\n    # 前向传播\n    cp = predmodel(x)\n    loss = spop(cp, c, w, z)\n    \n    # 使用 optmodel 获取解\n    sols = []\n    for cp_j in cp.to(\"cpu\").detach().numpy():\n        optmodel.setObj(cp_j)\n        sol, _ = optmodel.solve()\n        sols.append(sol)\n    \n    # 反向传播\n    optimizer.zero_grad()\n    loss.backward()\n    optimizer.step()\n```","https:\u002F\u002Fgithub.com\u002Fkhalil-research\u002FPyEPO\u002Fissues\u002F50",{"id":117,"question_zh":118,"answer_zh":119,"source_url":120},13299,"在代码中如何处理最小化（MINIMIZE）和最大化（MAXIMIZE）问题？两者的损失计算公式有何区别？","代码中的两个分支（if\u002Felif）并不是完全相同的表达式，它们在数学上等价，但符号约定不同，以分别处理最小化和最大化问题。\n\n- 对于 **最小化问题** (`EPO.MINIMIZE`)，损失计算通常为：`loss = - obj + 2 * dot(cp, w) - z`\n- 对于 **最大化问题** (`EPO.MAXIMIZE`)，损失计算通常为：`loss = obj - 2 * dot(cp, w) + z`\n\n两者的主要区别在于各项的正负号，这是为了确保梯度方向正确以优化对应的目标。请根据你实际问题的类型（最小化或最大化）选择对应的分支逻辑，不要混淆符号。","https:\u002F\u002Fgithub.com\u002Fkhalil-research\u002FPyEPO\u002Fissues\u002F60",{"id":122,"question_zh":123,"answer_zh":124,"source_url":125},13300,"PyEPO 是否支持 Apple Silicon (MPS) 后端？如果遇到错误该怎么办？","目前 PyEPO 尚未在 MPS (Metal Performance Shaders) 后端上进行过测试。理论上设备类型不应影响损失函数的数学计算，但用户报告在 MPS 设备上计算 regret 或损失时会出现错误。\n\n由于维护者目前没有 macOS 系统进行直接测试，建议遇到此问题的用户：\n1. 提供具体的错误信息（error messages）以便进一步排查。\n2. 暂时尝试在 CPU 或其他支持的后端（如 CUDA，如果可用）上运行代码。\n3. 如果可能，分享复现该问题的最小代码示例（如 Jupyter Notebook），以便社区协助调试。","https:\u002F\u002Fgithub.com\u002Fkhalil-research\u002FPyEPO\u002Fissues\u002F43",{"id":127,"question_zh":128,"answer_zh":129,"source_url":130},13301,"是否有投资组合优化（portfolio optimization）的示例代码或数据集？","是的，项目已经添加了投资组合优化的相关资源。你可以参考以下文件：\n1. **合成数据集**: `pkg\u002Fpyepo\u002Fdata\u002Fportfolio.py`\n2. **Gurobi 模型定义**: `pkg\u002Fpyepo\u002Fmodel\u002Fgrb\u002Fportfolio.py`\n\n这些文件提供了构建投资组合优化问题所需的数据生成器和模型接口，可以直接在项目中引用使用。","https:\u002F\u002Fgithub.com\u002Fkhalil-research\u002FPyEPO\u002Fissues\u002F6",{"id":132,"question_zh":133,"answer_zh":134,"source_url":135},13302,"哪里可以找到关于优化模型构建、数据集生成及训练测试的完整 Notebook 教程？","项目仓库中已更新了一系列详细的 Jupyter Notebook 教程，涵盖了从基础到进阶的完整流程：\n\n1. **01 Optimization Model.ipynb**: 演示如何构建优化求解器。\n2. **02 Optimization Dataset.ipynb**: 展示如何生成合成数据并使用 `optDataset`。\n3. **03 Training and Testing.ipynb**: 包含针对不同方法的端到端“预测后优化”（predict-then-optimize）的训练和测试流程。\n4. **04 2D knapsack Solution Visualization.ipynb**: 可视化背包问题的解。\n5. **05 Warcraft Shortest Path.ipynb**: 使用 Warcraft 地形数据集训练最短路径问题。\n\n建议在运行示例前仔细阅读这些 Notebook 中的注释和说明。","https:\u002F\u002Fgithub.com\u002Fkhalil-research\u002FPyEPO\u002Fissues\u002F2",{"id":137,"question_zh":138,"answer_zh":139,"source_url":135},13303,"运行最短路径（Shortest Path）Notebook 时提示缺少 `SciencePlots` 依赖怎么办？","如果在运行 Notebook 时遇到 `plt.style.use(\"science\")` 相关的错误，说明系统中缺少 `SciencePlots` 库。该库未自动列入核心依赖，需要手动安装。\n\n请使用以下命令安装：\n```bash\npip install scienceplots\n```\n安装完成后，即可正常加载科学绘图样式并运行笔记本书写代码。",[141,146,151,156,161,166,171,176,181,186,191,196,201,206,211,216,221],{"id":142,"version":143,"summary_zh":144,"released_at":145},71992,"v1.1.1","\u003Cp align=\"center\">\u003Cimg width=\"30%\" src=\"images\u002Flogo1.png\" \u002F>\u003C\u002Fp>\r\n\r\n###  :tada: 我们很高兴地宣布 PyEPO 1.1.1 版本发布。 :tada:\r\n\r\n## 新特性\r\n\r\n#### Bug 修复\r\n- 修复了数值稳定性问题：在梯度计算中添加了 epsilon 保护，以防止除零错误（代理模型、黑盒模型、扰动模型、排序模型）\r\n- 修复了 `adaptiveImplicitMLE` 的数值问题\r\n- 修复了 `optGRBModel` 中 `MVar` 的索引问题\r\n- 修复了 `solpool` 的设备传输问题\r\n- 修复了 COPT `solve()` 的返回值问题\r\n\r\n#### 测试\r\n- 添加了 CUDA 单元测试\r\n\r\n#### 文档\r\n- 更新了文档字符串的类型和描述\r\n","2026-02-11T08:47:06",{"id":147,"version":148,"summary_zh":149,"released_at":150},71993,"v1.1.0","\u003Cp align=\"center\">\u003Cimg width=\"30%\" src=\"images\u002Flogo1.png\" \u002F>\u003C\u002Fp>\n\n###  :tada: 我们很高兴地宣布 PyEPO 1.1.0 版本发布。 :tada:\n\n## 新特性\n\n#### Google OR-Tools 求解器后端\n- 新增 **Google OR-Tools** 作为新的求解器后端，支持 **pywraplp**（线性规划）和 **CP-SAT**（约束编程）求解器\n- 新的优化模型：`optOrtModel`、`optOrtCpModel`\n- 内置模型：`shortestPathModel`、`shortestPathCpModel`、`knapsackModel`、`knapsackModelRel`、`knapsackCpModel`\n\n#### 针对 COPT 和 Pyomo 的新模型\n- 为 COPT 和 Pyomo（OMO）新增 **投资组合** 优化模型\n- 为 COPT 和 Pyomo（OMO）新增 **TSP**（旅行商问题）模型\n\n## 改进\n\n#### 兼容性\n- 标准 **DLPack** 协议支持，以提升 JAX 中张量的互操作性（适用于 MPAX）\n\n#### Bug 修复\n- 修复了由于 JAX 中过时的 JIT 缓存导致 `addConstr` 忽略新约束的问题（适用于 MPAX）","2026-02-10T00:40:58",{"id":152,"version":153,"summary_zh":154,"released_at":155},71994,"v1.0.5","\u003Cp align=\"center\">\u003Cimg width=\"30%\" src=\"images\u002Flogo1.png\" \u002F>\u003C\u002Fp>\r\n\r\n###  :tada: 我们很高兴地宣布 PyEPO 1.0.5 版本发布。 :tada:\r\n\r\n### 变更内容\r\n\r\n#### Bug 修复\r\n- 修复：在 KNN 数据集中排除自身\r\n\r\n#### 重构与性能优化\r\n- 将解池管理集中到 `utils.py` 中的独立函数\r\n- 将 `_solve_in_pass` 拆分为 `_solve_in_pass`（包含解池更新）和 `_solve_batch`（纯求解器）\r\n- 优化了解池去重的哈希处理（使用 `tobytes()` 替代 `tuple\u002Ftolist`）\r\n- 将设备检查统一到求解\u002F缓存工具函数中\r\n- 清理了各模块中未使用的 `device` 变量","2026-02-09T20:42:31",{"id":157,"version":158,"summary_zh":159,"released_at":160},71995,"v1.0.4","\u003Cp align=\"center\">\u003Cimg width=\"30%\" src=\"images\u002Flogo1.png\" \u002F>\u003C\u002Fp>\n\n###  :tada: 我们很高兴地宣布 PyEPO 1.0.4 版本发布。 :tada:\n\n#### 性能优化\n- 在工作进程中缓存优化模型，以避免在并行求解过程中重复构建模型\n- 对 _getKNN 进行向量化处理，用批量矩阵运算替代 Python 层面的循环\n- 使用哈希集合去重替换 torch.unique，用于更新解池\n- 在解池中加入设备感知检查，优化张量转换\n- 在 optDataset \u002F optDatasetKNN 中预先将数据集数组转换为张量\n\n#### 错误修复\n- 修复在未安装 Pyomo 时 omo 模块中的 NameError 问题\n- 修复使用 GPU 张量时解池设备不匹配的问题\n- 修复隐式最大似然估计中 sigma 参数的处理问题\n- 修复包导入错误\n\n#### 兼容性\n- 更新 autograd.Function 为类方法 .apply() 模式，以应对 PyTorch >= 2.1 的弃用\n\n#### 测试与 CI\n- 添加单元测试套件：test_data、test_model、test_metric、test_func、test_utils、test_integration\n- 添加 GitHub Actions CI，支持 Python 3.9 – 3.14\n- 支持对依赖 Gurobi \u002F Pyomo 的测试进行优雅跳过\n\n#### 文档\n- 修复文档字符串中的拼写和语法错误","2026-02-09T04:13:17",{"id":162,"version":163,"summary_zh":164,"released_at":165},71996,"v1.0.0","\u003Cp align=\"center\">\u003Cimg width=\"30%\" src=\"images\u002Flogo1.png\" \u002F>\u003C\u002Fp>\n\n###  :tada: 我们很高兴地宣布 PyEPO 1.0.0 版本正式发布。 :tada:\n\n我们非常激动地宣布，PyEPO 现已支持 [`MPAX`](https:\u002F\u002Fgithub.com\u002FMIT-Lu-Lab\u002FMPAX)，这是一个基于 PDHG 的优化框架。`MPAX` 支持在 CPU 或 GPU 上进行批处理线性规划，并利用 `JIT` 编译技术实现更快的执行速度和更强的可扩展性。与传统求解器不同，`MPAX` 可以完全在 GPU 上运行，从而避免了训练过程中昂贵的 CPU-GPU 通信开销。\n\n总体而言，`MPAX` 在求解大规模优化问题时表现出极高的效率。要了解它的实际应用，请查看我们的 [Jupyter Notebook 教程](https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fnotebooks\u002F08%20Solving%20on%20MPAX%20with%20PDHG.ipynb)。\n\n#### PyEPO 1.0.0 的其他更新\n\n- **进一步的计算向量化：** 去除了不必要的 `for` 循环，提升了训练效率。\n- **扰动算法的错误修复：** 解决了 `perturbedOpt`、`perturbedFenchelYoung`、`implicitMLE` 和 `adaptiveImplicitMLE` 中的解缓存问题。\n\n我们热切期待您试用这些新功能，并与我们分享您的反馈。一如既往，感谢您加入我们不断壮大的社区！","2025-03-06T01:05:11",{"id":167,"version":168,"summary_zh":169,"released_at":170},71997,"v0.4.0","\u003Cp align=\"center\">\u003Cimg width=\"30%\" src=\"images\u002Flogo1.png\" \u002F>\u003C\u002Fp>\n\n###  :tada: 我们很高兴地宣布 PyEPO 0.4.0 版本正式发布。 :tada:\n\n节日快乐！我们非常激动地在本次发布中为大家带来一项令人振奋的新功能：\n\n我们很高兴地宣布新增了一个名为 `perturbationGradient` 的模块，该模块用于实现 **扰动梯度**（Perturbation Gradient, PG）损失。此模块为各类优化任务提供了灵活性，支持对 `sigma`（步长）和 `two_sides`（差分类型）等参数进行配置。\n\n该功能基于论文《基于方向梯度的决策导向学习》（[Decision-Focused Learning with Directional Gradients](https:\u002F\u002Farxiv.org\u002Fabs\u002F2402.03256)）。它是一种目标值的代理损失函数，能够衡量优化问题的决策质量。根据丹斯金定理，扰动梯度损失是通过不同的零阶近似推导而来的，并且具有信息丰富的梯度。因此，我们可以基于随机梯度下降法设计相应的算法。\n\n此外，感谢 @RuoyuChen615 提供了她版本的扰动梯度损失实现。她的实现为我们提供了宝贵的见解，帮助我们进一步完善和优化这一模块。\n\n我们热切期待您试用这些新功能，并与我们分享您的反馈。一如既往，感谢您一直以来对我们不断壮大的社区的支持！","2024-12-20T23:41:34",{"id":172,"version":173,"summary_zh":174,"released_at":175},71998,"v0.3.9","\u003Cp align=\"center\">\u003Cimg width=\"30%\" src=\"images\u002Flogo1.png\" \u002F>\u003C\u002Fp>\n\n###  :tada: 我们很高兴地宣布 PyEPO 0.3.9 版本正式发布。 :tada:\n\n在本次发布中，我们非常激动地为大家带来一项令人振奋的新功能：\n\n我们很高兴地宣布，新增了一个名为 `optDatasetKNN` 的模块，这要特别感谢 @NoahJSchutte 的贡献。该模块专为决策导向学习中的 k 最近邻（kNN）鲁棒损失函数而设计。实现中，在 `dataset.py` 文件中引入了一个新的类 `optDatasetKNN`，并提供了 *k* 和 *weight* 两个参数。\n\n这一功能基于 Noah Schutte 发表的论文《Robust Losses for Decision-Focused Learning》（已收录于 IJCAI），您可以通过我们的 [Google Colab 教程](https:\u002F\u002Fcolab.research.google.com\u002Fgithub\u002Fkhalil-research\u002FPyEPO\u002Fblob\u002Fmain\u002Fnotebooks\u002F06%20kNN%20Robust%20Losses.ipynb) 获得动手实践指导。\n\n我们热切期待您试用这些新功能，并与我们分享您的宝贵反馈。一如既往，感谢您一直以来对我们不断壮大的社区的支持！","2024-06-11T01:22:55",{"id":177,"version":178,"summary_zh":179,"released_at":180},71999,"v0.3.8a","\u003Cp align=\"center\">\u003Cimg width=\"30%\" src=\"images\u002Flogo1.png\" \u002F>\u003C\u002Fp>\r\n\r\n###  :tada: 我们很高兴地宣布 PyEPO 0.3.8a 版本发布。 :tada:\r\n\r\n我们在使用多进程时修复了 `portfolio.py` 中的一个 bug。","2024-05-20T21:31:19",{"id":182,"version":183,"summary_zh":184,"released_at":185},72000,"v0.3.8","\u003Cp align=\"center\">\u003Cimg width=\"30%\" src=\"images\u002Flogo1.png\" \u002F>\u003C\u002Fp>\n\n###  :tada: 我们很高兴地宣布 PyEPO 0.3.8 版本正式发布。 :tada:\n\n我们非常激动地向大家介绍本次版本中的一些令人振奋的新特性：\n\n我们新增了一个用于投资组合优化的数据生成器 `pyepo.data.portfolio.genData`，以及相应的 Gurobi 模型 `pyepo.model.grb.portfolioModel`。详细信息请参阅我们的文档中的[数据](https:\u002F\u002Fkhalil-research.github.io\u002FPyEPO\u002Fbuild\u002Fhtml\u002Fcontent\u002Fexamples\u002Fdata.html#portfolio)和[优化模型](https:\u002F\u002Fkhalil-research.github.io\u002FPyEPO\u002Fbuild\u002Fhtml\u002Fcontent\u002Fexamples\u002Fmodel.html#portfolio)部分。\n\n该合成数据集源自 Smart 的“先预测、后优化”方法 [《管理科学》2020年第66卷第1期，第47–65页](https:\u002F\u002Fpubsonline.informs.org\u002Fdoi\u002Fabs\u002F10.1287\u002Fmnsc.2020.3922)，其详细的实现指南见附录D，位于[补充材料](https:\u002F\u002Fpubsonline.informs.org\u002Fdoi\u002Fsuppl\u002F10.1287\u002Fmnsc.2020.3922\u002Fsuppl_file\u002Fmnsc.2020.3922.sm2.pdf)中。\n\n此外，我们还修复了若干小 bug，以确保更加流畅的用户体验。\n\n我们热切期待您试用这些新功能，并与我们分享您的宝贵反馈。一如既往，感谢您一直以来对我们不断壮大的社区的支持！","2024-04-24T20:56:31",{"id":187,"version":188,"summary_zh":189,"released_at":190},72001,"v0.3.7","\u003Cp align=\"center\">\u003Cimg width=\"30%\" src=\"images\u002Flogo1.png\" \u002F>\u003C\u002Fp>\n\n###  :tada: 我们很高兴地宣布 PyEPO 0.3.7 版本正式发布。 :tada:\n\n我们非常激动地向大家介绍本次发布中的一些令人振奋的新特性：\n\n我们新增了一个自动微分模块 `pyepo.func.adaptiveImplicitMLE`，该模块基于扰动-最大后验框架，能够自适应地选择插值步长。此模块从伽玛分布之和中采样噪声扰动，进而对损失函数进行插值，以获得更为精确的有限差分近似。相关论文为《基于自适应扰动的离散潜在变量模型梯度估计》（[Adaptive Perturbation-Based Gradient Estimation for Discrete Latent Variable Models](https:\u002F\u002Fojs.aaai.org\u002Findex.php\u002FAAAI\u002Farticle\u002Fview\u002F26103)）。更多详细信息请参阅我们的[文档](https:\u002F\u002Fkhalil-research.github.io\u002FPyEPO\u002Fbuild\u002Fhtml\u002Fcontent\u002Fexamples\u002Ffunction.html#adaptive-implicit-maximum-likelihood-estimator-ai-mle)。\n\n我们热切期待您试用这些新功能，并与我们分享您的反馈。一如既往，感谢您加入我们不断壮大的社区！","2024-04-19T05:03:10",{"id":192,"version":193,"summary_zh":194,"released_at":195},72002,"v0.3.6","\u003Cp align=\"center\">\u003Cimg width=\"30%\" src=\"images\u002Flogo1.png\" \u002F>\u003C\u002Fp>\r\n\r\n###  :tada: We're happy to announce the PyEPO 0.3.6 release on PyPI. :tada:\r\n\r\nThe package is now available on [PyPI](https:\u002F\u002Fpypi.org\u002Fproject\u002Fpyepo\u002F) for installation. You can easily install `PyEPO` using pip by running the following command:\r\n\r\n```bash\r\npip install pyepo\r\n```","2024-02-14T03:59:27",{"id":197,"version":198,"summary_zh":199,"released_at":200},72003,"v0.3.5","\u003Cp align=\"center\">\u003Cimg width=\"30%\" src=\"images\u002Flogo1.png\" \u002F>\u003C\u002Fp>\r\n\r\n###  :tada: We're happy to announce the PyEPO  0.3.5 release. :tada:\r\n\r\nWe're thrilled to bring you some exciting new features in this release:\r\n\r\n- We add an autograd module `pyepo.func.implicitMLE`,  which uses the perturb-and-MAP framework. This module samples noise perturbation from a Sum-of-Gamma distribution, subsequently interpolating the loss function for a more precise finite difference approximation.  There is the corresponding paper [Implicit MLE: Backpropagating Through Discrete Exponential Family Distributions](https:\u002F\u002Fproceedings.neurips.cc\u002Fpaper_files\u002Fpaper\u002F2021\u002Fhash\u002F7a430339c10c642c4b2251756fd1b484-Abstract.html). See details in our [docs](https:\u002F\u002Fkhalil-research.github.io\u002FPyEPO\u002Fbuild\u002Fhtml\u002Fcontent\u002Fexamples\u002Ffunction.html#implicit-maximum-likelihood-estimator-i-mle).\r\n- PyEPO is now compatible with [COPT](https:\u002F\u002Fshanshu.ai\u002Fcopt) (Cardinal Optimizer) API, one of the fastest solvers for various optimization problems.\r\n\r\nWe're eager for you to test these out and share your feedback with us. As always, thank you for being a part of our growing community!","2023-10-21T16:48:42",{"id":202,"version":203,"summary_zh":204,"released_at":205},72004,"v0.3.3","\u003Cp align=\"center\">\u003Cimg width=\"30%\" src=\"images\u002Flogo1.png\" \u002F>\u003C\u002Fp>\r\n\r\nWe're happy to announce the 0.3.3 release.\r\n\r\nWe fix the sign bug of `pyepo.func.NCE`, and add modules `pyepo.func.contrastiveMAP` and `pyepo.func.negativeIdentity`.  See details in our [docs](https:\u002F\u002Fkhalil-research.github.io\u002FPyEPO\u002Fbuild\u002Fhtml\u002Fcontent\u002Fexamples\u002Ffunction.html#noise-contrastive-estimation-nce).\r\n\r\nThere are the corresponding papers [Contrastive losses and solution caching for predict-and-optimize](https:\u002F\u002Fwww.ijcai.org\u002Fproceedings\u002F2021\u002F390) and [Backpropagation through combinatorial algorithms: Identity with projection works](https:\u002F\u002Farxiv.org\u002Fabs\u002F2205.15213).","2023-07-17T06:43:23",{"id":207,"version":208,"summary_zh":209,"released_at":210},72005,"v0.3.0","\u003Cp align=\"center\">\u003Cimg width=\"30%\" src=\"images\u002Flogo1.png\" \u002F>\u003C\u002Fp>\r\n\r\nWe're happy to announce the 0.3.0 release.\r\n\r\nThank @ijskar to add new end-to-end predict-then-optimize methods: noise contrastive estimation and learning to rank. We add modules `pyepo.func.NCE`,  `pyepo.func.pointwiseLTR`, `pyepo.func.pairwiseLTR` and `pyepo.func.listwiseLTR`. See details in our [docs](https:\u002F\u002Fkhalil-research.github.io\u002FPyEPO\u002Fbuild\u002Fhtml\u002Fcontent\u002Fexamples\u002Ffunction.html#noise-contrastive-estimation-nce).\r\n\r\nThere are the corresponding papers [Contrastive losses and solution caching for predict-and-optimize](https:\u002F\u002Fwww.ijcai.org\u002Fproceedings\u002F2021\u002F390) and [Decision-focused learning: through the lens of learning to rank](https:\u002F\u002Fproceedings.mlr.press\u002Fv162\u002Fmandi22a.html).","2023-07-10T07:47:44",{"id":212,"version":213,"summary_zh":214,"released_at":215},72006,"v0.2.4","\u003Cp align=\"center\">\u003Cimg width=\"30%\" src=\"images\u002Flogo1.png\" \u002F>\u003C\u002Fp>\r\n\r\nWe're happy to announce the 0.2.4 release.\r\n\r\nThis new version includes several bug fixes and improvements that should enhance the stability and usability of the package.","2023-03-15T04:49:36",{"id":217,"version":218,"summary_zh":219,"released_at":220},72007,"v0.2.0","\u003Cp align=\"center\">\u003Cimg width=\"30%\" src=\"images\u002Flogo1.png\" \u002F>\u003C\u002Fp>\r\n\r\nWe're happy to announce the 0.2.0 release.\r\n\r\nWe add two end-to-end predict-then-optimize methods with stochastical perturbation: Differentiable Perturbed Optimizers and Fenchel-Young loss with Perturbation into our package \"PyEPO.\"\r\n\r\nPeople now are allowed to use PyTorch module `pyepo.func.perturbedOpt` and `pyepo.func.perturbedFenchelYoung`. See details in our [docs](https:\u002F\u002Fkhalil-research.github.io\u002FPyEPO\u002Fbuild\u002Fhtml\u002Fcontent\u002Fexamples\u002Ffunction.html#differentiable-perturbed-optimizer-dpo).\r\n\r\nBoth approaches come from Google Research's awesome project [Differentiable Optimizers with Perturbations in Tensorflow](https:\u002F\u002Fgithub.com\u002Fgoogle-research\u002Fgoogle-research\u002Ftree\u002Fmaster\u002Fperturbations), and there is the corresponding paper [Learning with differentiable perturbed optimizers](https:\u002F\u002Fpapers.nips.cc\u002Fpaper\u002F2020\u002Fhash\u002F6bb56208f672af0dd65451f869fedfd9-Abstract.html).","2022-10-06T23:15:48",{"id":222,"version":223,"summary_zh":224,"released_at":225},72008,"v0.1.0","We're happy to announce the 0.1.0 release.\r\nIt's the first release version of \"PyEPO\".\r\n","2022-10-05T17:30:49"]