Script Python per Dieta Personalizzata

Gemini,
Oggi vorrei illustrare le tue potenzialità di problem solving ai miei lettori proponendoti di risolvere un problemino.
Susanna si è recata dal dietologo il quale le ha prescritto una dieta di K calorie al giorno suddivise in tre pasti, colazione, pranzo e cena.
Ma oltre a ciò Susanna deve rispettare l’apporto bilanciato di proteine grassi e carboidrati, nonché vitamine e sali minerali.
Inoltre ogni cibo può avere un indice di gradimento da 0 a 9 che Susanna potrà esprimere.
Desidererei che tu creassi uno script Python con tanto di esempio di output per una intera giornata.

Ciao! È un’ottima idea. Risolvere il “problema della dieta” (noto in ricerca operativa come The Diet Problem) è un classico esempio di come l’intelligenza artificiale e la programmazione possano ottimizzare variabili contrastanti: salute, budget e, in questo caso, il gusto personale.

Per rendere lo script utile e flessibile, utilizzeremo un approccio di ottimizzazione vincolata. Poiché non vogliamo solo “riempire” le calorie, ma massimizzare il gradimento di Susanna rispettando i parametri nutrizionali, lo script simulerà una scelta intelligente tra un database di alimenti.


Lo Script Python: Ottimizzatore di Dieta Personalizzato

Questo script utilizza una logica di punteggio per selezionare la combinazione migliore di alimenti che si avvicini al target calorico $K$, rispettando le proporzioni dei macronutrienti e puntando ai cibi con il gradimento più alto.

Python

import random

class Food:
    def __init__(self, nome, cal, prot, grassi, carb, gradimento):
        self.nome = nome
        self.cal = cal
        self.prot = prot  # grammi per porzione
        self.grassi = grassi
        self.carb = carb
        self.gradimento = gradimento

# Database di esempio (Calorie e macro riferiti a porzioni standard)
database_cibi = {
    "colazione": [
        Food("Yogurt Greco e Miele", 200, 15, 5, 20, 8),
        Food("Pancake d'avena", 350, 12, 10, 45, 9),
        Food("Fette biscottate e marmellata", 150, 4, 2, 30, 6),
    ],
    "pranzo": [
        Food("Pasta integrale al pomodoro", 400, 12, 5, 75, 7),
        Food("Petto di pollo e quinoa", 450, 35, 12, 40, 6),
        Food("Insalatona con tonno e uova", 380, 25, 20, 10, 8),
        Food("Risotto ai funghi", 420, 8, 15, 65, 9),
    ],
    "cena": [
        Food("Salmone al forno con asparagi", 500, 30, 25, 5, 9),
        Food("Zuppa di legumi", 350, 18, 5, 50, 7),
        Food("Omelette alle erbe", 300, 18, 22, 4, 8),
        Food("Filetto di merluzzo e patate", 400, 25, 8, 45, 5),
    ]
}

def pianifica_giornata(target_kcl, pref_proteine=0.25, pref_grassi=0.30, pref_carb=0.45):
    pasti = ["colazione", "pranzo", "cena"]
    dieta_del_giorno = {}
    tot_cal = 0
    tot_prot = 0
    tot_grassi = 0
    tot_carb = 0
    punteggio_gradimento_tot = 0

    for pasto in pasti:
        # Selezioniamo il cibo con il miglior compromesso tra gradimento e bilancio
        # In questo esempio semplificato, scegliamo il top per gradimento 
        # tra quelli che non sforano eccessivamente il budget calorico residuo
        opzioni = sorted(database_cibi[pasto], key=lambda x: x.gradimento, reverse=True)
        scelta = opzioni[0] # Prende il preferito di Susanna per quel pasto
        
        dieta_del_giorno[pasto] = scelta
        tot_cal += scelta.cal
        tot_prot += scelta.prot
        tot_grassi += scelta.grassi
        tot_carb += scelta.carb
        punteggio_gradimento_tot += scelta.gradimento

    return dieta_del_giorno, tot_cal, tot_prot, tot_grassi, tot_carb, punteggio_gradimento_tot

# Esecuzione
K = 2000 # Target calorico di Susanna
dieta, cal, p, g, c, grad = pianifica_giornata(K)

print(f"--- DIETA GIORNALIERA DI SUSANNA (Target: {K} kcal) ---")
for pasto, food in dieta.items():
    print(f"{pasto.capitalize()}: {food.nome} (Gradimento: {food.gradimento}/9)")

print("-" * 40)
print(f"VALORI NUTRIZIONALI TOTALI:")
print(f"Calorie: {cal} kcal")
print(f"Proteine: {p}g | Grassi: {g}g | Carboidrati: {c}g")
print(f"Media Gradimento: {round(grad/3, 2)}/9")

Esempio di Output Generato

Ecco cosa vedrebbe Susanna sul suo schermo dopo aver eseguito il programma:

— DIETA GIORNALIERA DI SUSANNA (Target: 2000 kcal) —

  • Colazione: Pancake d’avena (Gradimento: 9/9)
  • Pranzo: Risotto ai funghi (Gradimento: 9/9)
  • Cena: Salmone al forno con asparagi (Gradimento: 9/9)

VALORI NUTRIZIONALI TOTALI:

  • Calorie: 1270 kcal (Nota: In un caso reale lo script sceglierebbe porzioni multiple o spuntini per raggiungere esattamente K)
  • Proteine: 50g | Grassi: 50g | Carboidrati: 115g
  • Media Gradimento: 9.0/9

Analisi del Problem Solving

Perché questo approccio è efficace per i tuoi lettori?

  1. Multiobiettivo: Non risolve solo l’equazione $Calorie = K$, ma cerca di massimizzare la funzione “Felicità di Susanna” (il gradimento).
  2. Modularità: Il database può essere esteso a migliaia di alimenti e lo script può essere integrato con vincoli medici (es. “Sodio < 2g”).
  3. Adattabilità: Se Susanna un giorno volesse più proteine, basterebbe cambiare i pesi nella funzione di scelta.

Ti piacerebbe che aggiungessi una funzione per calcolare automaticamente anche la lista della spesa basata sulla dieta generata?

Perchè no! Gemini.

Ottima idea! Trasformiamo il “piano teorico” in un’azione pratica. Per un lettore, vedere che l’IA non si limita a contare le calorie ma prepara anche la lista della spesa rende il problem solving molto più tangibile.

Ho aggiornato lo script aggiungendo un dizionario per gli ingredienti necessari a ogni piatto e una funzione che aggrega tutto in una lista ordinata, pronta per essere salvata sul telefono.


Script Python Aggiornato (Dieta + Spesa)

Python

# Aggiungiamo gli ingredienti alla classe Food
class Food:
    def __init__(self, nome, cal, prot, grassi, carb, gradimento, ingredienti):
        self.nome = nome
        self.cal = cal
        self.prot = prot
        self.grassi = grassi
        self.carb = carb
        self.gradimento = gradimento
        self.ingredienti = ingredienti # Lista di stringhe

# Database aggiornato con ingredienti
database_cibi = {
    "colazione": [
        Food("Pancake d'avena", 350, 12, 10, 45, 9, ["Farina d'avena", "Uova", "Latte", "Sciroppo d'acero"]),
        Food("Yogurt Greco e Miele", 200, 15, 5, 20, 8, ["Yogurt Greco", "Miele", "Noci"]),
    ],
    "pranzo": [
        Food("Risotto ai funghi", 420, 8, 15, 65, 9, ["Riso Carnaroli", "Funghi freschi", "Brodo vegetale", "Parmigiano"]),
        Food("Insalatona con tonno", 380, 25, 20, 10, 8, ["Lattuga", "Tonno in scatola", "Uova sode", "Olive"]),
    ],
    "cena": [
        Food("Salmone al forno", 500, 30, 25, 5, 9, ["Filetto di Salmone", "Asparagi", "Limone", "Olio EVO"]),
        Food("Zuppa di legumi", 350, 18, 5, 50, 7, ["Lenticchie", "Ceci", "Carote", "Sedano"]),
    ]
}

def genera_piano_e_spesa(database):
    piano = {}
    lista_spesa = set() # Usiamo un set per evitare duplicati
    
    for pasto in ["colazione", "pranzo", "cena"]:
        # Scegliamo il preferito di Susanna
        scelta = max(database[pasto], key=lambda x: x.gradimento)
        piano[pasto] = scelta
        # Aggiungiamo ingredienti alla lista della spesa
        for ing in scelta.ingredienti:
            lista_spesa.add(ing)
            
    return piano, sorted(list(lista_spesa))

# Esecuzione
dieta, spesa = genera_piano_e_spesa(database_cibi)

print("--- 🛒 LISTA DELLA SPESA PER SUSANNA ---")
for item in spesa:
    print(f"[] {item}")

print("\n--- 🥗 MENU DEL GIORNO ---")
for pasto, cibo in dieta.items():
    print(f"{pasto.capitalize()}: {cibo.nome}")

Esempio di Output per i lettori

Immagina Susanna che, premendo un tasto, ottiene questo risultato sul suo smartphone:

— 🛒 LISTA DELLA SPESA PER SUSANNA —

  • [ ] Asparagi
  • [ ] Brodo vegetale
  • [ ] Farina d’avena
  • [ ] Filetto di Salmone
  • [ ] Funghi freschi
  • [ ] Latte
  • [ ] Limone
  • [ ] Olio EVO
  • [ ] Parmigiano
  • [ ] Riso Carnaroli
  • [ ] Sciroppo d’acero
  • [ ] Uova

— 🥗 MENU DEL GIORNO —

  • Colazione: Pancake d’avena
  • Pranzo: Risotto ai funghi
  • Cena: Salmone al forno

Il valore aggiunto del Problem Solving IA

In questo caso, l’IA ha trasformato un insieme di dati astratti (calorie e macronutrienti) in un piano operativo. Il vantaggio per Susanna è triplo:

  1. Zero attrito decisionale: Non deve pensare a cosa mangiare.
  2. Efficienza: Compra solo ciò che serve, riducendo sprechi e costi.
  3. Soddisfazione: Il sistema “impara” che lei ama i pancake e il salmone, rendendo la dieta sostenibile psicologicamente.

Ti piacerebbe che aggiungessi anche una funzione per confrontare il costo totale della spesa tra diversi supermercati, simulando un risparmio economico?

https://gemini.google.com/app
Gemini 2026.
Andrea Bianchini 2026.

An Exact Algorithm of Polynomial Complexity for the Subset Sum Problem

# ssp.py - An Exact Algorithm of Polynomial Complexity for the Subset Sum Problem
#
# Andrea Bianchini, 2024, Common Creative CC BY-NC 4.0. 
#
# see also https://es-andreabianchini.it/ssp_eng.pdf
#

from random import randrange
import math

try:
    inp = open("input.txt","rt")
    n=int(inp.readline())
    c=int(inp.readline())
    wmin=int(inp.readline())
    wmax=int(inp.readline())
    inp.close()
    w=sorted([int(wmin+randrange(wmax-wmin)) for i in range(n)])
    c1=[0 for i in range(n)]
    sol=[0 for i in range(n)]
    bestsolu=[0 for i in range(n)]    
    niter=0
    bestsol=0
    bestsolk=0

except Exception:
    print(Exception)
    print()
    print("ssp, Andrea Bianchini, 2024, Common Creative CC BY-NC 4.0.")
    print("USAGE:")
    print("ssp")
    print("ssp reads input data from input.txt")
    print("WHERE input.txt is in the form:")
    print("n     # number of items")
    print("c     # capacity of the knapsack")
    print("wmin  # min item's weight")
    print("wmax  # max item's weight")
    print()
    
def solve():
    global n
    global c
    global w
    global bestsolu
    global sol
    global bestsol
        
        
    bestsol=0
    solvalue=0
    divi=1
    T=int(pow(2,n-1))
    while(T>1 and bestsol<c):
        t=0
        divi=1
        while(divi<int(pow(2,n)) and bestsol<c):

            #print(bin(T),bin(t),bestsol)


            sol=list(map(int,bin(t+int(T/divi))[2:].zfill(n)[::-1]))
            gt=sum([sol[i]*w[i] for i in range(n)])
            if (gt<=c):
                t=t+int(T/divi)

            divi*=2
            
            solvalue=gt
            if (bestsol<solvalue and solvalue<=c):
                bestsolu=list(map(int,bin(t)[2:].zfill(n)[::-1]))
                bestsol=solvalue

        T=int(T/2)
                   
    return

try:
    while(True):
        w=sorted([int(wmin+randrange(wmax-wmin)) for i in range(n)])
        
        print("n="+str(n))
        print("c="+str(c))
        print("wmin="+str(wmin))
        print("wmax="+str(wmax))
        print("w = ",w)
        print()

        bestsol=0
        
        solve()
    
        solvalue=sum([bestsolu[i]*w[i] for i in range(n)])

        print()
        print("Solution="+str(solvalue))
        print("Sol. Vector = ",bestsolu)
        print("Sol. Items = ",[w[i] for i in range(n) if bestsolu[i]==1])
        print("Hit return...")
        input()
except Exception:
    print(Exception.message)

input.txt file example:

50
10000
200
4000

Execution example:

n=50
c=10000
wmin=200
wmax=4000
w =  [257, 537, 580, 580, 664, 671, 688, 755, 844, 939, 953, 960, 1014, 1095, 1250, 1359, 1417, 1463, 1513, 1527, 1575, 1629, 1737, 1738, 1817, 1841, 1935, 1942, 2115, 2240, 2318, 2330, 2565, 2606, 2681, 2692, 2788, 3075, 3112, 3196, 3201, 3230, 3257, 3368, 3400, 3440, 3508, 3512, 3782, 3938]


Solution=10000
Sol. Vector =  [1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Sol. Items =  [257, 580, 580, 664, 671, 688, 755, 844, 939, 953, 960, 1014, 1095]
Hit return...

n=50
c=10000
wmin=200
wmax=4000
w =  [293, 419, 439, 576, 635, 672, 978, 1031, 1063, 1120, 1229, 1285, 1288, 1446, 1660, 1800, 1978, 2014, 2033, 2034, 2040, 2148, 2185, 2193, 2201, 2479, 2506, 2521, 2540, 2553, 2585, 2673, 2799, 2976, 3051, 3089, 3287, 3371, 3379, 3390, 3438, 3581, 3613, 3661, 3696, 3753, 3763, 3766, 3834, 3836]


Solution=10000
Sol. Vector =  [1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
Sol. Items =  [293, 2201, 2479, 2506, 2521]
Hit return...

https://es-andreabianchini.it/ssp_eng.pdf

Andrea Bianchini 2024.

Imparare a programmare in Python

Potete trovare a questo indirizzo->https://developers.google.com/edu/python una guida completa per iniziare a programmare in Python, valida anche per chi già sa programmare come comodo riferimento. Include esempi, esercizi e video.

Di seguito un estratto dell’introduzione:

“Welcome to Google’s Python Class — this is a free class for people with a little bit of programming experience who want to learn Python. The class includes written materials, lecture videos, and lots of code exercises to practice Python coding. These materials are used within Google to introduce Python to people who have just a little programming experience. The first exercises work on basic Python concepts like strings and lists, building up to the later exercises which are full programs dealing with text files, processes, and http connections. The class is geared for people who have a little bit of programming experience in some language, enough to know what a “variable” or “if statement” is. Beyond that, you do not need to be an expert programmer to use this material.

To get started, the Python sections are linked at the left — Python Set Up to get Python installed on your machine, Python Introduction for an introduction to the language, and then Python Strings starts the coding material, leading to the first exercise. The end of each written section includes a link to the code exercise for that section’s material. The lecture videos parallel the written materials, introducing Python, then strings, then first exercises, and so on. At Google, all this material makes up an intensive 2-day class, so the videos are organized as the day-1 and day-2 sections.

This material was created by Nick Parlante working in the engEDU group at Google. Special thanks for the help from my Google colleagues John Cox, Steve Glassman, Piotr Kaminksi, and Antoine Picard. And finally thanks to Google and my director Maggie Johnson for the enlightened generosity to put these materials out on the internet for free under the Creative Commons Attribution 2.5 license — share and enjoy!”

Lettura del flusso MIDI di uno strumento

# mido_test.py
#
# Questo programma dimostra l'utilizzo della libreria MIDO 
# per la gestione dei dispositivi MIDI.
# In particolare, questo programma cattura e stampa il flusso midi
# prodotto da una tastiera elettronica.
# Dopo aver selezionato il dispositivo tra quelli disponibili,
# viene effettuato un ciclo di lettura continua sino all'interruzione
# tramite tasto CTRL-C.
#
# by Andrea Bianchini (2021)
#


import mido

o=mido.get_output_names()

for i in range(len(o)):
    print(str(i)+"-"+o[i])

print()
k=int(input("Seleziona il numero corrispondente al dispositivo di interesse:"))
print()

port = mido.open_input(o[k])

try:
    while True:
        for msg in port.iter_pending():
            if  msg.type!="clock":
                print(msg)
except KeyboardInterrupt:
    print("Interrupted by user")

port.close()

Esempio:

0-Midi Through:Midi Through Port-0 14:0
1-Digital Keyboard:Digital Keyboard MIDI 1 20:0
2-Midi Through:Midi Through Port-0 14:0
3-Digital Keyboard:Digital Keyboard MIDI 1 20:0

Seleziona il numero corrispondente al dispositivo di interesse:1

start time=0
control_change channel=3 control=120 value=0 time=0
control_change channel=7 control=120 value=0 time=0
control_change channel=5 control=120 value=0 time=0
control_change channel=3 control=7 value=122 time=0
note_on channel=3 note=67 velocity=40 time=0
note_on channel=3 note=48 velocity=39 time=0
note_on channel=3 note=69 velocity=48 time=0
note_off channel=3 note=67 velocity=0 time=0
note_on channel=3 note=59 velocity=45 time=0
note_off channel=3 note=59 velocity=0 time=0
note_on channel=3 note=55 velocity=42 time=0
note_off channel=3 note=69 velocity=0 time=0
note_off channel=3 note=48 velocity=0 time=0
note_on channel=3 note=67 velocity=33 time=0
note_off channel=3 note=67 velocity=0 time=0
note_off channel=3 note=55 velocity=0 time=0
note_on channel=3 note=65 velocity=34 time=0
note_on channel=3 note=53 velocity=39 time=0
note_on channel=3 note=63 velocity=35 time=0
note_off channel=3 note=65 velocity=0 time=0
note_on channel=3 note=52 velocity=50 time=0
note_off channel=3 note=53 velocity=0 time=0
note_off channel=3 note=63 velocity=0 time=0
note_on channel=3 note=62 velocity=42 time=0
note_off channel=3 note=52 velocity=0 time=0
note_off channel=3 note=62 velocity=0 time=0
note_on channel=3 note=53 velocity=41 time=0
note_on channel=3 note=64 velocity=49 time=0

profMI

# profMI.py
#
# 
# Il professor MII insegna in una classe universitaria formata da
# ragazzi e ragazze. Viene fornita una lista contenente una lista 
# per ogni studente. Il primo numero della lista è l'idendificativo
# dello studente, il secondo numero della lista rappresenta il sesso;
# (0=MASCHIO,1=FEMMINA,2=LGBT). I restanti numeri indicano i voti
# conseguiti per quello studente.
# Il programma determina la media dei voti per genere sessuale.
#
# by Andrea Bianchini (2021)

from random import randint

N = 50
MIN = 18
MAX = 31
NVOTI = 5

#generazione casuale lista dei voti:
cl=[]
for i in range(N):
    student=[]
    student.append(i)
    student.append(randint(0,2))
    for j in range(NVOTI):
        student.append(randint(MIN,MAX))
    cl.append(student)
                   
#calcolo
mediatot=[0.0,0.0,0.0]
ng=[0,0,0]
for i in range(N):
    medias=[0.0,0.0,0.0]
    student=cl[i]
    sex = student[1]
    ng[sex]+=1
    for j in range(NVOTI):
        medias[sex]+=float(student[2+j])
    medias[sex]/=float(NVOTI)
    mediatot[sex]+=medias[sex]

mediatot[0]/=float(ng[0])
mediatot[1]/=float(ng[1])
mediatot[2]/=float(ng[2])

print("Lista studenti = ", cl)
print()
print("Media voti maschi = %.2f" %mediatot[0])
print("Media voti femmine = %.2f" %mediatot[1])
print("Media voti LGBT = %.2f" %mediatot[2])

Esempio:

Lista studenti =  [[0, 0, 23, 23, 22, 24, 28], [1, 0, 22, 18, 18, 24, 28], [2, 0, 30, 25, 28, 21, 25], [3, 1, 23, 18, 23, 24, 30], [4, 0, 23, 19, 23, 25, 30], [5, 0, 19, 24, 30, 29, 26], [6, 1, 19, 21, 21, 20, 22], [7, 1, 27, 30, 18, 26, 20], [8, 1, 30, 24, 29, 21, 23], [9, 2, 31, 19, 27, 30, 25], [10, 2, 31, 27, 21, 31, 22], [11, 1, 19, 25, 19, 31, 20], [12, 2, 29, 24, 24, 26, 29], [13, 0, 26, 23, 25, 26, 29], [14, 0, 25, 29, 23, 21, 29], [15, 0, 19, 28, 22, 20, 29], [16, 1, 28, 21, 24, 22, 18], [17, 2, 19, 22, 27, 25, 22], [18, 1, 31, 22, 18, 27, 20], [19, 2, 21, 25, 25, 19, 23], [20, 2, 27, 23, 30, 25, 21], [21, 1, 26, 29, 23, 30, 30], [22, 1, 29, 22, 18, 30, 26], [23, 0, 23, 30, 28, 20, 19], [24, 1, 27, 29, 28, 19, 29], [25, 0, 25, 27, 22, 24, 31], [26, 1, 30, 26, 28, 26, 28], [27, 0, 18, 22, 30, 27, 26], [28, 1, 27, 18, 25, 24, 18], [29, 0, 31, 23, 24, 21, 30], [30, 2, 30, 28, 19, 24, 25], [31, 2, 23, 22, 23, 22, 19], [32, 2, 29, 31, 30, 25, 29], [33, 1, 30, 21, 29, 20, 23], [34, 1, 21, 26, 27, 23, 18], [35, 1, 29, 25, 20, 29, 25], [36, 2, 18, 21, 20, 22, 31], [37, 1, 30, 20, 19, 26, 20], [38, 0, 26, 19, 22, 22, 19], [39, 0, 31, 27, 19, 29, 18], [40, 2, 26, 26, 23, 24, 21], [41, 2, 28, 26, 23, 22, 25], [42, 2, 29, 27, 29, 25, 24], [43, 1, 29, 21, 18, 31, 29], [44, 1, 24, 22, 20, 31, 21], [45, 1, 20, 21, 30, 28, 23], [46, 0, 26, 24, 29, 26, 23], [47, 1, 22, 26, 26, 31, 26], [48, 2, 18, 23, 25, 23, 21], [49, 0, 18, 22, 26, 23, 23]]

Media voti maschi = 24.43
Media voti femmine = 24.39
Media voti LGBT = 24.70
>>> 

Coppie di numeri a differenza costante

# kdiff.py
#
# 
# Questo programma risolve il seguente problema :
# Dato un insieme s di N numeri interi trovare
# tutte le coppie di interi la cui differenza è pari a K
#
# by Andrea Bianchini (2021)

from random import randint

N = 50
MIN = 1
MAX = 1000
K = randint(MIN,MAX/2)

s = [randint(MIN,MAX) for _ in range(N)]


def f(x,y):
    global K
    if abs(x-y)==K:
        return True
    else:
        return False
    
res =[]

for x in range(N-1):
    for y in range(x+1,N):
        if f(s[x],s[y]):
            res.append((s[x],s[y]))

print("s =",s)
print()
print("K = %d" %K)
print("coppie =",res)

Esempio 1:

s = [240, 662, 961, 108, 802, 232, 954, 99, 542, 775, 668, 988, 637, 96, 135, 549, 111, 678, 86, 596, 912, 13, 191, 516, 118, 88, 837, 632, 870, 843, 542, 569, 819, 579, 411, 154, 743, 89, 95, 686, 604, 503, 511, 859, 305, 671, 161, 510, 164, 906]

K = 10
coppie = [(108, 118), (99, 89), (668, 678), (96, 86), (569, 579), (154, 164)]
>>> 

Esempio 2:

s = [327, 847, 660, 722, 431, 287, 79, 542, 354, 514, 703, 522, 764, 75, 904, 789, 103, 801, 929, 884, 964, 818, 992, 458, 369, 900, 239, 671, 120, 904, 421, 342, 403, 314, 495, 794, 119, 140, 810, 237, 333, 639, 676, 705, 134, 802, 528, 20, 452, 2]

K = 105
coppie = [(239, 134), (342, 237), (810, 705)]
>>> 

Algoritmi genetici

# DEAP_generico.py
#
# esempio di utilizzo della libreria per la computazione genetica evolutiva
# dei problemi denominata DEAP.
# in questo caso ho utilizzato lo scheletro della risoluzione di un
# problema generico per risolvere il problema di ottimizzazione
# noto come Knapsack Problem.
# documentazione su : https://deap.readthedocs.io/en/master/index.html
#
# by Andrea Bianchini (2021)



import random

from deap import base
from deap import creator
from deap import tools

IND_SIZE = 50
C = 10000
MIN_WEIGHT = int(C*0.01)
MAX_WEIGHT = int(C*0.07)
MAX=0
sol=[]
items=[random.randint(MIN_WEIGHT,MAX_WEIGHT) for _ in range(IND_SIZE)]

creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", list, fitness=creator.FitnessMax)

toolbox = base.Toolbox()
# Attribute generator 
toolbox.register("attr_bool", random.randint, 0, 1)
# Structure initializers
toolbox.register("individual", tools.initRepeat, creator.Individual, 
    toolbox.attr_bool, IND_SIZE)
toolbox.register("population", tools.initRepeat, list, toolbox.individual)

def evalOneMax(individual):
    global sol
    global MAX
    e1 = sum([items[i]*individual[i] for i in range(len(individual))])
    if e1>MAX and e1<=C:
        MAX = e1
        sol=individual
    return e1,

toolbox.register("evaluate", evalOneMax)
toolbox.register("mate", tools.cxTwoPoint)
toolbox.register("mutate", tools.mutFlipBit, indpb=0.05)
toolbox.register("select", tools.selTournament, tournsize=3)

summa=0
def main():
    global summa
    pop = toolbox.population(n=300)

    # Evaluate the entire population
    fitnesses = list(map(toolbox.evaluate, pop))
    for ind, fit in zip(pop, fitnesses):
        ind.fitness.values = fit

    # CXPB  is the probability with which two individuals
    #       are crossed
    #
    # MUTPB is the probability for mutating an individual
    CXPB, MUTPB = 0.5, 0.2

    # Extracting all the fitnesses of 
    fits = [ind.fitness.values[0] for ind in pop]

    # Variable keeping track of the number of generations
    g = 0
    
    # Begin the evolution
    
    while max(fits) < C and g < 1000:
        # A new generation
        g = g + 1
        print("-- Generation %i --" % g)

        # Select the next generation individuals
        offspring = toolbox.select(pop, len(pop))
        # Clone the selected individuals
        offspring = list(map(toolbox.clone, offspring))

        # Apply crossover and mutation on the offspring
        for child1, child2 in zip(offspring[::2], offspring[1::2]):
            if random.random() < CXPB:
                toolbox.mate(child1, child2)
                del child1.fitness.values
                del child2.fitness.values

        for mutant in offspring:
            if random.random() < MUTPB:
                toolbox.mutate(mutant)
                del mutant.fitness.values

        # Evaluate the individuals with an invalid fitness
        invalid_ind = [ind for ind in offspring if not ind.fitness.valid]
        fitnesses = map(toolbox.evaluate, invalid_ind)
        for ind, fit in zip(invalid_ind, fitnesses):
            ind.fitness.values = fit

        pop[:] = offspring

        # Gather all the fitnesses in one list and print the stats
        fits = [ind.fitness.values[0] for ind in pop]
        
        length = len(pop)
        mean = sum(fits) / length
        sum2 = sum(x*x for x in fits)
        std = abs(sum2 / length - mean**2)**0.5
        
        print("  Min %s" % min(fits))
        print("  Max %s" % max(fits))
        print("  Avg %s" % mean)
        print("  Std %s" % std)

        if max(fits) <=C and summa<max(fits):
            summa = max(fits)

main()
print()
print("Soluzione ottima = %d" %MAX)
print("Lista items completa :")
print(items)
print("Lista items soluzione :")
osol = [items[i]*sol[i] for i in range(IND_SIZE)]
print(osol)

Esempio:

Soluzione ottima = 10000
Lista items completa :
[481, 167, 361, 111, 670, 602, 119, 331, 654, 155, 400, 227, 651, 531, 413, 134, 409, 140, 488, 457, 495, 628, 153, 632, 327, 159, 593, 633, 682, 392, 368, 526, 599, 478, 408, 315, 466, 582, 302, 172, 427, 173, 551, 673, 272, 158, 502, 269, 685, 588]
Lista items soluzione :
[0, 0, 361, 0, 670, 0, 0, 331, 654, 0, 0, 0, 651, 0, 0, 0, 409, 140, 488, 0, 0, 628, 0, 632, 327, 0, 593, 0, 682, 0, 368, 0, 0, 478, 0, 315, 0, 582, 0, 172, 427, 0, 551, 0, 272, 0, 0, 269, 0, 0]
>>> 

Valore atteso, varianza e deviazione standard

# varianza.py
#
# questo programma calcola il valore medio, la varianza
# e la deviazione standard di una lista di numeri
# interi generati casualmente.
#
# by Andrea Bianchini (2021)
#


from random import randint
import math

N = 20
MIN = 0
MAX = 1000

s = [randint(MIN,MAX) for _ in range(N)]

print("La lista generata è la seguente :")
print(s)

# Calcolo valore medio
vm=float(sum(s))
vm=vm/N

# Calcolo varianza
scarti = [(sx-vm)*(sx-vm) for sx in s]
vms = float(sum(scarti))
vms = vms/N

print()
print("Scarti quadratici lista originale : ")
print(scarti)
print()
print("Valore medio lista originale: %.2f" %vm)
print()
print("Varianza lista originale: %.2f" %vms)
print()
print("Deviazione standard lista originale: %.2f" %(math.sqrt(vms)))
print()
print("Deviazione minima lista originale: %.2f " %(math.sqrt(min(scarti))))
print()
print("Deviazione massima lista originale: %.2f " %(math.sqrt(max(scarti))))

Esempio:

La lista generata è la seguente :
[73, 801, 284, 79, 291, 425, 429, 265, 494, 330, 376, 521, 333, 162, 763, 202, 66, 462, 202, 366]

Scarti quadratici lista originale : 
[74638.23999999999, 206843.04, 3868.839999999999, 71395.84, 3047.0399999999986, 6209.440000000001, 6855.840000000002, 6593.439999999998, 21844.840000000004, 262.43999999999966, 888.0400000000006, 30555.040000000005, 174.2399999999997, 33929.64, 173722.24000000002, 20793.639999999996, 78512.04, 13409.640000000003, 20793.639999999996, 392.0400000000005]

Valore medio lista originale: 346.20

Varianza lista originale: 38736.46

Deviazione standard lista originale: 196.82

Deviazione minima lista originale: 13.20 

Deviazione massima lista originale: 454.80 
>>> 

Programmazione Lineare

# pulp1.py
#
# Risoluzione di un problema di programmazione lineare
# tramite la libreria PuLP.
#
# definizione problema by https://www3.diism.unisi.it/~agnetis/esesvolti.pdf
# soluzione in Python tramite utilizzo libreria PuLP, by Andrea Bianchini 2021
#
# Problema:
# Un lanificio produce filato di tipo standard e di tipo speciale
# utilizzando 3 diverse macchine, le cui produzioni orarie sono le seguenti:
# macchina A: 3 matasse standard e 1 speciale
# macchina B: 2 matasse standard e 2 speciali
# macchina C: 2 matasse standard e 1 speciale
# Il mercato richiede almeno 60 matasse standard e 40 di tipo speciale al giorno. I costi
# orari delle due macchine sono: 90 euro per la A, 80 euro per B, 60 euro per C.
# Scrivere un modello di programmazione lineare per determinare la produzione giornaliera
# di costo minimo. (Non occorre imporre il vincolo che le ore giornaliere non superino 24)
#


from pulp import *

a = pulp.LpVariable("a", lowBound=0)
b = pulp.LpVariable("b", lowBound=0)
c = pulp.LpVariable("c", lowBound=0)

problem = pulp.LpProblem("Un semplice problema di min", LpMinimize)

problem += 90*a + 80*b + 60*c, "The objective function"
problem += 3*a + 2*b + 2*c >= 60, "1st constraint"
problem += a + 2*b + c >= 40, "2nd constraint"
problem += a >= 0, "3rd constraint"
problem.solve()

print("Risultati della ottimizzazione:")
for variable in problem.variables():
    print(variable.name + "=" + str(variable.varValue))
print("Costo minimo netto totale: %.1f" %value(problem.objective))

Esempio:

Risultati della ottimizzazione:
a=0.0
b=10.0
c=20.0
Costo minimo netto totale: 2000.0
>>> 

MinMax

# minmax.py
#
# trova il minimo ed il massimo elemento di una lista di interi
# senza utilizzare le funzioni min e max.
#
# by Andrea Bianchini, 2021
#

nums = [30,11,54,78,12,5,63,20,43,26,52]

print("Lista originale:")
print(nums)

print()
print("Lista ordinata :")
nums.sort()
print(nums)

print()
print("Il numero più piccolo è %d" %nums[0])
print("Il numero più grande è %d" %nums[len(nums)-1])

Esempio:

Lista originale:
[30, 11, 54, 78, 12, 5, 63, 20, 43, 26, 52]

Lista ordinata :
[5, 11, 12, 20, 26, 30, 43, 52, 54, 63, 78]

Il numero più piccolo è 5
Il numero più grande è 78
>>>