2016-04-10 5 views
-2

Ich möchte einen effizienten Algorithmus finden, um eine ganze Zahl auf einen Wert in einem max, min Bereich zu teilen. Es sollte so wenige Werte wie möglich geben.split einen Wert in Werte in max, min Bereich

Zum Beispiel: max = 7 min = 3 dann

8 = 4 + 4 
9 = 4 + 5 
16 = 5 + 5 + 6 (not 4 + 4 + 4 + 4) 

EDIT

Um es deutlich zu machen, lassen Sie ein Beispiel nehmen. Angenommen, Sie haben einen Haufen Äpfel und Sie möchten sie in Körbe packen. Jeder Korb kann 3 bis 7 Äpfel enthalten, und Sie möchten, dass die Anzahl der Körbe so klein wie möglich ist.

** Ich erwähnte, dass der Wert gleichmäßig aufgeteilt werden sollte, aber das ist nicht so wichtig. Ich mache mir mehr Sorgen um weniger Körbe.

+0

Wie definieren Sie "gleichmäßig aufgeteilt"? Was macht "16 = 5 + 5 + 6" zu einer besseren Lösung als "16 = 4 + 4 + 4 + 4"? –

+0

Entschuldigung, dass ich es nicht klar gemacht habe, habe ich die Frage aktualisiert, danke – TomNg

+0

Ok, nächste Frage: Was genau macht "16 = 5 + 5 + 6" besser als "16 = 6 + 6 + 4"? –

Antwort

1

Dies erschien mir als ein lustiges Problem, also habe ich versucht, eine schnelle Lösung zu hacken. Ich denke, dass dies ein interessanter Ausgangspunkt sein könnte, es wird Ihnen entweder eine gültige Lösung mit so wenig Zahlen wie möglich oder mit möglichst ähnlichen Zahlen geben, alles innerhalb der Grenzen des durch min_bound und max_bound definierten Bereichs Anzahl = int (Eingang ("Nummer:")) min_bound = 3 max_bound = 7

def improve(solution): 
    solution = list(reversed(solution)) 
    for i, num in enumerate(solution): 
     if i >= 2: 
      average = sum(solution[:i])/i 
      if average.is_integer(): 
       for x in range(i): 
        solution[x] = int(average) 
       break 
    return solution 

def find_numbers(number, division, common_number): 
    extra_number = number - common_number * division 
    numbers_in_solution = [common_number] * division 
    if extra_number < min_bound and \ 
    extra_number + common_number <= max_bound: 
     numbers_in_solution[-1] += extra_number 
    elif extra_number < min_bound or extra_number > max_bound: 
     return None 
    else: 
     numbers_in_solution.append(extra_number) 
    solution = improve(numbers_in_solution) 
    return solution 

def tst(number): 
    try: 
     solution = None 
     for division in range(number//max_bound, number//min_bound + 1): # Reverse the order of this for numbers as close in value to each other as possible. 
      if round (number/division) in range(min_bound, max_bound + 1): 
       solution = find_numbers(number, division, round(number/division)) 
      elif (number // division) in range(min_bound, max_bound + 1): # Rarely required but catches edge cases 
       solution = find_numbers(number, division, number // division) 
      if solution: 
       print(sum(solution), solution) 
       break 
    except ZeroDivisionError: 
     print("Solution is 1, your input is less than the max_bound") 

tst(number) 
for x in range(1,100): 
    tst(x) 

Dieser Code ist nur eine Idee zu zeigen, ich bin sicher, dass es für eine bessere Leistung optimiert werden könnte.

+0

Mit der kurzen Lösung könnten Sie wahrscheinlich durch die Liste iterieren, um zu sehen, ob es einen Durchschnitt gab, der die Zahlen näher zusammenbringen würde. Zum Beispiel, wenn Ihre Lösung [5, 5, 5, 2] wäre, würde sie zuerst auf 5 und 2 schauen, ihr Durchschnitt ist 3,5, also würde sie es überspringen. Dann würde es 5, 5, 2 betrachten, ihr Durchschnitt ist 4, also kann sie die Lösung auf [5, 4, 4, 4] aktualisieren. –

+0

Wenn der Eingang 20 ist, ist das Ergebnis [5, 5, 5, 5]. Es sollte [7, 7, 6] sein – TomNg

+0

Nicht mehr! Ich habe es oben aktualisiert. Es musste die gerundete Division vor der Bodenaufteilung überprüft werden. Ich habe die Mittelungsidee hinzugefügt, also versuche ich, diese Antworten wie [5, 5, 5, 2] zu nehmen und sie in [5, 4, 4, 4] umzuwandeln. –