调用 OR-Tools GLOP 求解器的简单模型实例

本文介绍 Python 语言调用 OR-Tools 求解器,求解线性规划模型和整数规划模型的代码示例。

 

 

线性规划模型 - Klee-Minty Cube

 

Klee-Minty Cube 问题:

 

代码示例:

from datetime import datetime
from ortools.linear_solver import pywraplp

n = 100
epsilon = 0.1

# instantiate a Glop solver
solver = pywraplp.Solver('klee_minty_cube', problem_type=pywraplp.Solver.GLOP_LINEAR_PROGRAMMING)

# variables
x = [solver.NumVar(0, solver.infinity(), 'x_{}'.format(i)) for i in range(n)]

# constraints
solver.Add(0 <= x[0])
solver.Add(x[0] <= 1)
for i in range(1, n):
    solver.Add(epsilon * x[i - 1] <= x[i])
    solver.Add(x[i] <= 1 - epsilon * x[i - 1])

# objective
solver.Maximize(x[n - 1])

# solve
dts = datetime.now()
status = solver.Solve()
dte = datetime.now()
tm = round((dte - dts).seconds + (dte - dts).microseconds / (10 ** 6), 3)
print("OR-Tools GLOP model solving time:  {} s".format(tm), '\n')

# result
if status == pywraplp.Solver.OPTIMAL:
    print("solution:")
    obj_opt = solver.Objective().Value()
    print("objective value:  {}".format(obj_opt))
    list_x_res = [x[i].solution_value() for i in range(n)]
    print("x solution:  {}".format(list_x_res))
else:
    print("The problem does not have an optimal solution.")

print("\nAdvanced usage:")
print("Problem solved in %f milliseconds" % solver.wall_time())
print("Problem solved in %d iterations" % solver.iterations())

 

参考资料:

The Glop Linear Solver

 

 

整数规划模型 - 选址问题

 

选址问题的整数规划模型较为经典,此处不赘述。

代码示例:

from datetime import datetime
from typing import List, Dict

from ortools.linear_solver import pywraplp


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

    :param num_node:  nodes amount
    :param mat_distance:  distance matrix

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

    # 整数规划模型 problem_type: CBC_MIXED_INTEGER_PROGRAMMING
    solver = pywraplp.Solver('location', problem_type=pywraplp.Solver.CBC_MIXED_INTEGER_PROGRAMMING)

    x = [[solver.BoolVar('x_{}_{}'.format(i, j)) for j in range(num_node)] for i in range(num_node)]

    # 选址问题基本约束
    for j in range(num_node):
        solver.Add(sum(x[i][j] for i in range(num_node)) == 1)

        for i in range(num_node):
            solver.Add(x[i][j] <= x[i][i])

    # 约束:中心点的数量(聚类数量)
    solver.Add(sum(x[i][i] for i in range(num_node)) == 10)

    # 目标:最小化总距离
    solver.Minimize(sum(x[i][j] * mat_distance[i][j] for j in range(num_node) for i in range(num_node)))

    dts = datetime.now()
    status = solver.Solve()
    dte = datetime.now()
    tm = round((dte - dts).seconds + (dte - dts).microseconds / (10 ** 6), 3)
    print("OR-Tools GLOP model solving time:  {} s".format(tm), '\n')

    # case 1: 最优解
    dict_res = {}
    if status == pywraplp.Solver.OPTIMAL:
        print("solution:")
        obj_opt = solver.Objective().Value()  # 获取最优目标函数值
        print("objective value:  {}".format(round(obj_opt, 4)))
        mat_x_res = [[x[i][j].solution_value() for j in range(num_node)] for i in range(num_node)]  # 获取最优解

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

    # case 2: 无解
    elif status == pywraplp.Solver.INFEASIBLE:
        print("Model infeasible!")

    # case 3: 其他
    else:
        print("unexpected status:  {}.".format(status))

    print("\nAdvanced usage:")
    print("Problem solved in %f milliseconds." % solver.wall_time())  # 求解时间
    print("Problem solved in %d iterations." % solver.iterations())  # 迭代次数

    return dict_res

 

算例规模:300 个点,10 个选址中心

硬件配置:i7-8700 3.20GHz 3.19GHz CPU;16GB 内存

求解时间:12.159 s

结果可视化:

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值