2024 年 9 月 6 日:在开始讨论问题本身之前,让我们先看看背景故事。挑战,书中的开放数学挑战。
图书馆里一本 1984 年的旧书,我忘了书名,但我在“更多阅读内容...”部分看到了它的一个非常有趣的问题的图片。
一个,呃,诗谜……是的,你没听错,是一道以古英语诗歌形式写成的数学问题。
从高中起我就不再喜欢诗歌了,但是,这首引起了我的注意。当我读到它的时候,我觉得我明白了一些东西,但又不完全明白。花了六个多小时来理解寓言中的谜题,比如龙之类的。但是,有一件事让我着迷,那就是宝石。为了让你充分理解,这里有一首诗:
**在佐普拉里亚无尽而奇妙的土地上,星星静静地嗡嗡作响,
远古巨龙守护着时间与潮汐合一的天空,
一位智慧的老圣人安静地生活,他的知识跨越了所有的时间,
他们的双手可以像诗人吟诗一样编织魔法的丝线。
有一天,从天堂的高处,乘着火与金的翅膀,
正如神话和传说所言,圣人的礼物降临:
巨大的宝藏——充满光芒四射的宝石,就像星星的碎片,
然而却与命运自己的预言联系在一起,其规则与火星一样古老。
天堂向他低语,一条轻柔但清晰的信息:
“小心地用心和耳朵将这些发光的宝石分成两部分。
让你精心制作的两个容器承受几乎共同的重量,
他们之间的和谐是明亮而公平的平衡。
但是请听我们说,贤者,如果完美的匹配超出了你的理解范围,
不要对你的追求感到绝望,因为你的旅程仍然不会结束。
因为即使平衡倾斜,但可能会有轻微的偏移,
天堂仍会对你微笑,祝福将自由流淌。”
圣人怀着勇敢与智慧的心,开始了他神圣的考验,
把器皿造得差不多,给明星最好的。
龙在高空盘旋,天使在飞行中停顿,
因为在这个平衡的任务中蕴藏着如光般纯净的真理。
宝石,就像来自过去的秘密,在圣人转变之前,
每一次选择,命运就已成型,心开始燃烧。
虽然工作艰巨,但明星们还是很佩服
这位圣人用稳健的双手寻求平衡宇宙之火。
以及故事如何在无尽的天空下结束,
只有那些寻求并敢于抬起眼睛的人知道。
在佐普拉里亚无边无际的国度,古老的故事永存,
有人说圣人犹思,心清净。
因为在寂静的天空中存在着一种微妙而罕见的平衡,
只有双手稳健的人才能分享的和谐。**
这就是这首诗,看起来很奇怪吧。它在一本数学书中做了什么。这不是一个新的谜题,一个 1600 年代的谜题,写在现代威斯敏斯特的某个地方。
不过AI是我们的好朋友对吧,我问它回答的很奇怪,看起来连狗屎都听不懂。
它以为是我创造了它,但其实不是我。但是,GPT-4 呢?我们就问它知不知道什么。它成了我的英语老师。
好的,需要自己解码。我们来试试吧。
2024 年 9 月 9 日:“将这些发光的宝石分成两部分,小心心和耳朵。
让你精心制作的两个容器承受几乎共同的重量,
他们之间的和谐是明亮而公平的平衡。
但是请听我们说,贤者,如果完美的匹配超出了你的理解范围,
不要对你的追求感到绝望,因为你的旅程仍然不会结束。
因为即使平衡倾斜,但可能会有轻微的偏移,
天堂仍会对你微笑,祝福将自由流淌。”
这是故事的主要部分,让我们来解码它。
经过一番集思广益,抱歉,连续折磨自己三天多,我终于有了线索。
宝石可能是数字,正如它所说的“用心聆听”。
容器可能是集合,但集合的概念直到那时才被发现,所以,我可能是错的。
上述摘录可能意味着两组元素数量相等,或者该组中的数字之和相等。如果总和不相同,可能会显示最接近的。
2024年9月15日:经过一些更复杂的思考并发布了许多补充文章。我想是的,我可能在这首诗中找到了我最好的想法。
虽然这首诗已经很古老了,但我找不到任何其他的答案来解释这首诗。但是,我已经提出了每个人都能理解的问题,包括我。
从C.S.的角度来看,是的,我会先用C.S.的形式,然后再用数学的形式。
我们得到了一个整数列表。我们的任务是将列表分成两个子列表,以使它们总和的绝对差最小化。如果存在完美分割,我们需要返回两个列表。否则,返回总和差值最小的两个列表。
Input: [3, 1, 4, 2, 2] Output: ([2, 4], [3, 1, 2])
在此示例中,将列表拆分为 [3, 4] 和 [1, 2, 2] 得出的和为 7 和 5,并且绝对差最小化为 2。
那么让我们开始编码吧。
2024 年 9 月 16 日:
from itertools import combinations def minimize_difference(lst): total_sum = sum(lst) n = len(lst) # Generate all possible subsets best_diff = float('inf') best_split = ([], []) for i in range(1, n//2 + 1): for subset in combinations(lst, i): subset_sum = sum(subset) other_sum = total_sum - subset_sum diff = abs(subset_sum - other_sum) if diff < best_diff: best_diff = diff best_split = (list(subset), [x for x in lst if x not in subset]) return best_split # Example usage lst = [3, 1, 4, 2, 2] result = minimize_difference(lst) print("Split lists:", result)
代码比我的大脑运行得更好这一事实真是令人惊讶。
将一个列表分成两个子列表以使它们总和之间的绝对差异最小化的问题源于一个令人着迷的数学挑战。让我们来分析一下所提供的 Python 代码是如何解决这个问题的。
理解问题:
目标是从给定列表中找到两个子列表,使其总和尽可能接近。如果存在完美分割(两个子列表的总和相等),我们返回两个子列表。否则,我们返回两个总和之间的差异最小的分割。
代码结构:
代码的核心在于从列表中生成所有可能的元素组合以形成子列表之一。一旦选择了一个子列表,另一个子列表将由剩余的元素自动形成。然后,我们比较它们的总和,以找到差异最小的最佳分割。
combinations(lst, i):这会从列表中生成长度为 i 的所有可能组合。对于每个子集,它模拟一个子列表,而其余元素形成另一个子列表。
total_sum = sum(lst):计算列表的总和。它用于通过从总和中减去当前子集的总和来轻松确定其他子列表的总和。
best_diff = float('inf'):我们用一个大数字(无穷大)初始化变量 best_diff 以跟踪迄今为止发现的最小差异。当我们遍历每个可能的分割时,如果发现较小的差异,我们就会更新该值。
找到最佳分割:对于生成的每个子集,代码计算两个子列表之和之间的差。如果当前差异小于 best_diff,则更新分割。
性能注意事项:
该代码使用 itertools 库中的组合函数来探索不同长度的子集。虽然此方法适用于相对较小的列表,但由于可能的子集呈指数增长,因此对于较大的列表可能不是最佳选择。对于更大的输入,可以考虑更有效的算法,例如动态规划。
示例输出:
在提供的示例中:
lst = [3, 1, 4, 2, 2] result = minimize_difference(lst) print("Split lists:", result)
该函数将列表拆分为 [2, 4] 和 [3, 1, 2],结果分别为 6 和 6,差值最小为 0,这是本例中的最优解。
您看到的以上内容是我的日记摘录,100%真实。但与她的传奇版本相比,还有一个更“传奇”的版本
以上是诗意的挑战!?的详细内容。更多信息请关注PHP中文网其他相关文章!