一个模型上下文协议服务器,提供了用于解决组合优化、凸优化、整数规划和非线性优化问题的工具。暴露了以下求解器的接口:
要安装,请运行 install.py 脚本。这将安装适用于Claude Desktop和/或Cursor的MPC服务器。
uv run install.py
然后打开Claude或Cursor,您应该能在工具列表中看到可用的MCP工具 usolver。
要运行各个求解器示例,可以调用各个示例模块。每个模块都包含一个文档字符串,可用于提示语言模型来解决问题。
你和一位朋友经过一台标准的硬币投币自动售货机,决定买一块糖果棒。
价格是0.95美元,但检查口袋后你只有一张一美元纸币,而机器只能接受硬币。
你转向你的朋友,并进行了如下对话:
你:嘿,你能换一下一美元吗?
朋友:让我看看。我有六枚硬币,虽然它们加起来是1.15美元,但我不能找零一美元。
你:什么?你能找零半美元吗?
朋友:不能。
你:那四分之一美元呢?
朋友:不行,而且在你问之前我要说我也不能找零十分之一美元或五分之一美元。
你:真的吗?这六枚硬币都是目前流通的美国政府硬币吗?
朋友:是的。
你:好吧,那你能不能把你的硬币放进自动售货机里给我买块糖果棒,然后我再还给你?
朋友:对不起,我想帮但用我手里的这些硬币做不到。
你的朋友手里拿着哪些硬币?
这可以输入到usolver中,它会生成一个约束系统:
$C$ 是六个未知硬币面值的集合,$c_1$ 到 $c_6$,每个都必须是一个正整数,代表美分。
$$ C = {c_1, c_2, c_3, c_4, c_5, c_6}, \quad \text{其中每个 } c_i \in \mathbb{Z}^+ $$
$\mathcal{S}$ 是你可以从六个硬币中选择两个或更多硬币的所有可能方式的集合。
$$ \mathcal{S} = {S \mid S \subseteq C \land |S| \ge 2 } $$
排除50美分硬币用于自动售货机。
$$ v(x) = \begin{cases} 0 & \text{如果 } x = 50 \ x & \text{如果 } x \neq 50 \end{cases} $$
约束0:所有六个硬币的总面值是115美分。
$$ \sum_{i=1}^{6} c_i = 115 $$
约束1:不能找零一美元。
$$ \forall S \in \mathcal{S}, \quad \sum_{x \in S} x \neq 100 $$
约束2:不能找零半美元。
$$ \forall S \in \mathcal{S}, \quad \sum_{x \in S} x \neq 50 $$
约束3:不能找零四分之一美元。
$$ \forall S \in \mathcal{S}, \quad \sum_{x \in S} x \neq 25 $$
约束4:不能找零十分之一美元。
$$ \forall S \in \mathcal{S}, \quad \sum_{x \in S} x \neq 10 $$
约束5:不能找零五分之一美元。
$$ \forall S \in \mathcal{S}, \quad \sum_{x \in S} x \neq 5 $$
约束6:如果排除半美元,不能用95美分购买糖果棒。
$$ \forall S \in \mathcal{S}, \quad \sum_{x \in S} v(x) \neq 95 $$
如果你将这个输入到求解器中,它会合成上述约束系统,使用Z3求解并返回解决方案。
你的朋友有:1枚半美元,1枚四分之一美元,和4枚十分之一美元
这总共是50¢ + 25¢ + 40¢ = 115¢ = $1.15 ✓
这是正好6枚硬币 ✓
一个金融示例:
目标:最大化预期投资组合回报
约束条件:
债券配置不得超过40%
股票配置不得超过60%
房地产配置不得超过30%
商品配置不得超过20%
所有配置必须是非负的
总配置必须等于100%
总投资组合风险不得超过10%
给定数据:
预期回报率:债券8%,股票12%,房地产10%,商品15%
风险因素:债券2%,股票15%,房地产8%,商品20%
这被编译成一个凸优化问题,可以使用cvxopt求解。
$$ \begin{align} \text{最大化} \quad & 0.08x_1 + 0.12x_2 + 0.10x_3 + 0.15x_4 \ \text{受约束于} \quad & x_1 + x_2 + x_3 + x_4 = 1 \ & x_1 \leq 0.4 \ & x_2 \leq 0.6 \ & x_3 \leq 0.3 \ & x_4 \leq 0.2 \ & 0.02x_1 + 0.15x_2 + 0.08x_3 + 0.20x_4 \leq 0.10 \ & x_1, x_2, x_3, x_4 \geq 0 \end{align} $$
其中:
答案是:
债券:30.0%
股票:20.0%
房地产:30.0%(达到最大允许值)
商品:20.0%(达到最大允许值)
最大预期回报:每年10.8%
一个化学工程示例:
使用usolver设计一个水输送管道,要求如下:
* 体积流量:0.05 m³/s
* 管道长度:100 m
* 水密度:1000 kg/m³
* 最大允许压力降:50 kPa
* 流量连续性:Q = π(D/2)² × v
* 压力降:ΔP = f(L/D)(ρv²/2),其中f ≈ 0.02为湍流
* 实际限制:0.05 ≤ D ≤ 0.5 m,0.5 ≤ v ≤ 8 m/s
* 压力约束:ΔP ≤ 50,000 Pa
* 找出:最优管道直径和流速
一个多线性优化示例:
使用usolver解决以下线性规划问题:
最小化:12x + 20y
受约束于:6x + 8y ≥ 100
7x + 12y ≥ 120
x ≥ 0
y ∈ [0, 3]
这被编译成一个约束满足问题,可以使用Z3求解。
$$ \begin{aligned} \text{最小化} \quad & 12x + 20y \ \text{受约束于} \quad & 6x + 8y \geq 100 \ & 7x + 12y \geq 120 \ & x \geq 0 \ & y \in [0, 3] \end{aligned} $$
其中:
最优解是:
x = 15.0
y = 1.25
目标值 = 205.0
一个简单的凸优化问题,最小化线性系统的2范数:
使用usolver解决以下凸优化问题:
最小化:||Ax - b||₂²
受约束于:0 ≤ x ≤ 1
其中
A = [1.0, -0.5; 0.5, 2.0; 0.0, 1.0]
b = [2.0, 1.0, -1.0]
一个经典的工人轮班调度问题:
使用usolver解决一个护士排班问题,要求如下:
* 安排4名护士(Alice, Bob, Charlie, Diana)在3个班次(周一、周二、周三)
* 班次:上午(7AM-3PM),下午(3PM-11PM),晚上(11PM-7AM)
* 每个班次每天必须分配给一名护士
* 每名护士每天最多工作一个班次
* 平均分配班次(每名护士在这段时间内工作2-3个班次)
* Charlie不能在周二工作。
一个使用OR-Tools优化餐桌布局和使用CVXPY优化员工排班的链式示例。
使用usolver优化餐厅的布局和员工排班,分为两部分。第一部分使用组合优化优化餐桌布局,第二部分使用凸优化优化员工排班。
* 第一部分:优化餐桌布局
- 包括2人座、4人座和6人座的混合
- 最大地面空间:150 m²
- 空间需求:4m²(2人座),6m²(4人座),9m²(6人座)
- 总桌子数量不超过20个
- 最小混合:2× 2人座,3× 4人座,1× 6人座
- 目标:最大化总座位容量
* 第二部分:使用第一部分的容量优化员工排班
- 12小时营业日
- 每名员工可处理20个座位
- 每小时至少2名员工
- 小时之间的员工变化最大为2人
- 变动需求:容量的40%-100%
- 目标:最小化劳动成本(每小时每名员工25美元)
也可以直接从GitHub容器注册表运行MCP服务器。
docker run -p 8081:8081 ghcr.io/sdiehl/usolver:latest
然后在客户端添加以下内容:
{
"mcpServers": {
"sympy-mcp": {
"command": "docker",
"args": [
"run",
"-i",
"-p",
"8081:8081",
"--rm",
"ghcr.io/sdiehl/usolver:latest"
]
}
}
}
根据Apache许可证2.0发布。详情见LICENSE文件。