Problem z zadaniem w python

0

Witam!
Zaczynam swoją przygodę z programowaniem i potrzebuję pomocy w zadaniu, ponieważ zaciąłem się w jednym punkcie i nie mam pomysłu jak inaczej podejść do problemu.
Treść brzmi następująco:
Dla zadanego zbioru liczb wypisz jego najmniej liczny podzbiór, którego suma jest większa niż suma pozostałych elementów tego zbioru.
Program wypisuje możliwe podzbiory, ale przy większej ilości wylosowanych elementów gubi niektóre z nich.
Będę wdzięczny jeśli ktoś postanowi mi pomóc.

import random
def randTab(n,tab):
    
    for i in range(n):
        tab.append(random.randint(0,10))
        
    print(tab)
    
mainList=[]
sum1=[]
sum2=[]
temp=0
length=int(input("Podaj dlugosc tablicy do wylosowania "))
randTab(length,mainList)
mainList.sort(reverse=True)
sum2.extend(mainList)

for i in range(0,length-1):
    sum1.append(mainList[i])
    sum2[i]=0
    if(sum(sum1)>sum(sum2)):
        print(sum1)
        break

for j in range(i+1,length):
    
    temp=sum1[i]
    sum1[i]=sum2[j]
    sum2[j]=temp
    if(sum(sum1)>sum(sum2)):
        print(sum1)

0

Dla liczb dodatnich to już takie coś powinno zadziałać:

def subset(lst):
    srtlst = sorted(lst, reverse=True)

    for i in range(len(lst)):
        if sum(srtlst[:i]) > sum(lst)/2:
            return srtlst[:i]


randlist = [5, 1, 8, 9, 7, 1, 2, 3, 1, 2]
subset(randlist)  # [9, 8, 7]

O ile kolejność liczb nie ma znaczenia i w zbiorze mogą się powtarzać te same liczby.

0

@Pyxis: Głównym problemem jest to że program powinien wyrzucać wszystkie możliwe kombinacje takich podzbiorów np. dla zbioru [2,4,1,3,9,0,3] wyjściem jest [4,9],[3,9]

0

W takim razie jeśli kolejność ma znaczenie, to warto wykorzystać moduł combinations:

from itertools import combinations

def subset(randlist):
    subsets = list()
    
    for i in range(1, len(randlist)):
        if len(subsets) > 0:
            break
        comb = combinations(randlist, i)
        for j in comb:
            if sum(j) > sum(randlist)/2:
                subsets.append(j)

    return subsets

randlist = [2, 4, 1, 3, 9, 0, 3]
subset(randlist)  # [(4, 9), (3, 9), (9, 3)]

Jak widzimy, powtarza się podzbiór z 3 i 9. Można temu zaradzić poprzez użycie zbiorów pythonowych, ale utracisz wtedy kolejność występowania elementów:

from itertools import combinations

def subset(randlist):
    subsets = set()
    
    for i in range(1, len(randlist)):
        if len(subsets) > 0:
            break
        comb = combinations(randlist, i)
        for j in comb:
            if sum(j) > sum(randlist)/2:
                subsets.add(frozenset(j))

    return [tuple(i) for i in subsets]

randlist = [2, 4, 1, 3, 9, 0, 3]
subset(randlist)  # [(9, 4), (9, 3)] zamiast [4, 9], [3, 9]
2

Kod zgodny z "Dla zadanego zbioru liczb wypisz jego najmniej liczny podzbiór, którego suma jest większa niż suma pozostałych elementów tego zbioru", liczy w O(n*log(n)); jak przerobiłeś temat zadania, (najmniej liczny podzbiór - liczba pojedyncza) na zwracający podzbiory?

def smallest_subset(xs):
    xs.sort(reverse=True)
    arr_sum = sum(xs)
    tmp_sum = 0
    for i in range(len(xs)):
        tmp_sum = sum(xs[:(i + 1)])
        if tmp_sum > arr_sum - sum(xs[:(i + 1)]):
            return xs[:(i + 1)]
0

@lion137: Przerobienie tematu wynika z faktu że nauczyciel podał mi właśnie takie przykłady wejścia i wyjścia tj. dla zbioru [2,4,1,3,9,0,3] wyjściem jest [4,9],[3,9]

1

To, żeby utrzymać, n * logn musisz powyższe troszkę nietrywialnie :) przerobić, albo brute force z kolejnego postu powyżej.

1 użytkowników online, w tym zalogowanych: 0, gości: 1