我有一个列表,其成员是从整数 1 到 600 [或出于存储目的从 0 到 599] 中选择的 5 个数字的集合。我需要选择此列表的子列表,以便在此子列表中的集合中,1 到 600 范围内的每个整数只出现一次,因此是 120 个元素的子列表。我的列表中包含 4200 或 840 个元素——我将通过运行来确定是否需要更大的数字。我需要任何一个这样的子列表。
这对我来说听起来像是一个标准问题,但我不知道如何搜索。有人可以帮忙提供算法吗?
我有一个列表,其成员是从整数 1 到 600 [或出于存储目的从 0 到 599] 中选择的 5 个数字的集合。我需要选择此列表的子列表,以便在此子列表中的集合中,1 到 600 范围内的每个整数只出现一次,因此是 120 个元素的子列表。我的列表中包含 4200 或 840 个元素——我将通过运行来确定是否需要更大的数字。我需要任何一个这样的子列表。
这对我来说听起来像是一个标准问题,但我不知道如何搜索。有人可以帮忙提供算法吗?
集合覆盖的贪心算法根据一个规则选择集合:在每个阶段,选择包含最多未覆盖元素的集合
维基百科似乎说这种算法在合理的复杂性假设下效果最好。
我会将其归结为以下步骤:
根据您使用的编程语言,有一些方法可以快速完成。
编辑:张贴者解释说每个整数必须只使用一次
所以,你真正需要做的只是继续添加元素,直到元素包含一个已经存在于你的子集中的整数。“完全”标准优先于“尚未在子集中”标准。当您达到 120 个子集时,您将跳出循环。
您可能还想跟踪将元素添加到子集中的顺序,并且当您遇到死胡同时(例如,超集中剩余的每个元素都包含一个已经存在于您的子集中的整数),您回溯一个元素并继续。
为了回溯并记住哪些组合不起作用,您需要保留一个“禁止集合”列表,并且每次决定是否添加新元素时,您首先应确保它不在此禁止集合列表中。在 Ruby 中执行此操作的最佳方法(我发现)是存储集合的哈希而不是集合本身。这提供了一种廉价的方式来评估预期的收集是否已经尝试过并导致了死胡同。
祝你好运!