Professional Documents
Culture Documents
import numpy as np
import matplotlib.pyplot as plt
#from mpl_toolkits.mplot3d import Axes3D
from tqdm import tqdm
Στο 7ο μάθημα είδαμε τον Γενετικό Αλγόριθμο, που είναι (με διαφορά) ο πιο δημοφιλής μετα-ευριστικός
αλγόριθμος βελτιστοποίησης. Στα μαθήματα 8 και 9 θα δούμε τους τέσσερις αμέσως δημοφιλέστερους μετα-
ευριστικούς αλγόριθμους, από δύο σε κάθε μάθημα.
Σήμερα θα δούμε δύο αλγόριθμους για αριθμητική βελτιστοποίηση, και συγκεκριμένα, για ελαχιστοποίηση της
συνάρτησης rastrigin.
http://localhost:8889/notebooks/python%20projects/optimization/9_Metaheuristics_Numerical.ipynb 1/7
31/5/2022 9_Metaheuristics_Numerical - Jupyter Notebook
Αυτή η συνάρτηση έχει σαν ελάχιστη πιθανή τιμή το 0, δηλαδή 𝑓𝑚𝑖𝑛 (𝑥) = 0, που προκύπτει για
𝑥 = [0,0,...,0].
Ας την ορίσουμε
In [2]:
def rastrigin(x):
f = 0
for i in np.arange(x.shape[0]):
f += x[i]*x[i]-(10*np.cos(2*np.pi*x[i]))+10
return f
Simulated Annealing
Ο αλγόριθμος Simulated Annealing ξεκινάει από κάποιο αρχικό, τυχαίο σημείο, και σε κάθε επανάληψη
αποφασίζει, με κάποια τυχαιότητα, αν θα μεταβεί σε κάποιο άλλο σημείο. Οι πιθανότητα για το αν θα μεταβεί σε
άλλο σημείο ή όχι εξαρτώνται από το αν το άλλο σημείο αποτελεί καλύτερη λύση. Όσο προχωρούν οι
επαναλήψεις, οι πιθανότητες μειώνονται, οδηγώντας σε ένα ενεργειακά σταθερό σύστημα και εξομοιώνοντας
την κίνηση των ατόμων σε μεγάλες θερμοκρασίες, που μειώνεται όσο οι θερμοκρασία πέφτει.
Αυτή η φυσική διεργασία ονομάζεται annealing. Αυτό εξομοιώνεται με μια παράμετρο Τ που συμβολίζει την
"θερμοκρασία" του συστήματος. Όσο προχωρούν οι επαναλήψεις τόσο μειώνεται η θερμοκρασία, και τόσο
μικραίνουν οι πιθανότητες να αλλάξουμε την λύση.
Παρακάτω γράφουμε τον αλγόριθμο σε μορφή συνάρτησης και τον τρέχουμε. Η συνάρτηση παίρνει τα εξής
ορίσματα:
http://localhost:8889/notebooks/python%20projects/optimization/9_Metaheuristics_Numerical.ipynb 2/7
31/5/2022 9_Metaheuristics_Numerical - Jupyter Notebook
In [228]:
def sa(func,dim,minx,maxx,T=100,a=0.95,n_iter=100):
for i in tqdm(range(n_iter)):
step = np.random.uniform(-1,1,size=2)
candidate = x + step
fc = func(candidate)
df = fx - fc
p = np.exp(df/T)
if np.random.uniform(0,1) <= p:
x = candidate.copy()
fx = fc.copy()
T *= a
monitor.append(fx)
return x, monitor
In [226]:
x, monitor[-1]
Out[226]:
http://localhost:8889/notebooks/python%20projects/optimization/9_Metaheuristics_Numerical.ipynb 3/7
31/5/2022 9_Metaheuristics_Numerical - Jupyter Notebook
In [227]:
plt.plot(np.arange(len(monitor)),monitor);
In [163]:
x = np.random.uniform(-5.12,5.21,2)
c = np.random.uniform(-5.12,5.21,2)
fx, fc = func(x), func(c)
print('fx:',fx)
print('fc:',fc)
print('probability to switch:',np.round(np.exp(fx-fc),5))
fx: 58.64128401521241
fc: 56.64608951387444
probability to switch: 7.35363
Τα σωματίδια κάνουν ένα βήμα προς μια κατεύθυνση που υπολογίζει ο αλγόριθμος. Η κατεύθυνση αυτή
εξαρτάται: 1) από την προηγούμενη κατεύθυνση του σωματιδίου, 2) από την καλύτερη λύση που βρέθηκε
ποτέ από όλα τα σωματίδια, και 3) από την καλύτερη λύση που έχει βρει το συγκεκριμένο σωματίδιο.
Υπολογίζεται η καλύτερη λύση από όλα τα σωματίδια και αποθηκεύεται.
Πριν δούμε τον αλγόριθμο πιο αναλυτικά, ας ορίσουμε μια κλάση Particle, όπου κάθε σωματίδιο θα έχει τα εξής
χαρακτηριστικά:
http://localhost:8889/notebooks/python%20projects/optimization/9_Metaheuristics_Numerical.ipynb 4/7
31/5/2022 9_Metaheuristics_Numerical - Jupyter Notebook
In [254]:
class Particle:
def __init__(self,mini,maxi,n):
self.position = np.random.uniform(mini,maxi,n)
self.velocity = np.random.rand(n)
self.fitness = rastrigin(self.position)
self.best_position = np.copy(self.position)
self.best_fitness = self.fitness
Όπως είπαμε, η κατεύθυνση που θα πάρει το σωματίδιο καθορίζεται από τρεις παράγοντες. Η βαρύτητα που θα
έχει κάθε παράγοντας επιλέγεται από εμάς με τις εξής παραμέτρους:
w1: Αδράνεια: όσο μεγαλύτερη, τόσο τείνει το σωματίδιο να πάει προς την κατεύθυνση που ήδη έχει
w2: Αυτονομία: όσο μεγαλύτερη, τόσο τείνει το σωματίδιο να πάει προς την καλύτερη λύση που έχει βρει το
ίδιο
w3: Κοινωνικότητα: όσο μεγαλύτερη, τόσο τείνει το σωματίδιο να πάει προς την καλύτερη ολική λύση από
όλα τα σωματίδια
1. Αρχικοποίηση σωματιδίων, τριών παραμέτρων W, λαλύτερες θέσεις είναι οι τωρινές τυχαίες, η καλύτερη
ολική λύση είναι τυχαία, η καλύτερη ολική fitness είναι μια πολύ υψηλή τιμή. (Επειδή έχουμε
ελαχιστοποίηση συνάρτησης, θα ελαχιστοποιήσουμε και την fitness)
2. Ξεκινάμε τις επαναλήψεις, αριθμός επαναλήψεων = n_iter.
3. Ανανέωσε την θέση των σωματιδίων.
4. Συγκρινε τις θέσεις τους με τις καλύτερές τους, ανανέωσε τις καταχωρήσεις των καλύτερων αν χρειαστεί.
5. Για όποιες καταχωρήσεις ανανεώθηκαν, σύγκρινε με ολική καλύτερη, ανανέωσε καταχώρηση ολικής
καλύτερης αν χρειαστεί.
6. Επιστροφή στο βήμα 3.
Όταν οι επαναλήψεις τελειώσουν, η λύση που βρέθηκε είναι αποθηκευμένη στην μεταβλητή της καλύτερης
ολικής λύσης.
http://localhost:8889/notebooks/python%20projects/optimization/9_Metaheuristics_Numerical.ipynb 5/7
31/5/2022 9_Metaheuristics_Numerical - Jupyter Notebook
In [255]:
# initializations
mini, maxi = -5.12,5.12
n = 3
best_g_position = np.zeros((n))#np.random.uniform(mini,maxi,n)
best_g_fitness = sys.float_info.max#rastrigin(best_g_position)
swarm_size = 100
swarm = [ Particle(mini,maxi,n) for i in range(swarm_size) ]
w1 = 0.1
w2 = 1.494
w3 = 1
monitor_fitness = []
#----------------------------------
n_iter = 500
for i in tqdm(range(n_iter)):
for i in range(swarm_size):
for k in range(n):
swarm[i].position += swarm[i].velocity
swarm[i].fitness = rastrigin(swarm[i].position)
monitor_fitness.append(best_g_fitness)
best_g_fitness,np.round(best_g_position,6)
Out[255]:
http://localhost:8889/notebooks/python%20projects/optimization/9_Metaheuristics_Numerical.ipynb 7/7