2012-03-07 73 views
5

Tôi đã làm việc trên một số tập lệnh nhanh và bẩn để thực hiện một số bài tập về hóa học của mình và một trong số chúng lặp lại trong danh sách có độ dài không đổi một hằng số nhất định. Đối với mỗi người, tôi kiểm tra xem họ có đáp ứng một số tiêu chí bổ sung và đưa chúng vào danh sách khác hay không.Tạo một dãy số tổng cho một số đã cho

tôi đã tìm ra một cách để đáp ứng các tiêu chí tổng hợp, nhưng có vẻ khủng khiếp, và tôi chắc chắn rằng có một số loại của thời điểm này có thể dạy dỗ ở đây:

# iterate through all 11-element lists where the elements sum to 8. 
for a in range(8+1): 
for b in range(8-a+1): 
    for c in range(8-a-b+1): 
    for d in range(8-a-b-c+1): 
    for e in range(8-a-b-c-d+1): 
    for f in range(8-a-b-c-d-e+1): 
     for g in range(8-a-b-c-d-e-f+1): 
     for h in range(8-a-b-c-d-e-f-g+1): 
     for i in range(8-a-b-c-d-e-f-g-h+1): 
     for j in range(8-a-b-c-d-e-f-g-h-i+1): 
      k = 8-(a+b+c+d+e+f+g+h+i+j) 
      x = [a,b,c,d,e,f,g,h,i,j,k] 
      # see if x works for what I want 
+0

'[vals for itertools.product (phạm vi (8), repeat = 11) nếu tổng (vals) == 8]' đẹp hơn, nhưng ** nhiều ** chậm hơn giải pháp của bạn. – eumiro

+0

+1 - Đạo cụ sử dụng máy tính để tự động hóa bài tập về nhà hóa học lặp đi lặp lại của bạn. –

+0

Cái nhìn sâu sắc của tôi là: cho một danh sách 11 số nguyên tất cả tổng hợp đến 8, một LOT của các con số sẽ bằng không. Cách nhanh nhất để làm điều này là tìm tất cả các cách tổng hợp các số nguyên thành 8 - ví dụ: '8, 1 + 7, 2 + 6, 3 + 5, 4 + 4, 1 + 1 + 6, 1 + 2 + 5 ... 'và sau đó chỉ cho phép những người có số lượng zeroes thích hợp. –

Trả lời

1

Đây là trình tạo đệ quy tạo ra các danh sách theo thứ tự từ điển. Để lại exactTrue cho kết quả được yêu cầu trong đó mọi giới hạn tổng ==; đặt exact thành False cung cấp tất cả các danh sách có 0 < = tổng số < = giới hạn. Việc đệ quy tận dụng lợi thế của tùy chọn này để tạo ra các kết quả trung gian.

def lists_with_sum(length, limit, exact=True): 
    if length: 
     for l in lists_with_sum(length-1, limit, False): 
      gap = limit-sum(l) 
      for i in range(gap if exact else 0, gap+1): 
       yield l + [i] 
    else: 
     yield [] 
1

Generic, giải pháp đệ quy:

def get_lists_with_sum(length, my_sum): 
    if my_sum == 0: 
     return [[0 for _ in range(length)]] 

    if not length: 
     return [[]] 
    elif length == 1: 
     return [[my_sum]] 
    else: 
     lists = [] 
     for i in range(my_sum+1): 
      rest = my_sum - i 
      sublists = get_lists_with_sum(length-1, rest) 
      for sl in sublists: 
       sl.insert(0, i) 
       lists.append(sl) 

    return lists 

print get_lists_with_sum(11, 8) 
+0

Chỉ cần thử chạy điều đó. Ôi trời, chậm quá ... Có thể chuyển đổi thành thứ gì đó sử dụng chồng thay vì đệ quy toàn diện? –

+0

Nó được nhắm mục tiêu với giá trị thấp, tất nhiên. Đối với những con số nhất định, tôi nghĩ rằng đó là chấp nhận được. Xây dựng một bộ nhớ đệm vào nó có lẽ sẽ giúp, bởi vì các đối số sẽ lặp lại khá thường xuyên. Tuy nhiên, số lượng các kết hợp có thể sẽ phát nổ cho các đối số có giá trị cao hơn. –

+0

Với các đối số '8,11' nó đã sắp xếp lại CPU của tôi trong vài phút trước khi tôi giết nó. Câu trả lời của OP thực sự rất nhanh (chỉ * xấu xí *.) –

Các vấn đề liên quan