数学建模练习小题目

news/2024/12/21 21:12:14/

题目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/news/1537179.html

相关文章

每日一题|3162. 优质数对的总数 I、II|因子分解、计数方法

第一题非常简单的暴力解法。 class Solution:def numberOfPairs(self, nums1: List[int], nums2: List[int], k: int) -> int:nums2_ [i * k for i in nums2]count 0for i in nums1:for j in nums2_:count 0 if i % j else 1return count 第二题的难度提升在数量级在10万…

代码随想录算法训练营第四十六天 | 647. 回文子串,516.最长回文子序列

四十六天打卡,今天用动态规划解决回文问题,回文问题需要用二维dp解决 647.回文子串 题目链接 解题思路 没做出来,布尔类型的dp[i][j]:表示区间范围[i,j] (注意是左闭右闭)的子串是否是回文子串&#xff0…

mDNS的服务类型

当使用 mDNS (Multicast DNS) 和 DNS-SD (DNS Service Discovery) 进行服务发现时,可以通过指定不同的服务类型来查找不同类型的设备或服务。以下是一些常见的 mDNS 服务类型示例: 通用服务类型 服务类型描述_services._dns-sd._udp服务发现服务类型&a…

LeetCode:134. 加油站(Java 贪心)

目录 134. 加油站 题目描述: 实现代码与解析: 贪心 原理思路: 134. 加油站 题目描述: 在一条环路上有 n 个加油站,其中第 i 个加油站有汽油 gas[i] 升。 你有一辆油箱容量无限的的汽车,从第 i 个加油…

Spring Boot 快速入门教程

1. Spring Boot 简介 Spring Boot 是一个基于 Spring 框架的项目,它简化了基于 Spring 的 Java 应用程序的创建和部署。Spring Boot 通过提供一系列的“Starters”来简化 Maven 配置,同时使用约定大于配置的原则,让开发者能够以最少的配置启…

Android Studio Koala Feature Drop 稳定版现已推出

作者 / Android Studio 产品经理 Sandhya Mohan Android Studio Koala Feature Drop (2024.1.2) 现已推出!🐨 🔗 Android Studio https://developer.android.google.cn/studio 今年早些时候,我们宣布每个 Android Studio 动物版本…

如何自制无人机?

自制无人机是一个既有趣又富有挑战性的项目,它涉及到电子工程、机械工程和航空航天工程等多个领域的知识。以下是一个基本的自制无人机制作步骤和所需材料概览,供您参考: 一、准备阶段 1. 明确目标 - 确定无人机的用途(如航拍、…

rabbitMq-----消费者管理模块

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言消费者字段消费者内存管理类新增/删除消费者 总的消费者管理类 前言 只有订阅客户端订阅了一个队列消息后,他才是一个消费者,而消费者存…