Files
MCM-ICM_Toolkit/docs/04-environment.md
T
guzhujushi 5319589dfd chore: 初始化 MCM/ICM Toolkit 仓库骨架
审查并精简 ChatGPT 的建库建议后落地的第一版骨架,只定接口不写实现。

- 建议审查:14 个包 → 7 个;约 250 个函数 → 约 40 个;5 个 Result 类 → 1 个
  (docs/01-suggestion-review.md)
- docs/:架构、路线图(含永久不做清单)、环境、Git 工作流、函数卡片模板
- src/mcm_toolkit/:core / data / stats / models / solve / decision / viz
  共 23 个模块,均为签名 + docstring + NotImplementedError
- tests/:9 个文件,其中 test_api_surface.py 已通过(20 passed)
- examples/ problems/ notebooks/ figures/ tables/ 骨架
- pyproject.toml(核心依赖 4 个 + 6 组 extras)、environment.yml
- scripts/:setup-venv.ps1(ASCII + LF)、setup-conda.ps1、doctor.ps1
- 环境:.venv(system-site-packages)与 conda 环境 mcm-toolkit 均已建好,
  数值栈版本与 base 完全对齐(numpy 2.4.6 / scipy 1.18.1 / pandas 3.0.6,MKL 后端)
2026-10-01 17:43:48 +08:00

9.3 KiB
Raw Blame History

环境配置

记录本机(Windows / PowerShell)上 conda 与 venv 两套环境的实际配置方式、 实测数据、以及踩过的坑。相关脚本在 scripts/。

状态:两套环境均已建好、版本已对齐、验证通过(2026-10-01)。


一、结论速查

venv conda env
路径 D:\MCM&ICM_Toolkit\.venv D:\anaconda\envs\mcm-toolkit
解释器 Anaconda base,Python 3.13.9 Python 3.13.15
占用 10.5 MB 1.55 GB(+ 共用 pkgs 缓存)
来源 --system-site-packages 复用 base conda 从 defaults 通道安装
用途 轻量开发 / 离线兜底 跑题主力环境
缺什么 SALib、pymoo、pyright 无缺口

两套的数值计算栈已完全一致(见 §5),只差 Python 补丁号。可以放心在两套之间切换。


二、venv(轻量、离线可用)

D:\anaconda\python.exe -m venv --system-site-packages --prompt "mcm-toolkit" .venv
.venv\Scripts\python.exe -m pip install -e . --no-deps --no-build-isolation

一键:./scripts/setup-venv.ps1

为什么用 --system-site-packages

让 venv 直接复用 Anaconda base 里已有的包,零下载就有可用的科学栈, 而且只有 10.5 MB,可以安心放在项目目录里。

已验证可导入(版本随 base 走,2026-10-01 base 升级后为):

text numpy 2.4.6 scipy 1.18.1 pandas 3.0.6 matplotlib 3.11.2 scikit-learn 1.9.1 statsmodels 0.15.0 networkx 3.6.1 sympy 1.14.0

--no-deps --no-build-isolation 是必须的

  • --no-deps:依赖已由 base 提供,不必联网解析;
  • --no-build-isolation:否则 pip 会新建隔离环境去下载 setuptools 构建后端。

三、conda 环境 mcm-toolkit(跑题主力)

# 一键(推荐)
.\scripts\setup-conda.ps1

# 等价的手工命令
$env:CONDA_PLUGINS_AUTO_ACCEPT_TOS = 'yes'   # 见 §4 坑 1
conda create -n mcm-toolkit -y python=3.13 ^
    numpy scipy pandas matplotlib scikit-learn statsmodels ^
    networkx sympy openpyxl pytest ruff pip

实测:约 14.5 分钟(868 秒),下载约 3 GB,环境本体 1.55 GB。

建完后补装 pip-only 的依赖并安装本项目:

$py = 'D:\anaconda\envs\mcm-toolkit\python.exe'
& $py -m pip install SALib pymoo pyright
& $py -m pip install -e . --no-deps --no-build-isolation

这些 setup-conda.ps1 已全部自动完成。

为什么不推荐 --clone base

原以为 conda create -n X --clone base 是"本地复制、秒级完成、不用下载"。 实测不是。 在 conda 25.11 上它会重放 base 的完整包列表并逐个下载安装 (连 pandoc、m2-msys2-runtime、anaconda-navigator 这些都用不上的也照下), 跑 253 秒才下完约 2 GB 就已被中止,按比例算远慢于精准列表。

所以 setup-conda.ps1 的默认路径是精准包列表;-CloneBase 只在你确实想 要一份 base 的完整副本时才用。

断网怎么办

提前建好环境,并保留 D:\anaconda\pkgs 缓存(现在 8.4 GB)。 包已在缓存里时 conda create --offline 才能工作;否则会失败。 比赛现场不要指望临时建环境,走 venv(它 100% 离线可用)。


四、踩过的坑

坑 1 —— Anaconda ToS 插件要联网。 Anaconda 25.x 自带 conda_anaconda_tos 插件,任何 create/install 之前都会去 repo.anaconda.com 拉 ToS 元数据。断网时它不是报"没网",而是抛一长串 traceback。

$env:CONDA_PLUGINS_AUTO_ACCEPT_TOS = 'yes'     # 推荐:跳过联网,保留 libmamba 求解器
conda --no-plugins create ...                  # 彻底关插件(退化成经典求解器,慢)

坑 2 —— envs_dirs / pkgs_dirs 必须可写。 不可写时报 NotWritableError 或 Error encountered while attempting to create cache directory。排查:

conda info --json | Select-String "envs_dirs","pkgs_dirs"
conda config --show envs_dirs pkgs_dirs

坑 3 —— 被中止的 conda create 用 conda env remove 删不干净。 本次中止后 conda env remove -n mcm-toolkit -y 跑完,D:\anaconda\envs\mcm-toolkit 仍然存在且 conda env list 里已看不到它。要手工删目录:

Remove-Item -LiteralPath 'D:\anaconda\envs\mcm-toolkit' -Recurse -Force

坑 4 —— 别把 conda env 建在项目目录里。 conda create -p ./.conda 会把 GB 级目录放进仓库,脏 .gitignore 也容易误提交。

坑 5 —— 版本漂移。 本机 base 是 2025-10 装的,defaults 通道已是 2026-10 的版本,于是新建的 conda 环境拿到的是更新的版本(pandas 从 2.3.3 跳到 3.0.6,是 major 升级)。 见 §5,写代码时注意别依赖两套环境都有的行为。


五、两套环境的实际版本(已对齐)

2026-10-01 已把 base 从 Anaconda 2025.12 升到 2026.07,两套环境版本已对齐。

包 venv(继承 base) conda mcm-toolkit
Python 3.13.9 3.13.15 补丁号,可忽略
numpy 2.4.6 2.4.6 ✅ 一致
scipy 1.18.1 1.18.1 ✅ 一致(连 build 号都相同)
pandas 3.0.6 3.0.6 ✅ 一致
matplotlib 3.11.2 3.11.2 ✅ 一致
scikit-learn 1.9.1 1.9.1 ✅ 一致
statsmodels 0.15.0 0.15.0 ✅ 一致
networkx 3.6.1 3.6.1 ✅ 一致
sympy 1.14.0 1.14.0 ✅ 一致
pytest 9.1.1 9.1.1 ✅ 一致
SALib / pymoo / pyright 缺失 已装 venv 本来就只做轻量开发
BLAS 后端 MKL MKL ✅ 一致

base 升级记录

[FENCE]powershell conda update -n base --all -y # 365 个包更新,下载 638 MB,耗时 1033 秒 conda install -n mcm-toolkit numpy=2.4.6 -y # 把项目环境对齐到 base 的 numpy [FENCE]

  • conda 本身从 25.11.1 升到 26.7.3。
  • 升级前 conda list -n base --revisions 里已留有 revision 记录,可回滚: conda install -n base --revision <N>。
  • 踩过的坑:base 想装 numpy=2.5.3 时求解器会顺手把 BLAS 从 MKL 换成 OpenBLAS (_anaconda_depends 2026.07 ..._mkl_1 → ..._openblas_1、blas 1.0-mkl → 1.0-openblas)。 _anaconda_depends 把 base 的 numpy 钉在 2.4.6,硬升会牵动整套线性代数后端, 所以选择把项目环境的 numpy 降到 2.4.6 来对齐,而不是动 base。
  • 升级期间遇到 repo.anaconda.com 读超时(默认 9.15 秒太短),已把 remote_read_timeout_secs 调到 120、remote_connect_timeout_secs 调到 30、 remote_max_retries 调到 5。这几项写在 ~/.condarc 里。

六、国内镜像(需要装新包时)

conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main
conda config --set show_channel_urls yes

# pip(对 venv 和 conda 环境都生效)
python -m pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

本机当前通过 http://127.0.0.1:7993 的 UniClash 代理直连,未配镜像。镜像只影响下载, 不影响坑 1 的 ToS 行为。


七、可选依赖

核心 4 个包(numpy scipy pandas matplotlib)两套环境都有。其余按需:

python -m pip install -e ".[ml]"            # sklearn statsmodels  已有
python -m pip install -e ".[graph]"         # networkx            已有
python -m pip install -e ".[sensitivity]"   # SALib               conda 环境已有
python -m pip install -e ".[symbolic]"      # sympy               已有
python -m pip install -e ".[moo]"           # pymoo               conda 环境已有
python -m pip install -e ".[excel]"         # openpyxl            已有
python -m pip install -e ".[dev]"           # pytest ruff pyright

缺依赖时对应函数应当给出可读的安装提示,而不是裸抛 ImportError (写成约定,见 docs/02-architecture.md §4.6)。


八、脚本的编码约定(踩过的坑)

scripts/ 下的 .ps1 必须是纯 ASCII + UTF-8 无 BOM + LF。

原因是 Windows PowerShell 5.1 在没有 BOM 时按 ANSI(本机 GBK)解析 .ps1, 中文注释和中文消息会被拆成非法字节,报出来的却是一堆莫名其妙的 Missing closing '}' in statement block / The string is missing the terminator。 (实测:带中文的 doctor.ps1 直接语法错误;改成纯 ASCII 后立刻正常。)

两种可行方案,本项目选了第二种:

  1. 保留中文 → 必须存成 UTF-8 with BOM(违反 AGENTS.md 的"无 BOM"约定);
  2. 纯 ASCII,注释与输出用英文 → 符合 AGENTS.md,且任何编码下都能解析。← 采用

另一个相关的坑:PowerShell 5.1 向原生程序传参时会吃掉双引号, 所以 doctor.ps1 里传给 python -c 的探测代码只能用单引号字符串。


九、已知的沙箱相关现象

如果在受限环境(文件系统只读 / 无网络)里跑 matplotlib,会看到:

Matplotlib created a temporary cache directory at ... because there was an issue with
the default path (C:\Users\guzhu\.matplotlib)

这不是配置问题,是 ~\.matplotlib 不可写。正常终端里不会出现; 真遇到时设置 MPLCONFIGDIR 指向可写目录即可:

$env:MPLCONFIGDIR = "$env:TEMP\matplotlib"