Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 一种生成满足一定条件集子集的算法_Python_Algorithm_Subset - Fatal编程技术网

Python 一种生成满足一定条件集子集的算法

Python 一种生成满足一定条件集子集的算法,python,algorithm,subset,Python,Algorithm,Subset,假设给我一个元素的排序列表,我想生成满足某个条件的所有子集,因此如果给定的集合不满足该条件,那么较大的子集也不满足该条件,并且一个元素的所有集合都满足该条件 例如,给定一个所有小于100的正整数的列表,确定其和小于130的子集:(100,29)(0,1,40),(0),等等 我如何才能做到这一点(最好是用Python) 谢谢!:) 当然有办法做到这一点,但除非你能以某种方式约束条件,否则它将需要O(2^n)个步骤。如果你考虑,例如,在1到100的条件下,所有子集都会被选择(例如,我在1-n中的<

假设给我一个元素的排序列表,我想生成满足某个条件的所有子集,因此如果给定的集合不满足该条件,那么较大的子集也不满足该条件,并且一个元素的所有集合都满足该条件

例如,给定一个所有小于100的正整数的列表,确定其和小于130的子集:(100,29)(0,1,40),(0),等等

我如何才能做到这一点(最好是用Python)


谢谢!:)

当然有办法做到这一点,但除非你能以某种方式约束条件,否则它将需要O(2^n)个步骤。如果你考虑,例如,在1到100的条件下,所有子集都会被选择(例如,我在1-n中的< i i),那么你将结束枚举所有子集。

你会看到

for i in the powerset of {1-n}
    if cond(i)
       note that set

只需生成从0到sn-1的所有二进制数,并在位i为1时为子集选择元素i,就可以得到集合的幂集。

当然有办法做到这一点,但除非您能够以某种方式约束条件,否则需要O(2^n)个步骤。如果你考虑,例如,在1到100的条件下,所有子集都会被选择(例如,我在1-n中的< i i),那么你将结束枚举所有子集。

你会看到

for i in the powerset of {1-n}
    if cond(i)
       note that set

只需生成从0到sn-1的所有二进制数,并在位i为1时为子集选择元素i,即可获得集合的幂集。

您可以使用一种技术生成所有子集:您可以以增量方式生成所有子集(生成已确定子集的超集),并将其用作修剪条件“如果根不满足约束,则不探索树的此分支”

如果您想对约束进行泛化,我认为这是最好的策略

请确保以正确的方式编写生成子集的代码,否则会多次生成相同的子集:为了避免由于映射查找和内存开销而导致耗时的记忆,您可以以这种方式生成子集:

GetAllSubsets(List objects) {
    List generated = {};
    GetAllSubsets(generated, [], objects);
    return generated;
}

GetAllSubsets(List subsetGenerated, List objectFixed, List objectsToFix) {
    GetAllSubsets(subsetGenerated, objectFixed, objectsToFix.sublist(1, objectsToFix.length());
    if (satisfy(toCheck = objectsFixed.add(objectsToFix.get(0)))) {
        subsetGenerated.add(toCheck);
        GetAllSubsets(subsetGenerated, toCheck, objectsToFix.sublist(1, objectsToFix.length());
    }
}

事实上,第一次调用GetAllSubsets添加的子集没有objectsToFix的第一个元素,第二次调用添加的子集(如果没有违反修剪条件)具有该元素,因此生成的两组子集的交集为空。

您可以使用一种技术生成所有子集:您可以以增量方式生成所有子集(生成已确定子集的超集),并将其用作修剪条件“如果根不满足约束,则不探索树的此分支”

如果您想对约束进行泛化,我认为这是最好的策略

请确保以正确的方式编写生成子集的代码,否则会多次生成相同的子集:为了避免由于映射查找和内存开销而导致耗时的记忆,您可以以这种方式生成子集:

GetAllSubsets(List objects) {
    List generated = {};
    GetAllSubsets(generated, [], objects);
    return generated;
}

GetAllSubsets(List subsetGenerated, List objectFixed, List objectsToFix) {
    GetAllSubsets(subsetGenerated, objectFixed, objectsToFix.sublist(1, objectsToFix.length());
    if (satisfy(toCheck = objectsFixed.add(objectsToFix.get(0)))) {
        subsetGenerated.add(toCheck);
        GetAllSubsets(subsetGenerated, toCheck, objectsToFix.sublist(1, objectsToFix.length());
    }
}

事实上,第一次调用GetAllSubsets添加的子集没有objectsToFix的第一个元素,第二次调用添加的子集(如果没有违反修剪条件)具有该元素,因此生成的两个子集集的交集为空。

您可以递归地构造集合,从空集合开始,尝试添加更多元素,如果其中一个子集(以及它的所有超集)出现,则放弃递归执行行未能满足条件。以下是一些伪代码,假设一个集合s的条件满足要列出的子集。为方便起见,假设s的元素可以索引为x(0)、x(1)、x(2)


第一个调用将T作为空集。然后,将打印与条件匹配的S的所有子集。此策略主要依赖于这样一个事实,即不满足条件的S的子集不能包含在满足条件的S的子集中。

您可以递归地构造集,从空集开始,尝试添加更多元素,如果其中一个子集(及其所有超集)未能满足条件,则放弃递归执行行。下面是一些伪代码,假设一个集合s的条件满足您要列出的子集。为方便起见,假设s的元素可以索引为x(0)、x(1)、x(2)


第一个调用将T作为空集。然后,将打印与条件匹配的S的所有子集。此策略主要依赖于这样一个事实,即不满足条件的S的子集不能包含在满足条件的S的子集中。

我对类调度生成算法做了类似的操作。我们的调度类s有两个要素——一个是添加到时间表中的课程列表,另一个是可添加的课程列表

伪代码:

queue.add(new schedule(null, available_courses))
while( queue is not empty )
    sched = queue.next()
    foreach class in sched.available_courses
        temp_sched = sched.copy()
        temp_sched.add(class)
        if(temp_sched.is_valid())
            results.add(temp_sched)
            queue.add(temp_sched)
我们的想法是从一个空的时间表和可用类列表开始,并在树下搜索有效的时间表(有效的含义符合用户给定的要求,没有时间冲突等)。如果时间表无效,它将被丢弃-我们不能通过添加类使无效的时间表有效(即,修剪树)


修改它来解决您的问题应该很容易。

我已经为课程时间表生成算法做了类似的事情。我们的时间表类有两个元素-一个添加到时间表中的课程列表和一个可添加的课程列表

伪代码:

queue.add(new schedule(null, available_courses))
while( queue is not empty )
    sched = queue.next()
    foreach class in sched.available_courses
        temp_sched = sched.copy()
        temp_sched.add(class)
        if(temp_sched.is_valid())
            results.add(temp_sched)
            queue.add(temp_sched)
我们的想法是从一个空的时间表和可用类列表开始,并在树下搜索有效的时间表(有效的含义符合用户给出的要求,没有时间冲突等)。如果一个时间表无效,它将被丢弃-我们不能通过添加类(即,删减