Knapsack (3)

Vedi la discussione.

In un deposito di minerali esistono esemplari di vario peso e valore individuati da sigle di riconoscimento.

Ciascun minerale è descritto da un termine che contiene le seguenti informazioni:

minerale(<sigla minerale >, <valore>, <peso>).

Il deposito contiene i seguenti minerali:

  • minerale(m1, 39, 58)
  • minerale(m2, 42, 64)
  • minerale(m3, 40, 65)
  • minerale(m4, 38, 59)
  • minerale(m5, 37, 61)
  • minerale(m6, 42, 62).

I minerali possono essere spostati con carrelli di diversa portata su cui si possono mettere tre esemplari (diversi).

  • Disponendo di un carrello con portata massima di 180 Kg, trovare la lista L1 delle sigle di tre minerali diversi che siano trasportabili contemporaneamente e che abbiano il massimo valore complessivo.
  • Disponendo di un carrello con portata massima di 185 Kg, trovare la lista L2 delle sigle di tre minerali diversi che siano trasportabili contemporaneamente e che abbiano il massimo valore complessivo.
  • Disponendo di un carrello con portata massima di 200 Kg, trovare la lista L1 delle sigle di tre minerali diversi che siano trasportabili contemporaneamente e che abbiano il massimo valore complessivo.

N.B. Nella lista, elencare le sigle in ordine (lessicale) crescente; per le sigle usate si ha il seguente ordine: m1 < m2 < m3 < …

Soluzione 1

Vedi il caso con una coppia di minerali.
Novità? L’indice k per il terzo minerale.

Soluzione 2

Aggiungi la lista dei nomi.
L’utente sceglie il peso massimo.

NOMI   = ["m1", "m2", "m3", "m4", "m5", "m6"]
VALORI = [39, 42, 40, 38, 37, 42]
PESI   = [58, 64, 65, 59, 61, 62]

PESO_MAX = int(input("Scegli il peso massimo >> "))

sol_nome   = ""
sol_valore = 0
sol_peso   = 0

n = len(NOMI)
for i in range(n):
    for j in range(i+1, n):
        for k in range(j+1, n):
            # ---------------------------- Nuova tripla
            nome   = NOMI[i] + "+" + NOMI[j] + "+" + NOMI[k]
            valore = VALORI[i]  +    VALORI[j]  +    VALORI[k]
            peso   = PESI[i]    +    PESI[j]    +    PESI[k]
            print(nome, valore, peso, sep="\t")

            # ---------------------------- Nuova soluzione?
            if(peso <= PESO_MAX) and (valore > sol_valore):
                sol_nome   = nome
                sol_valore = valore
                sol_peso   = peso
print()
print(sol_nome, sol_valore, sol_peso, sep="\t")
Scegli il peso massimo >> 180
m1+m2+m3	121	187
m1+m2+m4	119	181
m1+m2+m5	118	183
m1+m2+m6	123	184
m1+m3+m4	117	182
m1+m3+m5	116	184
m1+m3+m6	121	185
m1+m4+m5	114	178
m1+m4+m6	119	179
m1+m5+m6	118	181
m2+m3+m4	120	188
m2+m3+m5	119	190
m2+m3+m6	124	191
m2+m4+m5	117	184
m2+m4+m6	122	185
m2+m5+m6	121	187
m3+m4+m5	115	185
m3+m4+m6	120	186
m3+m5+m6	119	188
m4+m5+m6	117	182

m1+m4+m6	119	179

Soluzione 3

La classe minerale permette di eliminare le liste parallele per i nomi, valori, pesi.

class minerale:

    def __init__(self, nome, valore, peso):
        self.nome   = nome
        self.valore = valore
        self.peso   = peso

    def __str__(self):
        return f"{self.nome}, valore={self.valore}, peso={self.peso}"
#--------------------------------------------------------------------
MINERALI = [ minerale("m1", 39, 58),
             minerale("m2", 42, 64),
             minerale("m3", 40, 65),
             minerale("m4", 38, 59),
             minerale("m5", 37, 61),
             minerale("m6", 42, 62)
]
PESO_MAX = int(input("Scegli il peso massimo >> "))
#--------------------------------------------------------------------
soluzione = minerale("", 0, 0) 
n = len(MINERALI)
for i in range(n):
    for j in range(i+1, n):
        for k in range(j+1, n):
            # ------------------------------------ Nuova tripla
            m_1 = MINERALI[i]
            m_2 = MINERALI[j]
            m_3 = MINERALI[k]
            # ------------------------------------ Nuovo "minerale"
            m = minerale(m_1.nome    + "+" + m_2.nome   + "+" + m_3.nome,
                         m_1.valore  +       m_2.valore +       m_3.valore,
                         m_1.peso    +       m_2.peso   +       m_3.peso)        
            print(m)
            # ------------------------------------ Nuova soluzione?
            if(m.peso <= PESO_MAX) and (m.valore > soluzione.valore):             
                soluzione = m
#--------------------------------------------------------------------
print()
print(soluzione)
Scegli il peso massimo >> 180
m1+m2+m3, valore=121, peso=187
m1+m2+m4, valore=119, peso=181
m1+m2+m5, valore=118, peso=183
m1+m2+m6, valore=123, peso=184
m1+m3+m4, valore=117, peso=182
m1+m3+m5, valore=116, peso=184
m1+m3+m6, valore=121, peso=185
m1+m4+m5, valore=114, peso=178
m1+m4+m6, valore=119, peso=179
m1+m5+m6, valore=118, peso=181
m2+m3+m4, valore=120, peso=188
m2+m3+m5, valore=119, peso=190
m2+m3+m6, valore=124, peso=191
m2+m4+m5, valore=117, peso=184
m2+m4+m6, valore=122, peso=185
m2+m5+m6, valore=121, peso=187
m3+m4+m5, valore=115, peso=185
m3+m4+m6, valore=120, peso=186
m3+m5+m6, valore=119, peso=188
m4+m5+m6, valore=117, peso=182

m1+m4+m6, valore=119, peso=179