Eu tenho aprendido python para meu hobby e pesquisas empíricas sobre problemas completos de NP, como Subset Product. O algoritmo que tenho funciona, mas não está do jeito que pretendo fazer.
O que estou tentando fazer é interromper as ferramentas de controle combinations
assim que chegarem a um produto de subconjunto da variável de entrada target
. Isso tornará o código um pouco mais rápido. O código está no estágio de polimento, portanto há uma lista desnecessáriares_2
Aqui está o loop.
res_2 = [];
for i in range(1, len(s)+1):
var = (findsubsets(s, i))
kk = list(map(numpy.prod, var))
res_2.append(kk)
if target in kk:
print('yes')
print(var)
break
Esta é a saída que eu não quero. Observe que o script não irá parar no (4, 4). É um desperdício de recursos continuar verificando todas as combinações quando um alvo é "atingido".
Enter numbers WITH SPACES: 4 4 3 12
enter target integer:
16
yes
[(4, 4), (4, 3), (4, 12), (4, 3), (4, 12), (3, 12)]
kk
[16, 12, 48, 12, 48, 36]
Minha saída pretendida é parar em (4, 4) se for o primeiro "acerto". O mesmo para qualquer outro subconjunto como (1,2,3) ou (1,2,3 --- qualquer comprimento). Eu preferiria que o script continuasse até encontrar um hit. Depois de encontrar o acerto, ele para, porque isso melhoraria a velocidade do algoritmo.
Script completo abaixo
# Naive Subset-Product solver
# with python's itertools
import itertools
import numpy
s = list(map(int, input('Enter numbers WITH SPACES: ').split(' ')))
print('enter target integer: ')
target = int(input())
if s.count(target) > 0:
print('yes')
quit()
if target > numpy.prod(s):
print('sorry cant be bigger than total product of s')
quit()
def findsubsets(s, n):
return list(itertools.combinations(s, n))
# Driver Code
n = len(s)
# This code snippet is a for loop. It also is intended to cut down execution
# time once it finds the target integer. (instead of creating all combinations)
res_2 = [];
for i in range(1, len(s)+1):
var = (findsubsets(s, i))
kk = list(map(numpy.prod, var))
res_2.append(kk)
if target in kk:
print('yes')
print(var)
break
Questão
Como faço para que isso funcione para aumentar a velocidade do algoritmo? Que truques pitônicos resolveriam meu problema? Existe uma maneira mais curta de fazer isso?