热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python解决数学建模问题:赛程安排

五支足球队在同一场地上进行足球赛。进行单循环比赛,也就是说这五支球队的每两支球队在这次比赛中都要结对比赛一次。共进行十场比赛,在连续的十天中每天比赛一场
五支足球队在同一场地上进行足球赛。进行单循环比赛,也就是说这五支球队的每两支球队在这次比赛中都要结对比赛一次。共进行十场比赛,在连续的十天中每天比赛一场。问:如何安排这次比赛的赛程对各队来说都是公平的?



公平定义:

各队在其相邻比赛的最小的间隔场次达到最大的可能。

数学问题:

在所有赛程最小间隔场次中求最大。

考虑:

n 支球队的单循环赛的一个赛程。记最小的间隔场次为 r 。
于是,在这 r 场比赛前后的 2 场比赛中出现的 3 个队不参
与这 r 场比赛,而且有 2r 个不同的球队参加这 r 场比赛,
所以 2r ≤ n - 3 。
最大的可能就是 r = [ ( n - 3 ) / 2 ] 。



思路:

首先明确下面提及的概念,队组:即两个队伍搭配成一组,如[1,2]即1、2这两队组成一组。

一、定义节点和链表,及链表对应的初始化、获得头节点、遍历、加入元素、删除元素这些方法,对于每一个方法的详细介绍将在代码中体现。

class SingleNode(object):def __init__(self, item):# item存放数据元素,后面将会用来存放比赛的队组self.item = item# next是下一个节点的标识self.next = Noneclass SingleLinkList(object):# 初始化链表def __init__(self):self.__head = Nonedef is_empty(self):return self.__head == None# 获得该链表的头节点def get_first(self):return self.__head# 遍历链表,即按顺序打印出链表节点的内容def travel(self):cur = self.__headi=1while cur != None:print("第{}场:{}".format(i,cur.item))i+=1cur = cur.next# 向链表中增加节点,这里采用的是在链表的尾部加入,采用这种加入方式是和我们后面具体的算法有关def append(self, item):node = SingleNode(item)if self.is_empty():self.__head = nodeelse:cur = self.__headwhile cur.next != None:cur = cur.nextcur.next = node# 删掉节点,根据item的内容进行删除,因为我们后面比赛中的队组并不会重复,所以这里不考虑item在链表中有多个对应节点的情况def remove(self, item):cur = self.__headpre = Nonewhile cur != None:if cur.item == item:if not pre:self.__head = cur.nextelse:pre.next = cur.nextbreakelse:pre = curcur = cur.next

二、具体代码实现。这里的代码实现的结果是打印出一种公平的赛程安排。因为不考虑A,B,C,D,E这5队的顺序,故不妨设这5支队伍为0,1,2,3,4,且集合{A,B,C,D,E}与集合{0,1,2,3,4}相等(用集合相等来表达的原因就是在于顺序可以随意交换)。

假定初始赛程顺序即为随机,那么已经求出各队相邻比赛场次的最小间隔为 r ,那么满足这一条件的赛程必然满足对于任意场次[i,j]其后的 r 场的参赛队伍内均无 i 和 j 这两队,后面这一情况当然是一个充分条件。

那么为了满足其必要性,我们从第一场依次进行检查,若第一场[0, 1]的后r场内存在 0 或 1 这两支队伍参加比赛,那么就将其参加比赛的队组调整到最后一场,以保证第一场后的 r 场均满足其后的 r 场比赛内 0 和 1 均为参赛,那么再对第二场的后 r 场进行同样检查。注意这里的第二场是经过调整后的顺序里的第二场。

以此类推检查,即可满足对于任意场次[i,j]其后的 r 场的参赛队伍内均无 i 和 j 这两队,同时也由此可以推出对于任意场次[i,j]其前的 r 场的参赛队伍内均无 i 和 j 这两队,那么这样的赛程即为公平的。

当然,这里的初始赛程可以随意给出,最后的赛程结果也会相应的变化,另外,这里的0,1,2,3,4并未指明是哪一支队伍,故也可以随意替换,但无论如何,最终打印出来的结果均满足“公平”这一关键条件。

这里可以调节队伍数量 n 的值即可计算出结果,这里将 n 取为66,可得到66支队伍的公平赛程安排,且由于初始安排的随机性,每一次运行可以得到不同且公平的赛程安排。

from itertools import permutations
import numpy as np
# n表示队伍数量
n = 66
# N表示比赛场数
N = n*(n-1)//2
# 确定最小间隔r
r = (n-3)//2
# code用来存放比赛的二队组
code = []# 将队组存入code
for i in range(n):for j in range(i+1, n):code.append([i, j])
# 打乱code的顺序,一方面是验证代码的正确性,另一方面也是通过随机顺序尽量减少代码循环执行的次数
np.random.shuffle(code)
# 将code以节点的形式加入到链表llist中
llist = SingleLinkList()
for i in range(N):llist.append(code[i])
# chosen表示当前被检查的队组
# choosing表示当前正在和chosen对应的队组进行比较的后r场中的队组
chosen = llist.get_first()
choosing = SingleNode(1)
num = N-r
for j in range(num):k &#61; 0choosing &#61; chosen.next# 下面这一个while进行的是对chosen的后r场进行检查的循环while k < r and not choosing:choosing &#61; choosing.nextk &#43;&#61; 1# 下面这一个while是对choosing及其后不满足条件的队组进行调整的过程while choosing.item[0] in chosen.item or choosing.item[1] in chosen.item:change &#61; choosing.itemchoosing &#61; choosing.nextllist.remove(change)llist.append(change)if choosing &#61;&#61; None:breakchosen &#61; chosen.next
# 打印结果
print("最小间隔为&#xff1a;{}".format(r))
print(" ")
print("赛程安排如下&#xff1a;")
print(" ")
llist.travel()

附一张我运行的结果图&#xff1a;
在这里插入图片描述


用这种想法解决问题的起源&#xff1a;

我上课的时候学习的是另一种方法&#xff0c;好处是可以将所有的“公平的”赛程安排算出来&#xff0c;但是它的局限性是运行的时间太长&#xff0c;且因为考虑了五支队伍的差别&#xff0c;重复计算了多种赛程&#xff0c;比如他既考虑了&#xff08;A,B,C,D,E&#xff09;对应的所有公平赛程安排&#xff0c;也考虑了&#xff08;B,A,C,D,E&#xff09;的所有公平赛程安排&#xff0c;其实会发现这两种安排中会存在许多相同的公平赛程安排。

所以我就尝试用别的方法来减少运行时间&#xff0c;最后得到的就是上面这种方法。大家也可以看到这种方法结果上面的问题的好处是可以较快地运行出结果&#xff0c;这种方法先通过设置初始赛程顺序解决队伍差别问题&#xff0c;运用数据结构的知识来进行调整顺序得到结果。

但是这种方法局限性在于因最后的运行结果与初始赛程顺序&#xff08;随机产生&#xff09;和调整方法相关&#xff0c;只要调整成功便不再继续调整&#xff0c;所以运行结果唯一&#xff0c;没有办法呈现出所以的赛程安排&#xff08;想想其实可能再调整会有其他结果或者把调整方法改一下也会出现其他结果&#xff0c;但是这样我就兼顾不到我的速度了&#xff09;。

如果大家有可以兼顾速度和结果数量的思路&#xff0c;欢迎一起讨论&#xff01;


推荐阅读
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • 向QTextEdit拖放文件的方法及实现步骤
    本文介绍了在使用QTextEdit时如何实现拖放文件的功能,包括相关的方法和实现步骤。通过重写dragEnterEvent和dropEvent函数,并结合QMimeData和QUrl等类,可以轻松实现向QTextEdit拖放文件的功能。详细的代码实现和说明可以参考本文提供的示例代码。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • 不同优化算法的比较分析及实验验证
    本文介绍了神经网络优化中常用的优化方法,包括学习率调整和梯度估计修正,并通过实验验证了不同优化算法的效果。实验结果表明,Adam算法在综合考虑学习率调整和梯度估计修正方面表现较好。该研究对于优化神经网络的训练过程具有指导意义。 ... [详细]
  • Android JSON基础,音视频开发进阶指南目录
    Array里面的对象数据是有序的,json字符串最外层是方括号的,方括号:[]解析jsonArray代码try{json字符串最外层是 ... [详细]
  • 本文详细介绍了Spring的JdbcTemplate的使用方法,包括执行存储过程、存储函数的call()方法,执行任何SQL语句的execute()方法,单个更新和批量更新的update()和batchUpdate()方法,以及单查和列表查询的query()和queryForXXX()方法。提供了经过测试的API供使用。 ... [详细]
  • Python瓦片图下载、合并、绘图、标记的代码示例
    本文提供了Python瓦片图下载、合并、绘图、标记的代码示例,包括下载代码、多线程下载、图像处理等功能。通过参考geoserver,使用PIL、cv2、numpy、gdal、osr等库实现了瓦片图的下载、合并、绘图和标记功能。代码示例详细介绍了各个功能的实现方法,供读者参考使用。 ... [详细]
  • YOLOv7基于自己的数据集从零构建模型完整训练、推理计算超详细教程
    本文介绍了关于人工智能、神经网络和深度学习的知识点,并提供了YOLOv7基于自己的数据集从零构建模型完整训练、推理计算的详细教程。文章还提到了郑州最低生活保障的话题。对于从事目标检测任务的人来说,YOLO是一个熟悉的模型。文章还提到了yolov4和yolov6的相关内容,以及选择模型的优化思路。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
author-avatar
mobiledu2502877091
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有