试图用python实现子集和解决方案时出现的问题

试图用python实现子集和解决方案时出现的问题,python,algorithm,Python,Algorithm,我正试图用python编写一个暴力解决方案来解决子集和问题,但没有得到任何输出。。。我这样做对吗/知道我做错了什么吗 我的代码: def ss(set, tVal): #remove items greater than target from list cleaned = [c for c in set if c < tVal] #sort the list cleaned.sort() occurance = 0 leftIndex

我正试图用python编写一个暴力解决方案来解决子集和问题,但没有得到任何输出。。。我这样做对吗/知道我做错了什么吗

我的代码:

def ss(set, tVal):
    #remove items greater than target from list
    cleaned = [c for c in set if c < tVal]
    #sort the list
    cleaned.sort()  

    occurance = 0
    leftIndex = 0
    rightIndex = len(cleaned) - 1
    print("rI length: ", rightIndex)

    while(leftIndex < rightIndex):
        #if target value found
        if cleaned[leftIndex] + cleaned[rightIndex] == tVal:
            print("found!!! ", cleaned[leftIndex], " + ", cleaned[rightIndex])
            #occurance += 1
            leftIndex += 1
            rightIndex += 1
        #else if left index + right index < target increment left index
        elif cleaned[leftIndex] + cleaned[rightIndex] < tVal:
            leftIndex += 1
        #otherwise decrement right index
        else:
            rightIndex -= 1

cities = [18897109, 12828837, 9661105, 6371773, 5965343, 5926800, 5582170, 5564635, 5268860, 4552402, 4335391, 4296250, 4224851, 4192887, 3439809, 3279933, 3095213, 2812896, 2783243, 2710489, 2543482, 2356285, 2226009, 2149127, 2142508, 2134411]
target = 101000000 

ss(cities, target)
def ss(设置,tVal):
#从列表中删除大于目标的项目
清洁=[c为c,如果c
你确定你的
目标没有偏离一个数量级吗?你的
left+right
总和永远不会接近
tVal
。代码运行正常,循环只会不断递增
leftIndex
,直到
失败。一些
print
语句将有助于了解发生了什么

稍微修改
ss()
的内部:

def ss(set, tVal):

    # ...

    print("target:       ", tVal) # spacing aligned for printing

    while(leftIndex < rightIndex):
        left_plus_right = cleaned[leftIndex] + cleaned[rightIndex]
        print("left + right: ", left_plus_right)

        if left_plus_right == tVal:
            print("found!!! ", cleaned[leftIndex], " + ", cleaned[rightIndex])
            leftIndex += 1
            rightIndex += 1
        elif left_plus_right < tVal:
            leftIndex += 1
        else:
            rightIndex -= 1

    # ...

您的测试中似乎没有匹配项,这就是没有输出的原因。 我添加了一些调试代码来打印每个计算:

val is lower than tval 21031520 101000000
val is lower than tval 21039617 101000000
val is lower than tval 21046236 101000000
val is lower than tval 21123118 101000000
val is lower than tval 21253394 101000000
val is lower than tval 21440591 101000000
val is lower than tval 21607598 101000000
val is lower than tval 21680352 101000000
val is lower than tval 21710005 101000000
val is lower than tval 21992322 101000000
val is lower than tval 22177042 101000000
val is lower than tval 22336918 101000000
val is lower than tval 23089996 101000000
val is lower than tval 23121960 101000000
val is lower than tval 23193359 101000000
val is lower than tval 23232500 101000000
val is lower than tval 23449511 101000000
val is lower than tval 24165969 101000000
val is lower than tval 24461744 101000000
val is lower than tval 24479279 101000000
val is lower than tval 24823909 101000000
val is lower than tval 24862452 101000000
val is lower than tval 25268882 101000000
val is lower than tval 28558214 101000000
val is lower than tval 31725946 101000000
当我将目标值更改为其中一个和时,它找到了它

>>> ss(cities, 21039617)
val is lower than tval 21031520 21039617
found.  1   25
此外,此代码也有问题:

if cleaned[leftIndex] + cleaned[rightIndex] == tVal:
            print("found!!! ", cleaned[leftIndex], " + ", cleaned[rightIndex])
            #occurance += 1
            leftIndex += 1
            rightIndex += 1
如果输入此条件,将尝试将rightIndex增加1。如果在前面的循环中没有减少,则在下一次调用
cleaned[rightIndex]
-->
索引器错误:列表索引超出范围


如果rightIndex小于
len(cleaned)-1,则需要先添加一个检查,然后再增加它。否则就让它保持原样。

通过阅读代码和问题描述的状态,您试图实现的目标有点不清楚。当你说“子集之和”时,你是在试图对这25个城市中的每个可能子集(例如)求和吗

如果是这种情况,那么就有2^n-1个可能的子集,或者对于n=2533554433。如果您试图通过创建所有这些子集的列表或集合来立即将其读入内存,则可能会消耗所有内存

您可以使用生成器一次一个地对结果进行流式处理,并检查解决方案,例如:

import itertools

cities = [18897109, 12828837, 9661105, 6371773, 5965343, 5926800, 5582170, 5564635, 5268860, 4552402, 4335391, 4296250, 4224851, 4192887, 3439809, 3279933, 3095213, 2812896, 2783243, 2710489, 2543482, 2356285, 2226009, 2149127, 2142508, 2134411]
target = 101000000 
ps = (set(itertools.combinations(cities,i)) for i in range(len(cities)))
for s in ps:
    for x in s:
        if sum(x) == target:
            print ('target reached:', x)

被接受的答案解决了您眼前的问题,但我不确定它是否是您所描述问题的正确解决方案。

您的清洁用法不正确。我在代码中添加了一个调试打印,发现总数总是超过tVal。因此,if测试总是失败,并且没有打印出找到的消息

例如

lIndex =  24 rIndex =  25
c[lIndex] =  12828837 c[rIndex] = 18897109
total  -  31725946 tval =  101000000
或者输入一个else for not found以查看此信息

显示这一点的调试打印是

    while(leftIndex < rightIndex):
    print 'lIndex = ', leftIndex, 'rIndex = ', rightIndex
    print 'c[lIndex] = ', cleaned[leftIndex], 'c[rIndex] =', cleaned[rightIndex]
    mytot = cleaned[leftIndex] + cleaned[rightIndex]
    print 'total  - ', mytot, 'tval = ', tVal
    if mytot == tVal:
        print("found!!! ", cleaned[leftIndex], " + ", cleaned[rightIndex])
        leftIndex += 1
        rightIndex +=1
    elif cleaned[leftIndex] + cleaned[rightIndex] < tVal:
        leftIndex += 1
    else:
        rightIndex -= 1
while(leftIndex