---
title: "使用 Rsymphony 求解线性规划问题"
author: "Rui"
date: "2022-09-13"
categories: [R, 线性规划, Rsymphony]
image: "redflowers.jpg"
format:
html:
code-fold: true
code-tools: true
---
```{r setup, include = FALSE}
# 设置默认参数
knitr::opts_chunk$set(
echo = TRUE,
fig.align = "center",
message = FALSE,
warning = FALSE,
collapse = TRUE
)
```
`Rsymphony` 包中的核心函数是 `Rsymphony_solve_LP`,用法示例:
Rsymphony_solve_LP(
obj,
mat,
dir,
rhs,
bounds = NULL,
types = NULL,
max = FALSE,
verbosity = -2,
time_limit = -1,
node_limit = -1,
gap_limit = -1,
first_feasible = FALSE,
write_lp = FALSE,
write_mps = FALSE
)
其中:
| **主要参数** | **作用** |
|----------------|--------------------------------------------------------|
| obj | 目标函数系数向量 |
| mat | 约束条件系数向量或矩阵 |
| dir | 一个字符型向量,表示约束条件的方向。只能为"\<=","=="或"\>="中的其中一种 |
| rhs | 约束条件的右侧,即约束值 |
| bounds | NULL(默认)或具有包含目标变量的索引和相应边界的元素的列表。 每个变量的默认值是 0 和 Inf (无穷)之间的界限。 |
| type | 接受一组字符型向量用来限定目标变量的类型。"B"指的是 0-1 规划,"C"代表连续型(实数),"I"代表整型(整数)。默认值为 NULL,代表目标变量全为连续型。 |
| max | 接受一个布尔值用来指明优化的方向。TRUE 代表求解目标函数最大值,FALSE (默认值)代表求解目标函数最小值。 |
| verbosity | 接受一个整数来指定输出的详细程度,-2 (默认值)代表没有输出 |
更多参数设置见 `?Rsymphony`
## 一般线性规划
$$
\min \quad z=2x_1+4x_2+3x_3\\
\left\{\begin{matrix}
& 3x_1+4x_2+2x_3 \leqslant 60\\
& 2x_1+x_2+x_3 \leqslant 40\\
& x_1+3x_2+2x_3 \leqslant 80\\
\end{matrix}\right.
$$
```{r}
# 求解
library(Rsymphony)
obj <- c(2, 4, 3)
mat <- matrix(c(3, 2, 1, 4, 1, 3, 2, 1, 2), nrow = 3)
dir <- c("<=", "<=", "<=")
rhs <- c(60, 40, 80)
max <- FALSE
Rsymphony_solve_LP(obj, mat, dir, rhs, max = max)
```
::: callout-note
若 `status` 返回值为 -1 则表示无解。
:::
## 整数线性规划
$$
\min \quad z=40x_1+90x_2\\
\left\{
\begin{matrix}
9x_1+7x_2 \leqslant 56\\
7x_1+20x_2 \geqslant 70\\
x_1,x_2 为非负整数\\
\end{matrix}
\right.
$$
```{r}
obj <- c(40, 90)
mat <- matrix(c(9, 7, 7, 20), nrow = 2)
dir <- c("<=", ">=")
rhs <- c(56, 70)
max <- FALSE
types <- c("I", "I")
Rsymphony_solve_LP(obj, mat, dir, rhs, types = types, max = max)
```
## 混合整数线性规划
$$
\max \quad z=3x_1+x_2+3x_3\\
\left\{
\begin{matrix}
-x_1+2x_2+x_3 \leqslant 4\\
4x_2-3x_3 \leqslant 2\\
x_1-3x_2+2x_3 \leqslant 3\\
x_1,x_3 为非负整数\\
x_2 为非负实数
\end{matrix}
\right.
$$
```{r}
obj <- c(3, 1, 3)
mat <- matrix(c(-1, 0, 1, 2, 4, -3, 1, -3, 2), nrow = 3)
dir <- c("<=", "<=", "<=")
rhs <- c(4, 2, 3)
max <- TRUE
types <- c("I", "C", "I")
Rsymphony_solve_LP(obj, mat, dir, rhs, types = types, max = max)
```
$$
\max \quad z=3x_1+x_2+3x_3\\
\left\{
\begin{matrix}
-x_1+2x_2+x_3 \leqslant 4\\
4x_2-3x_3 \leqslant 2\\
x_1-3x_2+2x_3 \leqslant 3\\
-\infty <x_1 \leqslant 4\\
0 \leqslant x_2 \leqslant 100\\
2 \leqslant x_3 \leqslant +\infty\\
x_1,x_3 为整数\\
x_2 为实数
\end{matrix}
\right.
$$
```{r}
obj <- c(3, 1, 3)
mat <- matrix(c(-1, 0, 1, 2, 4, -3, 1, -3, 2), nrow = 3)
dir <- c("<=", "<=", "<=")
rhs <- c(4, 2, 3)
max <- TRUE
types <- c("I", "C", "I")
bounds <- list(
lower = list(
ind = c(1L, 2L, 3L), val = c(-Inf, 0, 2)),
upper = list(ind = c(1L, 2L, 3L), val = c(4, 100, Inf)
)
)
Rsymphony_solve_LP(obj, mat, dir, rhs, types = types, max = max)
```