SCIP是一款开源的求解整数规划求解器,跟cplex、gurobi一样。
到SCIP官网下载软件 https://scipopt.org/#download ,下载10.0.1版本的.exe程序,点击安装。我的路径G:\software\SCIPOptSuite1001,而且G:\software\SCIPOptSuite1001\bin要添加到系统环境变量中。
CMakeLists.txt内容如下:
cpp
cmake_minimum_required(VERSION 3.25)
project(P_median_problem)
set(CMAKE_CXX_STANDARD 20)
# 设置 SCIP 根目录(根据你的实际路径修改)
set(SCIP_DIR "G:/software/SCIPOptSuite1001")
# 包含头文件目录
include_directories(${SCIP_DIR}/include)
# 添加库目录(以便 find_library 或直接链接)
link_directories(${SCIP_DIR}/lib)
# 添加可执行文件
add_executable(my_scip_app ../improved_Lagrangian_relaxation/main1_SCIP_MIP.cpp)
# 查找 SCIP 核心库和 SoPlex 库
find_library(SCIP_CORE_LIBRARY NAMES libscip PATHS ${SCIP_DIR}/lib NO_DEFAULT_PATH)
find_library(SOPLEX_LIBRARY NAMES libsoplex libsoplexshared PATHS ${SCIP_DIR}/lib NO_DEFAULT_PATH)
if(NOT SCIP_CORE_LIBRARY)
message(FATAL_ERROR "SCIP core library not found")
endif()
if(NOT SOPLEX_LIBRARY)
message(FATAL_ERROR "SoPlex library not found")
endif()
target_link_libraries(my_scip_app ${SCIP_CORE_LIBRARY} ${SOPLEX_LIBRARY} ws2_32 winmm)
# 复制 SCIP bin 目录下所有 DLL 到输出目录
add_custom_command(TARGET my_scip_app POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${SCIP_DIR}/bin"
$<TARGET_FILE_DIR:my_scip_app>
COMMENT "Copying SCIP DLLs to output directory"
)

main1_SCIP_MIP.cpp内容如下:
cpp
#include <iostream>
#include "scip/scip.h"
#include "scip/scipdefplugins.h"
using namespace std;
int main() {
// 1. 创建 SCIP 实例并加载默认插件
SCIP* scip = nullptr;
SCIP_CALL( SCIPcreate(&scip) );
SCIP_CALL( SCIPincludeDefaultPlugins(scip) );
// 2. 创建问题
SCIP_CALL( SCIPcreateProbBasic(scip, "simple_integer_program") );
SCIPsetObjsense(scip, SCIP_OBJSENSE_MAXIMIZE);
// 3. 创建变量
SCIP_VAR* x1 = nullptr;
SCIP_VAR* x2 = nullptr;
SCIP_CALL( SCIPcreateVar(scip, &x1, "x1", 0.0, SCIPinfinity(scip), 3.0,
SCIP_VARTYPE_INTEGER, true, false,
nullptr, nullptr, nullptr, nullptr, nullptr) );
SCIP_CALL( SCIPcreateVar(scip, &x2, "x2", 0.0, SCIPinfinity(scip), 5.0,
SCIP_VARTYPE_INTEGER, true, false,
nullptr, nullptr, nullptr, nullptr, nullptr) );
SCIP_CALL( SCIPaddVar(scip, x1) );
SCIP_CALL( SCIPaddVar(scip, x2) );
// 4. 创建约束(使用简化版本 SCIPcreateConsBasicLinear)
SCIP_CONS* cons1 = nullptr;
SCIP_CONS* cons2 = nullptr;
// 约束 1: 2x1 + 4x2 <= 100
{
SCIP_VAR* vars[2] = { x1, x2 };
double coeffs[2] = { 2.0, 4.0 };
SCIP_CALL( SCIPcreateConsBasicLinear(scip, &cons1, "resource1",
2, vars, coeffs,
-SCIPinfinity(scip), 100.0) );
SCIP_CALL( SCIPaddCons(scip, cons1) );
}
// 约束 2: 3x1 + 2x2 <= 90
{
SCIP_VAR* vars[2] = { x1, x2 };
double coeffs[2] = { 3.0, 2.0 };
SCIP_CALL( SCIPcreateConsBasicLinear(scip, &cons2, "resource2",
2, vars, coeffs,
-SCIPinfinity(scip), 90.0) );
SCIP_CALL( SCIPaddCons(scip, cons2) );
}
// 释放约束(已添加到问题,可以释放)
SCIP_CALL( SCIPreleaseCons(scip, &cons1) );
SCIP_CALL( SCIPreleaseCons(scip, &cons2) );
// 5. 设置求解器参数
SCIP_CALL( SCIPsetRealParam(scip, "limits/time", 60.0) ); // 限制求解时间 60 秒
SCIP_CALL( SCIPsetIntParam(scip, "display/verblevel", 5) ); // 输出详细日志
// 6. 求解
cout << "Starting optimization..." << endl;
SCIP_CALL( SCIPsolve(scip) );
// 7. 获取解
SCIP_SOL* sol = SCIPgetBestSol(scip);
if ( sol ) {
double objval = SCIPgetSolOrigObj(scip, sol);
double x1_val = SCIPgetSolVal(scip, sol, x1);
double x2_val = SCIPgetSolVal(scip, sol, x2);
cout << "\nOptimal solution found!" << endl;
cout << "Objective value = " << objval << endl;
cout << "x1 = " << x1_val << endl;
cout << "x2 = " << x2_val << endl;
} else {
cout << "No solution found." << endl;
}
// 8. 清理
SCIP_CALL( SCIPreleaseVar(scip, &x1) );
SCIP_CALL( SCIPreleaseVar(scip, &x2) );
SCIP_CALL( SCIPfree(&scip) );
return 0;
}
运行结果如下:
cpp
Starting optimization...
LP Solver <SoPlex 8.0.1>: barrier convergence tolerance cannot be set -- tolerance of SCIP and LP solver may differ
LP Solver <SoPlex 8.0.1>: fastmip setting not available -- SCIP parameter has no effect
LP Solver <SoPlex 8.0.1>: number of threads settings not available -- SCIP parameter has no effect
transformed problem has 2 variables (0 bin, 2 int, 0 cont) and 2 constraints
2 constraints of type <linear>
original problem has 4 active (100%) nonzeros and 4 (100%) check nonzeros
feasible solution found by trivial heuristic after 0.0 seconds, objective value 0.000000e+00
presolving:
(round 1, fast) 0 del vars, 0 del conss, 0 add conss, 3 chg bounds, 0 chg sides, 0 chg coeffs, 0 upgd conss, 0 impls, 0 clqs, 0 implints
(0.0s) running MILP presolver
(0.0s) MILP presolver found nothing
(round 2, exhaustive) 0 del vars, 0 del conss, 0 add conss, 3 chg bounds, 0 chg sides, 0 chg coeffs, 2 upgd conss, 0 impls, 0 clqs, 0 implints
(0.0s) symmetry computation started: requiring (bin +, int +, cont +), (fixed: bin -, int -, cont -)
(0.0s) no symmetry present (symcode time: 0.00)
clique table cleanup detected 0 bound changes
presolved problem has 4 active (100%) nonzeros and 4 (100%) check nonzeros
presolving (3 rounds: 3 fast, 2 medium, 2 exhaustive):
0 deleted vars, 0 deleted constraints, 0 added constraints, 3 tightened bounds, 0 added holes, 0 changed sides, 0 changed coefficients
0 implications, 0 cliques, 0 implied integral variables (0 bin, 0 int, 0 cont)
presolved problem has 2 variables (0 bin, 2 int, 0 cont) and 2 constraints
2 constraints of type <varbound>
transformed objective value is always integral (scale: 1)
Presolving Time: 0.00
transformed 1/1 original solutions to the transformed problem space
time | node | left |LP iter|LP it/n|mem/heur|mdpt |vars |cons |rows |cuts |sepa|confs|strbr| dualbound | primalbound | gap | compl.
p 0.0s| 1 | 0 | 0 | - | vbounds| 0 | 2 | 2 | 2 | 0 | 0 | 0 | 0 | 2.150000e+02 | 9.000000e+01 | 138.89%| unknown
p 0.0s| 1 | 0 | 0 | - | vbounds| 0 | 2 | 2 | 2 | 0 | 0 | 1 | 0 | 2.150000e+02 | 1.250000e+02 | 72.00%| unknown
* 0.0s| 1 | 0 | 2 | - | LP | 0 | 2 | 2 | 2 | 0 | 0 | 3 | 0 | 1.350000e+02 | 1.350000e+02 | 0.00%| unknown
0.0s| 1 | 0 | 2 | - | 843k | 0 | 2 | 2 | 2 | 0 | 0 | 3 | 0 | 1.350000e+02 | 1.350000e+02 | 0.00%| unknown
SCIP Status : problem is solved [optimal solution found]
Solving Time (sec) : 0.00
Solving Nodes : 1
Primal Bound : +1.35000000000000e+02 (4 solutions)
Dual Bound : +1.35000000000000e+02
Gap : 0.00 %
Optimal solution found!
Objective value = 135
x1 = 20
x2 = 15
Process finished with exit code 0