Làm thế nào để làm cho trăn dừng lại một khi sản phẩm mục tiêu được tìm thấy trong tập hợp con?


8

Tôi đã học trăn vì sở thích và nghiên cứu thực nghiệm về các vấn đề hoàn chỉnh NP như Subset Product. Thuật toán tôi có hoạt động, nhưng nó không thực hiện theo cách tôi dự định làm.

Những gì tôi đang cố gắng làm là dừng itertools ' combinationskhi nó đến một sản phẩm con của biến đầu vào target. Điều này sẽ làm cho mã nhanh hơn một chút. Mã đang trong giai đoạn đánh bóng nên có một danh sách không cần thiếtres_2

Đây là vòng lặp.

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

Đây là đầu ra mà tôi không muốn. Lưu ý rằng tập lệnh sẽ không dừng lại ở (4, 4). Thật lãng phí tài nguyên để tiếp tục kiểm tra tất cả các kết hợp khi mục tiêu bị "tấn công".

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]

Đầu ra dự định của tôi là dừng lại ở (4, 4) nếu đó là "lần nhấn" đầu tiên. Tương tự cho bất kỳ tập hợp con khác như (1,2,3) hoặc (1,2,3 --- bất kỳ độ dài nào). Tôi thích hơn nếu kịch bản tiếp tục cho đến khi nó có thể tìm thấy một hit. Một khi nó tìm thấy cú đánh, nó dừng lại, bởi vì điều này sẽ cải thiện tốc độ của thuật toán.

Kịch bản đầy đủ bên dưới

# 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

Câu hỏi

Làm thế nào để tôi làm việc này để tăng tốc độ của thuật toán? Những thủ thuật pythonic sẽ khắc phục vấn đề của tôi? Có cách nào ngắn hơn để làm điều này?

Câu trả lời:


3

Việc chuyển đổi combinationsgiá trị trả về của itertools thành sớm list, đặc biệt là khi bạn đang cố gắng thoát sớm và tránh quá nhiều chi phí. Thường có một lý do chính đáng để các hàm thư viện trả về các trình vòng lặp thay vì các danh sách được nhận biết đầy đủ.

Đây là một gợi ý:

def findsubsets(s, n): 
    return itertools.combinations(s, n)

def find_subset(target,nums):
    for i in range(1,len(nums)+1):
        for ss in findsubsets(nums, i):
            if np.prod(ss) == target:
                prodstr = '*'.join(str(num) for num in ss)
                print(f"{target} = {prodstr}")
                return ss
    return None

find_subset(96,[1,6,2,8])

Cho rằng đó findsubsetslà một dòng duy nhất, thật đáng nghi ngờ khi nó có chức năng độc lập (về cơ bản chúng ta chỉ là bí danh combinationscó thể được thực hiện với một import X as Ytuyên bố). Trong mọi trường hợp, điều này nên dừng lại sớm mà không chiếm quá nhiều RAM với đầu vào lớn hơn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.