c++ SCIP求解整数规划模型

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
相关推荐
恒者走天下1 分钟前
手机行业cpp c++相关就业岗位详细汇总
c++
洛阳吕工5 分钟前
【Python 教程】无人机 MAVLink 通信完整实战:连接飞控、接收数据与发送指令
开发语言·python·无人机
小辉同志5 分钟前
79. 单词搜索
开发语言·c++·leetcode·回溯
娇娇爱吃蕉蕉.5 分钟前
类和对象的默认成员函数
c语言·开发语言·c++·算法
量子炒饭大师6 分钟前
【C++ 11】Cyber骇客 最后的一片净土 ——【列表初始化{}】(附带完整代码解析)
c++·dubbo·列表初始化
小白学大数据10 分钟前
Python requests + BeautifulSoup 爬取豆瓣电影图片
开发语言·python·beautifulsoup
她说..8 小时前
Java 对象相关高频面试题
java·开发语言·spring·java-ee
watson_pillow9 小时前
c++ 协程的初步理解
开发语言·c++
庞轩px9 小时前
深入理解 sleep() 与 wait():从基础到监视器队列
java·开发语言·线程··wait·sleep·监视器
故事和你919 小时前
洛谷-算法1-2-排序2
开发语言·数据结构·c++·算法·动态规划·图论