数学建模练习小题目

devtools/2024/10/18 1:49:00/

题目A

有三名商人各带一名仆人过河,船最多能载两人。在河的任何一岸,若仆人数超 过商人数,仆人会杀商人越货。如何乘船由商人决定,问是否有安全过河方案,若有,最少需要几步?

定义变量

商人和仆人的状态:使用状态 (M, S) 来表示某一岸上的商人数和仆人数。

船的状态:由于船只能在两岸之间移动,使用一个二元变量来表示船的位置,1 表示船在左岸(起始岸),0 表示船在右岸(目标岸)。

因此,系统的一个状态可以表示为三元组 (M, S, B),其中,M 表示左岸的商人数,S 表示左岸的仆人数,B 表示船的位置(左岸或右岸),定义初始状态为 (3, 3, 1),目标状态为 (0, 0, 0),即所有人都在右岸。

状态转换

在问题的解决过程中,船一次可以带1或2人过河,因此允许的操作包括一名商人和一名仆人一起过河 (1, 1),两名商人一起过河 (2, 0),两名仆人一起过河 (0, 2),一名商人过河 (1, 0),一名仆人过河 (0, 1)

基于当前船所在的位置,商人和仆人要么从左岸到右岸(如果船在左岸),要么从右岸到左岸(如果船在右岸)。

合法状态条件:

如果左岸有商人和仆人,必须满足左岸的商人数 >= 左岸的仆人数。

如果右岸有商人和仆人,也必须满足右岸的商人数 >= 右岸的仆人数。

如果某岸没有商人,则无需考虑仆人数量。

目标函数

问题的目标是找到一种安全的过河策略,使得所有商人和仆人安全过河,并且最少步数完成过河过程。步数是需要最小化的目标函数。

约束条件

  1. 每次船的载重不能超过两人。

  2. 每次过河之后,任何一岸的仆人数不能超过商人数。

  3. 商人决定乘船方案,仆人不能独立决定过河。

BFS求解

广度优先搜索(BFS)是一种常用来寻找最短路径的算法,适合用来解决这种问题。

具体步骤如下:

  1. 从初始状态 (3, 3, 1) 开始,加入队列。

  2. 对于队列中的每个状态,尝试所有可能的合法过河方式,生成新状态。

  3. 如果新状态满足安全条件并且没有被访问过,将其加入队列。

  4. 当某个状态到达目标状态 (0, 0, 0) 时,停止搜索,返回路径。

  5. 如果所有状态都搜索完毕还没有找到解,则说明问题无解。

python">from collections import deque
​
# 定义初始状态 (左岸商人数量, 左岸仆人数量, 船所在岸 1表示左岸, 0表示右岸)
initial_state = (3, 3, 1)
goal_state = (0, 0, 0)
​
# 检查状态是否合法
def is_valid(state):left_m, left_s, _ = stateright_m = 3 - left_mright_s = 3 - left_s# 检查两岸的商人数和仆人数比例if (left_m >= 0 and left_s >= 0 and left_m >= left_s) or left_m == 0:if (right_m >= 0 and right_s >= 0 and right_m >= right_s) or right_m == 0:return Truereturn False
​
# 使用BFS算法来搜索最优解
def bfs():queue = deque([(initial_state, [])])  # 队列保存当前状态和走过的路径visited = set()  # 记录已经访问过的状态visited.add(initial_state)while queue:current_state, path = queue.popleft()# 如果到达目标状态,返回路径if current_state[:2] == goal_state[:2] and current_state[2] == goal_state[2]:return path + [current_state]left_m, left_s, boat = current_statenew_boat = 1 - boat  # 切换船所在的岸# 定义所有可能的船的移动情况moves = [(1, 0), (0, 1), (1, 1), (2, 0), (0, 2)  # (商人移动数量, 仆人移动数量)]for move_m, move_s in moves:if boat == 1:  # 如果船在左岸new_state = (left_m - move_m, left_s - move_s, new_boat)else:  # 如果船在右岸new_state = (left_m + move_m, left_s + move_s, new_boat)# 检查新状态是否合法if is_valid(new_state) and new_state not in visited:visited.add(new_state)queue.append((new_state, path + [current_state]))
​return None
​
# 运行BFS算法
result = bfs()
​
if result:print("找到安全过河方案,最少步骤为:", len(result) - 1)for step in result:print(step)
else:print("没有找到安全过河方案。")

求解结果

找到安全过河方案,最少步骤为: 11
(3, 3, 1)
(2, 2, 0)
(3, 2, 1)
(3, 0, 0)
(3, 1, 1)
(1, 1, 0)
(2, 2, 1)
(0, 2, 0)
(0, 3, 1)
(0, 1, 0)
(1, 1, 1)
(0, 0, 0)

得到方案如下:

商人和仆人最少经过11步安全渡河。首先,一名商人和一名仆人过河,两岸各有2名商人和2名仆人。接着,一名仆人回到左岸,左岸有3名商人和2名仆人。然后,两名仆人过河,左岸剩下3名商人,右岸有3名仆人和2名商人。接着一名仆人返回左岸,左岸有3名商人和1名仆人。随后,两名商人过河,左岸剩下1名商人和1名仆人。接着一名商人和一名仆人返回,左右岸再次各有2名商人和2名仆人。然后两名商人过河,左岸只剩下仆人,右岸有4名商人和2名仆人。接着一名仆人回到左岸,左岸有1名仆人,右岸有4名商人和1名仆人。随后两名仆人过河,右岸所有人到达。最后,一名仆人回到左岸,并带着最后的商人和仆人安全到达右岸,完成全部渡河过程。

问题C

四个著名的音乐人受邀成为一场音乐比赛的评委,评委席的座次安排一他们互相谦让,最后组委会不得不让他们投票选出自己心中的座次安排,如果你是组委会拿到了如下的投票结果,请问你将如何安排座次?(注:排在最前面的坐首席)

甲:乙丙甲丁
乙:丙甲丁乙
丙:甲丙丁乙
丁:甲丙乙丁

解:根据每个人的投票顺序,为每个评委进行排序打分。排名越靠前,得分越高。假设排名第一得 3 分,排名第二得 2 分,排名第三得 1 分,排名第四得 0 分;然后将所有投票结果进行加总,得出每位评委的总分,分数高者安排在靠前的位置。

编写代码如下:

python"># 定义每位评委的投票顺序
votes = {'甲': ['乙', '丙', '丁', '甲'],'乙': ['丙', '甲', '丁', '乙'],'丙': ['甲', '丙', '丁', '乙'],'丁': ['甲', '丙', '乙', '丁']
}
# 初始化得分表
scores = {'甲': 0, '乙': 0, '丙': 0, '丁': 0}
# 给每个评委根据投票顺序打分
for voter, ranking in votes.items():# 第一名得3分,第二名得2分,第三名得1分,第四名得0分for i, candidate in enumerate(ranking):scores[candidate] += 3 - i
# 按得分从高到低排序
sorted_scores = sorted(scores.items(), key=lambda x: x[1], reverse=True)
# 输出最终座次安排
print("最终座次安排:")
for i, (name, score) in enumerate(sorted_scores, 1):print(f"第{i}名: {name},得分: {score}")

求得结果:

最终座次安排:
第1名: 丙,得分: 9
第2名: 甲,得分: 8
第3名: 乙,得分: 4
第4名: 丁,得分: 3

故应将座位安排为丙甲乙丁。


http://www.ppmy.cn/devtools/122101.html

相关文章

[大语言模型-论文精读] 悉尼大学-ACL2024-提升大型语言模型的复杂视觉推理能力

[大语言模型-论文精读] 悉尼大学-ACL2024-提升大型语言模型的复杂视觉推理能力 目录 文章目录 [大语言模型-论文精读] 悉尼大学-ACL2024-提升大型语言模型的复杂视觉推理能力目录论文简介0. 摘要2. 相关工作2.1 视觉-语言领域的推理研究2.2 用于视觉-语言分析的大型语言模型 3 …

【PostgreSQL】提高篇——PostgreSQL 对 JSON 和数组的支持及其在数据建模中的应用

数据的多样性和复杂性日益增加,传统的关系型数据库结构往往难以灵活应对这些变化。PostgreSQL 作为一个强大的开源关系数据库管理系统,提供了对 JSON 和数组数据类型的原生支持,使得开发者能够更灵活地进行数据建模和存储。 一、背景与重要性…

ROS C++ : 控制 rosbag 包的录制与停止

文章目录 1. 终端操作1.1. 录制指定话题1.2. 录制所有话题1.3. 其它录制参数1.4. 自动打开新的终端并执行录制 2. C代码2.1. 录包2.2. 停止录包 我们经常会用rosbag来录一些ROS的消息进行离线调试什么的。如果是在终端运行,输入命令,然后Ctrl C就可以运…

基于keras的停车场车位识别

1. 项目简介 该项目旨在利用深度学习模型与计算机视觉技术,对停车场中的车位进行检测和状态分类,从而实现智能停车管理系统的功能。随着城市化的发展,停车场管理面临着车位检测效率低、停车资源分配不均等问题,而传统的人工检测方…

Hive数仓操作(八)

一、Hive中的分桶表 1. 分桶表的概念 分桶表是Hive中一种用于提升查询效率的表类型。分桶指的是根据指定列的哈希值将数据划分到不同的文件(桶)中。 2. 分桶表的原理 哈希分桶:根据分桶列计算哈希值,对哈希值取模,将…

中安未来 OCR—— 开启文字识别新时代

在数字化的浪潮中,高效准确的文字识别技术正发挥着越来越重要的作用。今天,我要向大家介绍一款令人惊艳的 OCR 解决方案 —— 中安未来 OCR。 一、初识中安未来 OCR 中安未来 OCR 以其强大的功能和卓越的性能,在众多文字识别工具中脱颖而出。…

RabbitMQ 优点和缺点

优势: 消息可靠性:RabbitMQ 提供了持久化功能和消息确认机制,确保消息在各种情况下都能可靠地存储和处理。 灵活的路由:通过多种交换机类型和绑定规则,RabbitMQ 能够灵活地路由消息到指定的队列。 支持多种消息协议&am…

OpenCV视频I/O(9)视频采集类VideoCapture之释放与视频捕获相关的所有资源函数release()的使用

操作系统:ubuntu22.04 OpenCV版本:OpenCV4.9 IDE:Visual Studio Code 编程语言:C11 算法描述 关闭视频文件或捕获设备。 该方法由随后的 VideoCapture::open 和 VideoCapture 析构函数自动调用。 C 函数还释放内存并清除 *capture 指针。 …