置换编程挑战的困难“;山羊“;用Python

置换编程挑战的困难“;山羊“;用Python,python,permutation,Python,Permutation,我被分配了一项任务-解决以下编程难题: 山羊 乔治和他的一群山羊在河边。他想用一个重量有限的木筏带着他的山羊过河,木筏的航向不超过K。他的山羊都不同,体重也不同。他想计算筏的最小承载力是多少,它能让所有的N山羊在不超过K路线的情况下通过河流。 但是,他有必须遵守的规则: 在每一个过程中,他首先把最重的山羊放在木筏上,然后从剩下的山羊中再放一只对木筏的容量来说不会太重的最重的山羊,然后再放下一只,依此类推,直到因为木筏的容量,没有更多的山羊可以放在木筏上。在那之后,他把它们带到对岸(划出一条航线)

我被分配了一项任务-解决以下编程难题:

山羊
乔治和他的一群山羊在河边。他想用一个重量有限的木筏带着他的山羊过河,木筏的航向不超过K。他的山羊都不同,体重也不同。他想计算筏的最小承载力是多少,它能让所有的N山羊在不超过K路线的情况下通过河流。
但是,他有必须遵守的规则:
在每一个过程中,他首先把最重的山羊放在木筏上,然后从剩下的山羊中再放一只对木筏的容量来说不会太重的最重的山羊,然后再放下一只,依此类推,直到因为木筏的容量,没有更多的山羊可以放在木筏上。在那之后,他把它们带到对岸(划出一条航线),然后回来把更多的山羊放在木筏上,再划出另一条航线。(木筏的承载力必须至少与最重的山羊重量相同)

因此,我需要编写一个脚本,计算给定航向K、山羊数量N、以及每只山羊的重量(A1、A2等等)下筏的最小承载力。由于它是一个相对较小的常数,因此忽略了George的权重(无需将其添加到计算中)

到目前为止,所有记录都符合挑战的要求

正确解决方案的结果示例:

(A | B C), (A B | C)
(A | C B), (A C | B) 
(B | A C), (B A | C)
(B | C A), (B C | A)
(C | B A), (C B | A)
(C | A B), (C A | B)
6只山羊,2道菜
每只山羊的体重:26,7,10,30,5,4
结果(筏的最小承载力):42
课程有:(30、10);(26,7,5,4)
以下解决方案不符合规则:(30,7,4);(26,10,5)-因为体重10公斤的山羊可以在第一道菜中,并且必须按照规则在那里

我的解决方案尝试:

import itertools

goatnum = 0
courses = 0
goatw = []
counter = 0

goatnum = int(input("Enter the number of goats: "))
courses = int(input("Enter the number of courses: "))
for g in range(goatnum):
    goatw.append(int(input("Enter the weight of goat #{}: ".format(g+1))))

goatw = sorted(goatw, reverse=True)
goats = sum(goatw)
result = []
permlen = len(goatw)/courses
while not result:
    result = [seq for i in range(len(goatw), 0, -1) for seq in itertools.permutations(goatw, permlen) if sum(seq) == int(goats/courses)]
    if not result:
        goats += 1
        permlen += 1
    else:
        break

print(result)
我在任务中使用排列,只是因为我不知道另一种方法。目前,从结果中,我只得到不遵守规则的解决方案(对于给定的示例)。我得到了解决方案
(30,7,4);(26,10,5)
然而,在内部,即使一个课程的山羊数量与3只不同,也没有结果,所有课程都有3只山羊

我对给定示例的输出(6只山羊,2个课程,w:26,7,10,30,5,4):


我对这类事情还不熟悉,我还从互联网上得到了使用排列的例子。我的代码哪里错了?我知道我可以做一个函数来检查我得到的结果是否符合规则,如果不符合,修复结果,但我不知道该怎么做。任何帮助都将不胜感激。

我相信您遇到的问题是,您生成的所有排列都由3只山羊组成。如果要生成N个山羊的所有可能排列,然后在K个位置切片这些排列,正确的解决方案将是这些列表中的一个。例如,对于3只山羊,
A
B
C
我们得到以下排列:

(A,B,C),(A,C,B),(B,A,C),(B,C,A),(C,B,A),(C,A,B)

假设我们有两门课。现在假设我们有K-1棒(本例中为1),我们可以将其放置在每个排列中的N-1个位置(本例中为2个)。一根棍子可以放在任何山羊之间或边缘。棍子作为一个分隔物,决定每一次旅行的山羊是哪一组。在一般情况下,你有K-1棒的地方,你不想把两个棒放在同一个地方,因为这意味着你将有一次旅行,没有山羊在船上。然后,我们可以在以下空间中搜索解决方案:

(A | B C), (A B | C)
(A | C B), (A C | B) 
(B | A C), (B A | C)
(B | C A), (B C | A)
(C | B A), (C B | A)
(C | A B), (C A | B)
请注意,您可以在最左边“放置棍子”,也就是说,将有一个空行程和一个所有山羊都去的行程,但显然在这里找不到最佳解决方案,因为使用尽可能多的行程总是更好的。请注意,由于山羊需要按顺序加载,因此这些可能性中的许多都不会遵守规则,因此需要对这些结果进行过滤,以删除那些不遵守规则的结果

从这里开始,只需找出这些可能性中的哪一个需要最小容量的船,这可以通过计算每个可能性中的最大总和并选择该总和最小的可能性来计算

综上所述,使用排列解决这个问题的一种方法是:

  • 生成所有可能的山羊排列

  • 生成每个排列可以细分为K组的所有方式

  • 清除步骤2生成的任何不遵守规则的候选项

  • 从剩下的候选者中,找出最重行程比其他候选者中最重行程轻的一个


  • 这决不是一个最优的解决方案,但它应该能解决问题。

    这是一个典型的贪婪问题。在谷歌上搜索贪婪编程,你可以找到相当多的教程。先看一下你是否能解决这个问题。