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

含“或”约束的线性优化器构建及额外约束添加求助

解决方案:添加两类约束到线性优化模型

我会帮你把两个新约束整合到现有的lpSolve代码中,下面是分步实现方法和完整代码:

1. 约束逻辑转化思路

因为线性规划只能处理线性约束,我们需要把你的逻辑需求转化为可量化的线性表达式:

  • 约束1(至少一种type1出现≥2次):通过引入辅助0-1变量实现"或"逻辑,确保至少有一个type1类别的选中数量达标。
  • 约束2(Y物品的type1唯一):通过线性化处理,避免非线性乘积项,确保选中的Y物品的type1不会出现在X物品中。

2. 完整修改后的可运行代码

library(lpSolve)
library(dplyr)

# 初始化物品数据
id <- 1:50
type1 <- sample(c('A', 'B', 'C', 'D', 'E'), length(id), replace = T)
type2 <- sample(c('X', 'X', 'X', 'Y'), length(id), replace = T)
value <- round(runif(length(id), 0, 20),0)
cost <- round(runif(length(id), 750, 1250),0)
df <- data.frame(id, type1, type2, value, cost) %>% mutate(total = 1)

# 添加属性哑变量
type1Dummy <- as.data.frame.matrix(table(df$id, df$type1))
type2Dummy <- as.data.frame.matrix(table(df$id, df$type2))
df <- cbind(df, type1Dummy, type2Dummy)

# ---------------------- 新增约束相关处理 ----------------------
# 1. 为约束1创建辅助0-1变量(对应A-E五个type1类别)
num_z_vars <- 5
z_names <- paste0("z_", colnames(type1Dummy))

# 扩展目标函数:辅助变量不影响价值最大化,系数设为0
obj <- c(df$value, rep(0, num_z_vars))

# 2. 构建完整约束矩阵
# 保留原有约束(总数量、总成本、X数量、Y数量),并扩展辅助变量列
existing_mat <- t(data.frame(df$total, df$cost, df$X, df$Y))
existing_mat <- cbind(existing_mat, matrix(0, nrow = nrow(existing_mat), ncol = num_z_vars))

# --- 约束1:至少一个type1出现≥2次 ---
# 子约束:每个type1类别满足「选中数 +5*辅助变量 ≥2」
constraint_type1_freq <- list()
for (k in colnames(type1Dummy)) {
  row <- c(df[[k]], rep(0, num_z_vars))
  row[which(z_names == paste0("z_", k))] <- 5
  constraint_type1_freq[[k]] <- row
}
constraint_type1_freq <- do.call(rbind, constraint_type1_freq)

# 总约束:辅助变量之和≥1(确保至少有一个类别触发选中数≥2的要求)
constraint_z_sum <- c(rep(0, nrow(df)), rep(1, num_z_vars))

# --- 约束2:Y物品的type1不在X物品中出现 ---
# 对每个type1类别,约束「X中该类选中数 +5*Y中该类选中数 ≤5」
# 逻辑:若Y物品是该类,则第二项为5,强制X中选中数为0;否则约束自动满足
constraint_y_type1_unique <- list()
for (k in colnames(type1Dummy)) {
  row <- c(df$X * df[[k]] + 5 * df$Y * df[[k]], rep(0, num_z_vars))
  constraint_y_type1_unique[[k]] <- row
}
constraint_y_type1_unique <- do.call(rbind, constraint_y_type1_unique)

# 合并所有约束矩阵
mat <- rbind(existing_mat, constraint_type1_freq, constraint_z_sum, constraint_y_type1_unique)

# 3. 构建约束方向和右侧值
# 原有约束参数
rhs <- c(5, 5000, 4, 1)
dir <- c("==", "<=", "==", "==")

# 约束1的参数
rhs <- c(rhs, rep(2, num_z_vars), 1)
dir <- c(dir, rep(">=", num_z_vars), ">=")

# 约束2的参数
rhs <- c(rhs, rep(5, num_z_vars))
dir <- c(dir, rep("<=", num_z_vars))

# ---------------------- 求解并验证结果 ----------------------
sol <- lpSolve::lp("max", 
                   objective.in = obj, 
                   const.mat = mat, 
                   const.dir = dir, 
                   const.rhs = rhs, 
                   all.bin = T )

# 提取选中物品
df$selected <- sol$solution[1:nrow(df)]
dfSolved <- df[df$selected == 1,]

# 输出结果
cat("选中的物品:\n")
print(dfSolved %>% select(id, type1, type2, value, cost))

# 验证约束是否满足
cat("\n=== 约束验证 ===\n")
# 验证约束1
type1_counts <- table(dfSolved$type1)
cat("约束1:是否有type1出现≥2次?\n")
print(type1_counts)
cat(paste("结果:", any(type1_counts >=2), "\n"))

# 验证约束2
y_item <- dfSolved %>% filter(type2 == "Y")
y_type1 <- y_item$type1
x_has_y_type1 <- y_type1 %in% dfSolved$type1[dfSolved$type2 == "X"]
cat("\n约束2:Y物品的type1是否不在X物品中?\n")
cat(paste("Y物品的type1:", y_type1, "\n"))
cat(paste("X物品中是否存在该type1:", x_has_y_type1, "\n"))
cat(paste("结果:", !x_has_y_type1, "\n"))

代码关键说明

  • 辅助变量z_k仅用于实现"或"逻辑,不影响价值最大化目标;
  • 约束2通过线性化处理,巧妙规避了非线性的乘积项,符合线性规划要求;
  • 代码末尾添加了验证步骤,可直观检查两个约束是否被满足。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:26:15