You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

CPSAT约束中用指数计算贷款分期报错,求解决方案

解决OR-Tools非线性约束报错问题

错误原因

你遇到的TypeError是因为OR-Tools的决策变量(adjusted_duration)无法参与幂运算这类非线性操作。OR-Tools的线性/整数规划求解器仅支持线性表达式(变量与常数的加减乘组合),不能直接处理包含变量的指数、变量作为分母的除法等非线性逻辑。

可行解决方法

由于你的adjusted_duration取值范围是1-100(非常小),可以通过预计算所有可能期限对应的月供系数,将非线性约束转换为线性约束。具体步骤如下:

1. 预计算各期限的月供系数

提前算出每个期限d对应的月供计算系数,公式和你原代码逻辑一致:

import math

# 月利率
monthly_rate = 0.00049 / 12
# 预计算每个期限对应的系数:(月利率) / (1 - (1+月利率)^-期限)
monthly_payment_coeff = {}
for d in range(1, 101):
    denominator = 1 - math.pow(1 + monthly_rate, -d)
    monthly_payment_coeff[d] = monthly_rate / denominator

2. 用布尔变量关联期限与约束

通过布尔变量标记当前选择的期限,再为每个期限添加对应的线性约束:

# 定义布尔变量数组,每个变量对应一个期限是否被选中
is_selected_duration = {}
for d in range(1, 101):
    is_selected_duration[d] = model.NewBoolVar(f"duration_{d}_selected")

# 约束:只能选中一个期限
model.Add(sum(is_selected_duration.values()) == 1)

# 关联adjusted_duration与布尔变量(确保变量值等于选中的期限)
model.Add(adjusted_duration == sum(d * is_selected_duration[d] for d in range(1, 101)))

# 计算薪资上限的整数值(和你原代码逻辑一致)
salary_limit = int(Salary * 0.5 * scaling_factor)

# 为每个期限添加月供约束
for d in range(1, 101):
    # 将系数缩放为整数(匹配你的scaling_factor逻辑,避免浮点精度问题)
    scaled_coeff = int(monthly_payment_coeff[d] * scaling_factor)
    # 仅当该期限被选中时,约束生效
    model.Add(scaled_coeff * adjusted_amount <= salary_limit).OnlyEnforceIf(is_selected_duration[d])

方法合理性说明

因为期限的取值范围极小(仅100种可能),预计算所有情况的开销可以忽略,同时将原本的非线性表达式拆分为多个线性约束,完全符合OR-Tools求解器的要求。

内容的提问来源于stack exchange,提问作者stefano guerrieri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 00:35:57