【发布时间】:2018-10-04 20:37:29
【问题描述】:
这个问题已经困扰我好几天了,我不知道如何解决它。我已经非常努力地自己解决它,但现在我非常感谢一些帮助和正确方向的指针。
问题:
给定一组数字,以及每个数字可以大于或小于以下数字的最大限制,根据限制确定数字的有效排序数。
示例:
数字:20、30、36、40
一个数字可以大于以下数字的最大数量:16
一个数字可以小于以下数字的最大数量:8
这里将有 3 个有效的订单:
36 40 30 20
40 36 30 20
40 30 36 20
我设计了一种使用递归和树生成所有有效排列的方法,但不幸的是,在列表中有许多有效顺序的情况下(我相信接近 n!运行时间),这需要很长时间。我觉得好像有一种更快、更数学的方法可以使用我没有看到的组合学来解决这个问题。任何建议将不胜感激,谢谢!
编辑: 这是我想出的置换算法的代码。代码的最后一部分使用我上面给出的示例对其进行了测试。它是用 Python 3.6 编写的。
class block:
def __init__(self, val, children):
self.val = val
self.children = children
# Gets all the possible children of the current head within the limits
def get_children(head, nums, b, visited, u, d):
global total
if all(visited):
total += 1
return
for i in range(b):
if not visited[i]:
if head.val - nums[i] <= d and nums[i] - head.val <= u:
head.children.append(block(nums[i], []))
visited[i] = True
get_children(head.children[-1], nums, b, visited, u, d)
visited[i] = False
# Display all the valid permutations of the current head
def show(head, vals, b):
vals.append(head.val)
if head.children == [] and len(vals) == b:
print(*vals)
return
for child in head.children:
show(child, vals[:], b)
# Test it out with the sample
b, nums, u, d = 4, [20, 30, 36, 40], 8, 16
visited = [False for x in range(b)]
total = 0
heads = []
for i in range(b):
heads.append(block(nums[i], []))
visited[i] = True
get_children(heads[-1], nums, b, visited, u, d)
visited[i] = False
show(heads[-1], [], b)
print(total)
打印出来:
36 40 30 20
40 30 36 20
40 36 30 20
3
【问题讨论】:
-
我认为这个问题实际上可能很难——这看起来很相似:math.stackexchange.com/questions/2251021/… 你为什么不分享你最快的递归方法,也许这会帮助人们看到优化选项?
-
这不类似于计算图中的所有哈密顿路径吗?
-
@גלעדברקן 是的。但这会让事情变得更容易吗?
-
你的目标是一定的时间复杂度,还是设定大小?
-
@m69 我不知道,但它会将其识别为可能已知解决方案的已知问题。
标签: algorithm math permutation combinatorics