[cplex教程]cp问题系列2


前言:cplex的安装教程已经发布在 前面的内容中了,可自行领取
cplex系列1的链接为:https://blog.csdn.net/wlgtcl/article/details/137999127?spm=1001.2014.3001.5501

Golomb 标尺/最优标尺

问题描述

  • Golomb ruler,也被称为Golomb标尺或最优标尺,是一个非负整数序列,其中每个数字表示标尺上的一个标记位置。这个标尺的特点是,序列中任意两个数字之间的差都是唯一的,即标尺上任意两个标记之间的距离都是不同的。
  • 由于其特性,Golomb ruler在信息理论中有着重要的应用,特别是在无线电通信和雷达测距等领域。例如,它可以用于设计无线电频率的分配,以避免相互干扰。
  • 示例:一个简单的Golomb ruler例子是[0, 1, 4, 6],其中0是起点,1、4和6是标尺上的标记。可以验证,这些标记之间的距离(1-0=1,4-1=3,4-0=4,6-4=2,6-1=5,6-0=6)都是唯一的。
  • 本题目目标:给定一个序列的长度,构造一个Golomb ruler。即构造一个任意两个标记之间的距离都是唯一的且具有结尾值最小的序列。
    • 例如:给定序列长度为5,则有两个解:[0,1 4, 9, 11]与[0, 2, 7, 8, 11],注意是序列任意两个值的差距而不仅仅是相邻的两个值的差距。[0, 1, 3, 6, 10]就不行,因为[0, 3]间隔与[3, 6]间隔相同。

代码与解析

  • 导包与定义问题输入
from docplex.cp.model import CpoModel
from sys import stdout
ORDER = 8 # 序列长度为8
MAX_LENGTH = (ORDER - 1) ** 2 # 最长不可能超过49
  • 实例化模型并定义变量
    • dist是后面的标记减去前面的标记,该变量是为了后面的约束条件使用
mdl = CpoModel()
marks = mdl.integer_var_list(ORDER, 0, MAX_LENGTH, 'M')
dist = [marks[i] - marks[j] for i in range(1, ORDER) for j in range(0, i)]
  • 约束条件
    • 第一个约束条件是确保上述的dist取不同的值
    • 第二个约束条件是让标记从0开始,是一个不太重要的约束条件,一般大家都会默认如此,除非业务场景有要初始值不能从0开始
    • 循环约束条件保证有序性,即序列的单调性,使序列递增
    • 第四个约束条件是为了避免镜像解
      • 在求解Golomb ruler问题时,需要避免mirror solution(镜像解)的原因主要有以下几点:
      • 重复性问题:Mirror solution实际上是原始解的镜像翻转,它并不提供新的、独立的信息或解。在求解最优Golomb ruler时,如果存在大量的mirror solutions,那么这些解会在解空间中占据不必要的位置,导致搜索效率降低。
      • 计算效率:避免mirror solution可以减少搜索空间,从而提高求解最优Golomb ruler的计算效率。当算法在搜索最优解时,如果不加区分地考虑mirror solutions,它将不得不处理大量的重复或等效解,这会增加计算时间和资源消耗。
      • 解的唯一性:在科学研究和实际应用中,通常追求的是唯一且最优的解。Mirror solution并不增加解的多样性或提供额外的洞察力,因此,在求解过程中将其排除有助于提高解的质量和独特性。
      • 简洁性和可解释性:避免mirror solution还有助于保持解的简洁性和可解释性。在科学研究中,简洁且易于解释的解往往更具吸引力和实用价值。
      • 综上所述,为了避免不必要的重复、提高计算效率、保证解的唯一性以及保持解的简洁性和可解释性,在求解Golomb ruler问题时应该避免mirror solution。这可以通过在搜索过程中实施对称性破坏约束或后处理步骤来实现,以确保只获得唯一的、非镜像的解。
    • 第五个约束条件其实是目标函数
mdl.add(mdl.all_diff(dist))
mdl.add(marks[0] == 0)
for i in range(1, ORDER):
    mdl.add(marks[i] > marks[i - 1])
mdl.add((marks[1] - marks[0]) < (marks[ORDER - 1] - marks[ORDER - 2]))
mdl.add(mdl.minimize(marks[ORDER - 1]))
  • 对问题进行求解
    • 注意更改本地路径
msol = mdl.solve(TimeLimit=100,
                 agent='local',
                 execfile=r'C:\Program Files\IBM\ILOG\CPLEX_Enterprise_Server1210\CPLEX_Studio\cpoptimizer\bin\x64_win64\cpoptimizer.exe')
  • 打印结果
if msol:
    print("solution: " + msol.get_solve_status())
    print('标记的位置为')
    for v in marks:
        print(msol[v], end=',')
    print()
    print("求解时间:" + str(round(msol.get_solve_time(), 2)))
else:
    print(msol.get_solve_status())

solution: Optimal
标记的位置为
0,1,4,9,15,22,32,34,
求解时间:0.14
还有三个不同任务的相关内容后续做介绍

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值