欧拉路径和欧拉回路
![sketch of my solution algorithm](https://i-blog.csdnimg.cn/blog_migrate/5eb2965e5c2a09693671dcf0986424c7.jpeg)
sketch of my solution algorithm
我的求解算法示意图
最大路径和I (Maximum Path Sum I)
Warning: Please only read this post, when you are absolutely sure, that you don’t want to take part in the challenge that is Project Euler. My posts will spoil the solution for you. I’m posting my solutions to show one possible way on how to solve the problems in case you want to compare your solutions with mine or are stuck and gave up on solving the problem.
警告:只有在绝对确定不希望参加Euler项目这一挑战时,才请阅读此文章。 我的帖子将为您破坏解决方案。 我要发布解决方案,以显示一种解决问题的可能方法,以防您想将自己的解决方案与我的解决方案进行比较,或者被卡住而放弃解决问题。
So this Project Euler Problem asks you to find the largest sum that can be produced by adding up numbers through a chain with the adjacent numbers following in the row below in a triangle. The triangle we are supposed to solve for this problem looks like this:
因此,这个欧拉项目问题要求您找到一个最大的总和,该总和可以通过将一条数字与下面的三角形下面一行中的相邻数字相加而得出。 我们应该为这个问题解决的三角形看起来像这样:
![Triangle from Problem 18](https://i-blog.csdnimg.cn/blog_migrate/45d74bb46efed5b3a06bbeb81ab6d45b.png)
Number Triangle from Problem 18
问题18中的数字三角形
There is a hint in the problem description mentioning, that this number triangle (with edge lengths of 15) only has 16384 possible routes from top to bottom. This number is small enough to be quickly solved by simply calculating and comparing each paths sum, but later on in Project Euler Problem 67 we get a triangle with side lengths of a hundred, giving it 299 possible paths, with is far too large to be calculated in a timely fashion anytime soon. So we are already going to try to solve Problem 18 in a smart way, to make our lives easier, when we arrive at Problem 67.
问题描述中提到了一个提示,即这个三角形(边长为15)从上到下只有16384条可能的路线。 这个数字足够小,可以通过简单地计算和比较每个路径的总和来快速解决,但是后来在Project Euler问题67中,我们得到了一个边长为100的三角形,给了它2 99条可能的路径,但太大了以至于尽快得到及时计算。 因此,当我们到达问题67时,我们已经将尝试以聪明的方式解决问题18,以使我们的生活更轻松。
The Algorithm
算法
There is a easy way to find the maximum path. We know, that the maximum path has to go through the very top value 75, since every possible path starts there. It would also mean that the maximum path subtracting the 75 would be the maximum path up to the second row, since the maximum path can only go through these two possible numbers in the second row to reach the 75. The true maximum path in the second row would therefore be the maximum between the maximum path that leads to 95 (the first value in the second row) and the maximum path that leads to 64 (the second value in the second row). These assumptions can be continued on until you reach the last row of the triangle. Our algorithm is going to take advantage of this knowledge.
有一种简单的方法可以找到最大路径。 我们知道,最大路径必须经过最高值75,因为所有可能的路径都从那里开始。 这也将意味着减去75的最大路径将是到达第二行的最大路径,因为最大路径只能经过第二行中的这两个可能的数字才能达到75。第二个路径中的真实最大路径因此,该行将是通向95的最大路径(第二行中的第一个值)与通向64的最大路径(第二行中的第二个值)之间的最大值。 可以继续进行这些假设,直到到达三角形的最后一行。 我们的算法将利用这一知识。
Our algorithm would start in the second to last row of the triangle and replace each number with its maximum sum of itself and the bottom left value of the last row and of itself and the bottom right value of the last row (the sketch at the top of this post may help understanding this step). The calculated values now represent the maximum paths that lead to this value when starting from the last row.
我们的算法将从三角形的第二行到最后一行开始,并用其自身与最后一行的左下角值及其自身与最后一行的右下角值的最大值之和替换每个数字(顶部的草图的帖子可能有助于理解这一步骤)。 现在,计算出的值表示从最后一行开始时导致该值的最大路径。
We are going to repeat this step until we reach the top of our triangle and as the sketch shows, you’ll have the maximum of the complete triangle replace the top value. And by following the path of the maximum adjacent numbers from the top to the bottom of the triangle you also can backtrack the path that yields the maximum path.
我们将重复此步骤,直到到达三角形的顶部为止,并且如草图所示,您将用完整的三角形的最大值替换顶部的值。 通过沿着三角形的顶部到底部跟踪最大相邻数的路径,您还可以回溯产生最大路径的路径。
码 (Code)
The code is similar to the previous problems that involved info from the Project Euler website. So I first parse the html page to save the number triangle as a list of lists. I then have a for loop starting at depth-2, the index of the second last line of the number triangle, and the third parameter -1 in range signifies to decrease i by minus one after each loop.
该代码类似于先前涉及到来自Euler项目网站的信息的问题。 因此,我首先解析html页面,以将数字三角形保存为列表列表。 然后,我有一个从深度2(数字三角形的倒数第二行的索引)开始的for循环,范围内的第三个参数-1表示在每个循环之后将i减一。
The built-in max function returns the highest value in the list given as parameter. We use this to compare the bottom-left and bottom-right value for their size. The bigger sum is then added to the above value. The result of this problem is then saved in the top number triangle value.
内置的max函数返回以参数形式给出的列表中的最大值 。 我们使用它来比较左下角和右下角的大小。 然后将较大的总和加到上述值上。 然后,此问题的结果将保存在顶部数字三角形值中。
"""Find maximum total from top to
bottom in the given triangle"""
import urllib.request
req = urllib.request.Request("https://projecteuler.net/problem=18")
response = urllib.request.urlopen(req)
the_page = response.read()
the_page_string = the_page.decode("utf-8")
counter = the_page_string.find("75<br />")
triangle = []
row = []
while(counter < len(the_page_string)):
# add number to list
row.append(int(the_page_string[counter:counter+2]))
counter += 2
if(the_page_string[counter] == " "):
counter += 1
elif(the_page_string[counter:counter+6] == "<br />"):
counter += 8 # +2 for n
triangle.append(row)
row = []
elif(the_page_string[counter:counter+4] == "</p>"):
triangle.append(row)
break
"""Start at second last row and replace by max of the two sums by either
adding to the bottom left or the bottom right."""
depth = len(triangle)
for i in range(depth-2,-1,-1):
for j in range(0,len(triangle[i])):
triangle[i][j] += max([triangle[i+1][j], triangle[i+1][j+1]])
print("Result: " + str(triangle[0][0]))
The computation needs about 0.452 seconds of processing time on my laptop, which is sufficient and should probably scale well enough for Problem 67 sometime later.
计算在我的笔记本电脑上需要大约0.452秒的处理时间,这足够了,并且可能会在以后的某个时候很好地扩展以解决问题67。
Problem 18 involved some work to come up with a clever algorithm to solve this problem. It was hard to do specific research on the topic, since its hard to classify this problem to a certain mathematical field. Writing the code didn’t offer too many troubles.
问题18涉及一些工作,需要一个聪明的算法来解决这个问题。 由于很难将这个问题归类到某个数学领域,因此很难对该主题进行具体的研究。 编写代码不会带来太多麻烦。
Hope it was a fun read, don’t be hesitant to send me suggestions on improving the algorithms via email at ratherreadblog@gmail.com or by leaving a comment at the post. You can also subscribe to my mailing list here if you always want to stay up-to-date with my newest posts and changes on the website.
希望这是一本有趣的文章,不要犹豫,可以通过电子邮件发送给我,有关改进算法的建议,方法是发电子邮件至prettyreadblog@gmail.com或在帖子中发表评论。 如果您始终想了解我最新的帖子和网站上的更改,也可以在这里订阅我的邮件列表 。
翻译自: https://www.pybloggers.com/2015/05/project-euler-18-maximum-path-sum-i/
欧拉路径和欧拉回路