Python 用预定义值填充一维空间
我想用预定义的“子长度”填充长度。 假设我的子长度是:3,4,5,6,7,10。 要填充15的长度,我可以使用“10+5”、“3+4+3+5”、“7+4+4”、“7+5+3”。。。。 我怎样才能得到这些结果中的一个? 更好:如何获得一个数组以获得几个好的结果?我的最大长度是70,我想要得到这个值的所有好结果可能会很耗时 我是一名3d艺术家,我的编码技能非常有限,我不知道如何处理这个问题。我可以使用Python或类似C的语言来解决这个问题 此代码似乎在我的软件中起作用:Python 用预定义值填充一维空间,python,c,algorithm,Python,C,Algorithm,我想用预定义的“子长度”填充长度。 假设我的子长度是:3,4,5,6,7,10。 要填充15的长度,我可以使用“10+5”、“3+4+3+5”、“7+4+4”、“7+5+3”。。。。 我怎样才能得到这些结果中的一个? 更好:如何获得一个数组以获得几个好的结果?我的最大长度是70,我想要得到这个值的所有好结果可能会很耗时 我是一名3d艺术家,我的编码技能非常有限,我不知道如何处理这个问题。我可以使用Python或类似C的语言来解决这个问题 此代码似乎在我的软件中起作用: def fillBuild
def fillBuild(length, subLengths):
for i in range(len(subLengths)):
if subLengths[i] == length:
yield subLengths[i:i + 1]
elif subLengths[i] < length:
for subResult in fillBuild(length - subLengths[i] ,subLengths[i:] ):
yield subLengths[i:i + 1] + subResult
def fillBuild(长度、子长度):
对于范围内的i(len(子波长)):
如果子长度[i]==长度:
产量子长度[i:i+1]
elif子长度[i]<长度:
对于fillBuild中的子结果(长度-子长度[i],子长度[i:]):
产生子长度[i:i+1]+子结果
下面是一个递归解决方案,使用Python 2.7:
def fill(length, sublengths):
# IMPORTANT: this function will produce INCORRECT RESULTS if sublengths
# is not a list of unique integers sorted increasingly.
fillings = []
for i, sublength in enumerate(sublengths):
if sublength > length:
# if sublength is greater than length, there are no more allowable
# fillings (because sublengths are unique and are sorted
# increasingly), so we return the fillings collected so far;
return fillings
elif sublength == length:
# if sublength is exactly equal to length, then only one filling is
# possible, namely [sublength]; we append this filling to the
# fillings;
fillings.append([sublength])
else:
# we generate all the fillings that begin with sublength by
# prepending sublength to all the allowable fillings of
# (length - sublength), which we obtain by making a recursive call.
fillings.extend([[sublength] + subresult
for subresult in
fill(length - sublength, sublengths[i:])])
例如:
In [2]: fill(15, [3, 4, 5, 6, 7, 10])
Out[2]:
[[3, 3, 3, 3, 3],
[3, 3, 3, 6],
[3, 3, 4, 5],
[3, 4, 4, 4],
[3, 5, 7],
[3, 6, 6],
[4, 4, 7],
[4, 5, 6],
[5, 5, 5],
[5, 10]]
顺便说一句:fill(70、[3,4,5,6,7,10])
生成1657个可能的填充,因此您可能需要一些额外的标准来减少替代方案
一些注意事项:
- 为了避免重复解决方案,我们将要求每种填充物的订购量不断增加
- 关键思想是:假设要填充的长度是L,并且a1
fill
的
块中递归调用的基本原理。(当函数调用自身时,如else
所做的那样,该函数称为递归函数。)fill
- 由于
要求fill
无重复项,且分类越来越多,我们可以使用以下前端功能来确保满足这些条件: def do_填充(长度、子长度): 返回填充(长度、排序(设置(子长度)))sublength
(NB:下面是对代码作用的相当详细的解释。如果您已经理解了代码,您可以放心地跳过本文的其余部分。) 为了更好地了解发生了什么,回到上面的例子,首先根据第一个子长度对解决方案进行分组;您将得到如下所示的三个组:
# group I
[3, 3, 3, 3, 3]
[3, 3, 3, 6]
[3, 3, 4, 5]
[3, 4, 4, 4]
[3, 5, 7]
[3, 6, 6]
# group II
[4, 4, 7]
[4, 5, 6]
# group III
[5, 5, 5]
[5, 10]
现在,使用子长度[3,4,5,6,7,10],将第I组中所有以3开头的填充物与15-3=12的填充物进行比较:
In [3]: fill(15 - 3, [3, 4, 5, 6, 7, 10])
Out[3]:
[[3, 3, 3, 3],
[3, 3, 6],
[3, 4, 5],
[4, 4, 4],
[5, 7],
[6, 6]]
In [4]: fill(15 - 4, [4, 5, 6, 7, 10])
Out[4]:
[4, 7],
[5, 6]
In [5]: fill(15 - 5, [5, 6, 7, 10])
Out[5]:
[[5, 5],
[10]]
如果现在你在所有这些填充物前面加上3,你将得到与第一组完全相同的填充物
现在考虑第II组的填充物,所有这些填充物开始于4。使用子长度[4,5,6,7,10],将其与15-4=11的填充物进行比较:
In [3]: fill(15 - 3, [3, 4, 5, 6, 7, 10])
Out[3]:
[[3, 3, 3, 3],
[3, 3, 6],
[3, 4, 5],
[4, 4, 4],
[5, 7],
[6, 6]]
In [4]: fill(15 - 4, [4, 5, 6, 7, 10])
Out[4]:
[4, 7],
[5, 6]
In [5]: fill(15 - 5, [5, 6, 7, 10])
Out[5]:
[[5, 5],
[10]]
同样,如果你在所有这些填充物前面加上4,你得到的填充物正好是第二组中的填充物
您可能想知道,为什么我在上一次调用fill
时使用[4,5,6,7,10]作为子长度,而不是[3,4,5,6,7,10]?这是因为我只感兴趣的填充物是越来越多的秩序,并开始与4。这排除了任何包含3的填充
最后,为了得到第三组中的填充物,使用子长度[5,6,7,10],为15-5=10的所有填充物预加5:
In [3]: fill(15 - 3, [3, 4, 5, 6, 7, 10])
Out[3]:
[[3, 3, 3, 3],
[3, 3, 6],
[3, 4, 5],
[4, 4, 4],
[5, 7],
[6, 6]]
In [4]: fill(15 - 4, [4, 5, 6, 7, 10])
Out[4]:
[4, 7],
[5, 6]
In [5]: fill(15 - 5, [5, 6, 7, 10])
Out[5]:
[[5, 5],
[10]]
如果你有这种倾向,你可以对每个小组重复同样的分析。例如,您可以根据第一个元素对
fill(15-3、[3,4,5,6,7,10])
生成的填充进行分组;您将得到4个组:
[3, 3, 3, 3]
[3, 3, 6]
[3, 4, 5]
[4, 4, 4]
[5, 7]
[6, 6]
这些组分别通过将3、4、5或6预先添加到由以下方法生成的填充物中来获得:
fill((15 - 3) - 3, [3, 4, 5, 6, 7, 10])
fill((15 - 3) - 4, [ 4, 5, 6, 7, 10])
fill((15 - 3) - 5, [ 5, 6, 7, 10])
fill((15 - 3) - 6, [ 6, 7, 10])
上面的分析只是“手动”完成fill
函数的功能
需要注意的一点是,对于每个递归调用,问题都会变得更简单
例如,在生成填充[3,5,7]的过程中,执行了对fill
的以下调用:
fill(15, [3, 4, 5, 6, 7, 10]) = fill(15, [3, 4, 5, 6, 7, 10])
fill(15 - 3, [3, 4, 5, 6, 7, 10]) = fill(12, [3, 4, 5, 6, 7, 10])
fill(15 - 3 - 5, [ 5, 6, 7, 10]) = fill( 7, [ 5, 6, 7, 10])
特别注意最后一个,
fill(7、[5,6,7,10])
。可以通过检查发现其溶液:从子长度[5,6,7,10]中只能填充一次7。递归总是以这些琐碎情况的解结束。最终的解决方案由这些琐碎的解决方案组合而成。递归生成器函数(Python)生成池的所有可能的子列表排列(带重复)
总计总数:
from pprint import pprint
def sub_lists(pool, total):
for i in range(len(pool)):
if pool[i] == total:
yield pool[i:i + 1]
elif pool[i] < total:
for sub_list in sub_lists(pool, total - pool[i]):
yield pool[i:i + 1] + sub_list
pprint(list(sub_lists([3, 4, 5, 6, 7, 10], 15)))
[[3, 3, 3, 3, 3],
[3, 3, 3, 6],
[3, 3, 4, 5],
[3, 3, 5, 4],
[3, 3, 6, 3],
[3, 4, 3, 5],
[3, 4, 4, 4],
[3, 4, 5, 3],
[3, 5, 3, 4],
[3, 5, 4, 3],
[3, 5, 7],
[3, 6, 3, 3],
[3, 6, 6],
[3, 7, 5],
[4, 3, 3, 5],
[4, 3, 4, 4],
[4, 3, 5, 3],
[4, 4, 3, 4],
[4, 4, 4, 3],
[4, 4, 7],
[4, 5, 3, 3],
[4, 5, 6],
[4, 6, 5],
[4, 7, 4],
[5, 3, 3, 4],
[5, 3, 4, 3],
[5, 3, 7],
[5, 4, 3, 3],
[5, 4, 6],
[5, 5, 5],
[5, 6, 4],
[5, 7, 3],
[5, 10],
[6, 3, 3, 3],
[6, 3, 6],
[6, 4, 5],
[6, 5, 4],
[6, 6, 3],
[7, 3, 5],
[7, 4, 4],
[7, 5, 3],
[10, 5]]
从pprint导入pprint
def子单元列表(池,总计):
对于范围内的i(len(pool)):
如果池[i]==总计:
收益率池[i:i+1]
elif池[i]<总计:
对于sub_列表中的sub_列表(池,总计-池[i]):
收益池[i:i+1]+子清单
pprint(列表(子列表([3,4,5,6,7,10,15]))
[[3, 3, 3, 3, 3],
[3, 3, 3, 6],
[3, 3, 4, 5],
[3, 3, 5, 4],
[3, 3, 6, 3],
[3, 4, 3, 5],
[3, 4, 4, 4],
[3, 4, 5, 3],
[3, 5, 3, 4],
[3, 5, 4, 3],
[3, 5, 7],
[3, 6, 3, 3],
[3, 6, 6],
[3, 7, 5],
[4, 3, 3, 5],
[4, 3, 4, 4],
[4, 3, 5, 3],
[4, 4, 3, 4],
[4, 4, 4, 3],
[4, 4, 7],
[4, 5, 3, 3],
[4, 5, 6],
[4, 6, 5],
[4, 7, 4],
[5, 3, 3, 4],
[5, 3, 4, 3],
[5, 3, 7],
[5, 4, 3, 3],
[5, 4, 6],
[5, 5, 5],
[5, 6, 4],
[5, 7, 3],
[5, 10],
[6, 3, 3, 3],
[6, 3, 6],
[6, 4, 5],
[6, 5, 4],
[6, 6, 3],
[7, 3, 5],
[7, 4, 4],
[7, 5, 3],
[10, 5]]
是否要获取所有总和?所有的价值观都是积极的吗?“语言看起来像C”-不是很有帮助。我猜可能是MEL(如果您使用Maya)或MaxScript(如果您使用3DsMax)。所以您可以重复使用元素?我可以重复使用元素。我使用的C语言在胡迪尼语中是Vex。所有值均为正值。我不需要获得所有的总数。谢谢你的代码,它工作得很好。现在,对于我的使用,当我增加