Python 调用 SCIP 求解器的选址模型代码示例

本文介绍 Python 语言调用 SCIP 求解器,求解选址模型的代码示例。


安装 SCIP 和 PySCIPOpt


安装 SCIP 求解器的教程:
SCIP | 数学规划求解器SCIP超详细的使用教程.

笔者在 Windows 10 系统上安装了 SCIP v7.0.0,并通过清华镜像源安装了 PySCIPOpt v3.2.0,Python 版本为 3.7.8
(UserWarning 显示,该版本的 PySCIPOpt 建议使用 SCIP v7.0.1)

pip install PySCIPOpt==3.2.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

选址模型代码示例


模型模块:

from typing import List, Dict

from pyscipopt import Model, quicksum


def location(num_node: int, num_centre: int, mat_distance: List[List[float]]) -> Dict[int, List[int]]:
    """
    location model

    :param num_node:  number of nodes
    :param num_centre:  number of centres
    :param mat_distance:  distance matrix

    :return: dict_res:  {centre node: [node] list} dictionary
    """

    model = Model("location")

    x = {(i, j): model.addVar(vtype="B", name="x_[{},{}]".format(i, j)) for i in range(num_node)
         for j in range(num_node)}

    # basic constraint
    for j in range(num_node):
        model.addCons(quicksum(x[i, j] for i in range(num_node)) == 1, name="basic_cover_[{}]".format(j))

        for i in range(num_node):
            model.addCons(x[i, j] <= x[i, i], name="basic_centre_[{},{}]".format(i, j))

    # number of centres
    model.addCons(quicksum(x[i, i] for i in range(num_node)) == num_centre, name="num_centre")

    # objective: min, total distance
    model.setObjective(quicksum(mat_distance[i][j] * x[i, j] for i in range(num_node) for j in range(num_node)),
                       sense="minimize")

    # time limit
    model.setRealParam("limits/time", 1000)

    # solve
    model.optimize()
    print()

    # status
    status = model.getStatus()
    print("model status: {}".format(status), '\n')
    if status != "optimal":
        return {}

    # optimal objective value
    obj_value = model.getObjVal()
    print("optimal objective value: {}".format(obj_value), '\n')

    # optimal solution
    x_ = {(i, j): model.getVal(x[i, j]) for i in range(num_node) for j in range(num_node)}

    # result process
    dict_res = {}
    for i in range(num_node):
        if x_[i, i] > 0.9:
            list_tmp = []
            for j in range(num_node):
                if x_[i, j] > 0.9:
                    list_tmp.append(j)
            dict_res[i] = list_tmp
            print("centre code {} serves nodes:  {}".format(i, list_tmp))

    return dict_res

主程序:

import random

from model import location


num_node = 100
ran_coo = (0, 100)
random.seed(a=1024)
list_coo = [(random.randint(ran_coo[0], ran_coo[1]),
             random.randint(ran_coo[0], ran_coo[1])) for _ in range(num_node)]
mat_dist = [[((list_coo[i][0] - list_coo[j][0]) ** 2 + (list_coo[i][1] - list_coo[j][1]) ** 2) ** 0.5
             for j in range(num_node)] for i in range(num_node)]

num_amount = 10
dict_res = location(num_node=num_node, num_centre=num_amount, mat_distance=mat_dist)

求解日志:
求解日志

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值