距离 Kotlin 版首发过去了三个月。这三个月里改动最大的其实不是界面,而是三件“地基”上的事:包名、数据库格式,以及规划求解的算法。这篇把 1.0.1 的变化一次说清楚。

包名迁移:等于换了一个应用

Android 用 applicationId 识别应用,所以包名从旧版 com.formulamanager 改成 cn.formulamanager.formulamanager 之后,系统会把它当成一个全新的 App:新包可以和旧包并存,但旧包的应用私有数据不会自动迁移。

要带走公式库,只有两条路:在旧版里「导出数据库」,再到新版里「导入数据库」;或者直接把 .db 文件复制出来导入。公式库、方案库都是独立文件,与包名无关,这一步不会丢数据。

顺带一提:改包名之后一定要重新检查签名、权限和所有硬编码的包名引用,任何一个漏掉都会在真机上以“莫名其妙”的方式暴露出来。

数据库:两端终于用同一份 Room v3

Android 端用 Room 2.6.1,schema 版本 3;Windows 端(WPF / .NET 8)原本是 EF Core 那套 PascalCase 列名,这一版把它逐项对齐了 Room v3——表名、列名、列类型、非空约束、索引、外键,连 room_master_table 的身份哈希和 PRAGMA user_version = 3 都写进去了。

结果就是:同一个 .db 文件,手机和电脑都能直接打开。

  • Windows 端打开旧版库时会先留一份 <库名>.bak-时间戳 备份,再重建为 Room v3 并搬运数据,迁移后做行数校验,对不上就不替换;
  • Windows 端首次运行释放的内嵌种子库,与 Android 安装包里的 cement_formula_zh.room.db 是同一份文件(哈希一致,200 条公式 / 46 个分类);
  • 因此库内容更新只需要替换这一个文件,不用再改代码。

五套公式库

除了内置的水泥工艺库,现在有 4 套专业库可以直接导入,导入后作为独立库存在,不合并、可切换、可删除:

公式库条数分类查表公式
水泥工艺(内置)20046—
工厂供配电设计54114 个二维 + 2 个三维
水泥厂工艺设计与设备选型55151 个三维
工程造价与投资决策79161 个二维
水泥工艺(英文)12944—

合计 517 条。分类数按分类树的全部节点计;真正挂公式的末级分类是 37 / 10 / 14 / 15 / 35。

查表公式的表格数据存 JSON,两种语义不能混:interpolate: true 时区间内线性插值、越界取端点;interpolate: false 时只做精确匹配,非标准取值直接返回空(钢筋理论重量表就是这种,直径是离散规格,插值没有意义)。

公式库和方案库是成对分发的。分步方案按 step_calc_plans:<公式库名> 分目录存放,所以公式库文件名不能改,改名之后方案就找不到了。

规划求解:从手写单纯形换成顶点枚举

规划面板要做的事和 Excel Solver 类似:目标(最大 / 最小 / 目标值)、变量上下限与整数约束、一组线性或非线性约束。非线性走 GRG 与演化方法,线性则要求给出精确解。

最初线性部分是手写的单纯形表,后来在配料场景里连续踩了三个坑:等式拆成两条不等式时松弛方向按翻转前的算符算、Phase I 的目标行方向取反导致凡含 >= 的问题全报无解、退化基处理不全导致“可行但非最优”。这三个问题都不是调参能解决的。

现在的做法是 LpVertexSolver:线性目标在有界多面体上的最优值必然在顶点取得,而顶点就是“若干约束同时取等号”的解。把约束统一成等式与不等式两组,等式化行简化阶梯形求特解与零空间基,再在零空间坐标下枚举边界组合解线性方程组,校验后取最优。变量通常只有 2~10 个,规模很小,这套枚举又快又准,也没有单纯形那套退化与人工变量的坑。

两个容易被忽略的细节:非负约束必须作为显式不等式参与枚举(配煤的最优解就是某个变量取 0,只枚举显式约束会漏掉这类顶点);含整数变量或规模过大时,求解器会明确回退到搜索方法,而不是硬报无解。

配套的方案库现在有 23 个:6 个水泥配料方案(率值约束用交叉相乘写成线性形式,计入煤灰)加 17 个通用规划案例——生产计划、采购物流、投资组合、排班、配比、设备、投放、0-1 选择。导入后标为「系统方案」,只读,可以「另存为」改成自己的。

PDF 报告:不引第三方库,自己拼字节

统计、分步、规划三个面板都能导出 PDF。Windows 端的生成器是手写的 PDF 1.4:只需要 Catalog / Pages / Page / Contents / Font 五类对象加一张 xref 表,中文用 STSong-Light 的 Type0 复合字体(UniGB-UCS2-H 编码),不嵌入字体文件,由阅读器用系统中文字体替换显示;文本统一写成 UTF-16BE 十六进制串,中英文同一套写法。

代价是折行只能按字符宽度估算(CJK 记 1.0em、ASCII 记 0.5em),右边界会略有参差;换来的是整个项目不新增任何 NuGet 依赖。Android 端则用系统的 PdfDocument,体例与 Windows 端保持一致。

版本与下载

Android 版 1.0.1(versionCode 27,cn.formulamanager.formulamanager),Windows 版 1.0.7。APK 与 5 套公式库、4 套方案库都可以在首页直接下载;两端导入同一份 .db,互通。