updating jupyter
This commit is contained in:
parent
9a33746a6e
commit
ac75e0f5d8
1129
Projet_algo.ipynb
1129
Projet_algo.ipynb
File diff suppressed because one or more lines are too long
74
tests/libs/pso.py
Normal file
74
tests/libs/pso.py
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
# Import necessary libraries
|
||||||
|
import numpy as np
|
||||||
|
from sklearn.cluster import KMeans
|
||||||
|
|
||||||
|
# Class to represent a Particle in Particle Swarm Optimization
|
||||||
|
class Particle:
|
||||||
|
def __init__(self, num_cities, num_trucks, distances, time_windows, infinite_distance_value=1e6):
|
||||||
|
# Initialize the particle's position, velocity, and best position
|
||||||
|
self.position = np.random.permutation(range(1, num_cities+1))
|
||||||
|
self.velocity = np.zeros_like(self.position)
|
||||||
|
self.best_position = self.position.copy()
|
||||||
|
self.best_cost = float('inf')
|
||||||
|
self.num_trucks = num_trucks
|
||||||
|
self.distances = distances
|
||||||
|
self.time_windows = time_windows
|
||||||
|
self.infinite_distance_value = infinite_distance_value
|
||||||
|
|
||||||
|
# Cluster the cities based on their distances
|
||||||
|
self.city_cluster = self.cluster_cities()
|
||||||
|
|
||||||
|
# Function to cluster cities based on their distances
|
||||||
|
def cluster_cities(self):
|
||||||
|
# Replace infinite distances with a large finite value
|
||||||
|
clustering_distances = np.where(self.distances == float('inf'), self.infinite_distance_value, self.distances)
|
||||||
|
kmeans = KMeans(n_clusters=self.num_trucks, n_init=10)
|
||||||
|
clusters = kmeans.fit_predict(clustering_distances)
|
||||||
|
return clusters
|
||||||
|
|
||||||
|
# Function to evaluate the cost of the particle's current position
|
||||||
|
def evaluate_cost(self):
|
||||||
|
# Split cities among trucks
|
||||||
|
trucks = [[] for _ in range(self.num_trucks)]
|
||||||
|
for i in range(len(self.position)):
|
||||||
|
current_city = int(self.position[i])
|
||||||
|
truck = self.city_cluster[current_city - 1]
|
||||||
|
trucks[truck].append(current_city)
|
||||||
|
|
||||||
|
# Calculate the total cost based on the schedule of each truck
|
||||||
|
total_cost = 0
|
||||||
|
for truck in trucks:
|
||||||
|
if len(truck) > 0:
|
||||||
|
departure_time = self.time_windows[truck[0] - 1][0]
|
||||||
|
for i in range(len(truck) - 1):
|
||||||
|
u, v = int(truck[i]), int(truck[i+1])
|
||||||
|
distance = self.distances[u-1, v-1] if self.distances[u-1, v-1] != float('inf') else self.infinite_distance_value
|
||||||
|
total_cost += distance
|
||||||
|
arrival_time = departure_time + distance
|
||||||
|
time_window = self.time_windows[v-1]
|
||||||
|
if arrival_time < time_window[0]:
|
||||||
|
total_cost += time_window[0] - arrival_time
|
||||||
|
departure_time = time_window[0]
|
||||||
|
elif arrival_time > time_window[1]:
|
||||||
|
total_cost += arrival_time - time_window[1]
|
||||||
|
departure_time = arrival_time
|
||||||
|
else:
|
||||||
|
departure_time = arrival_time
|
||||||
|
return total_cost
|
||||||
|
|
||||||
|
# Function to update the particle's velocity
|
||||||
|
def update_velocity(self, global_best_position, inertia_weight, cognitive_weight, social_weight):
|
||||||
|
r1 = np.random.random()
|
||||||
|
r2 = np.random.random()
|
||||||
|
cognitive_component = cognitive_weight * r1 * (self.best_position - self.position)
|
||||||
|
social_component = social_weight * r2 * (global_best_position - self.position)
|
||||||
|
self.velocity = inertia_weight * self.velocity + cognitive_component + social_component
|
||||||
|
|
||||||
|
# Function to update the particle's position based on its velocity
|
||||||
|
def update_position(self):
|
||||||
|
indices = np.random.choice(range(len(self.position)), 2, replace=False)
|
||||||
|
self.position[indices[0]], self.position[indices[1]] = self.position[indices[1]], self.position[indices[0]]
|
||||||
|
current_cost = self.evaluate_cost()
|
||||||
|
if current_cost < self.best_cost:
|
||||||
|
self.best_cost = current_cost
|
||||||
|
self.best_position = self.position.copy()
|
||||||
@ -14,7 +14,6 @@ class SimulatedAnnealing:
|
|||||||
self.temperature_ok = temperature_ok
|
self.temperature_ok = temperature_ok
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
interration = 0
|
|
||||||
current_solution = self.cities.copy()
|
current_solution = self.cities.copy()
|
||||||
best_solution = self.cities.copy()
|
best_solution = self.cities.copy()
|
||||||
while self.temperature > self.temperature_ok:
|
while self.temperature > self.temperature_ok:
|
||||||
@ -33,8 +32,4 @@ class SimulatedAnnealing:
|
|||||||
best_solution = current_solution
|
best_solution = current_solution
|
||||||
# Cool down
|
# Cool down
|
||||||
self.temperature *= self.cooling_rate
|
self.temperature *= self.cooling_rate
|
||||||
interration += 1
|
|
||||||
# Print every 1000 iterations
|
|
||||||
if interration % 1000 == 0:
|
|
||||||
print("Iteration", interration, "with distance", total_distance(current_solution))
|
|
||||||
return best_solution
|
return best_solution
|
||||||
@ -1,46 +0,0 @@
|
|||||||
import math, random
|
|
||||||
|
|
||||||
def distance(city1, city2):
|
|
||||||
return math.sqrt((city1[0] - city2[0]) ** 2 + (city1[1] - city2[1]) ** 2)
|
|
||||||
|
|
||||||
def total_distance(cities):
|
|
||||||
return sum([distance(cities[i - 1], cities[i]) for i in range(len(cities))])
|
|
||||||
|
|
||||||
class SimulatedAnnealing:
|
|
||||||
def __init__(self, cities, temperature=10000, cooling_rate=0.9999, temperature_ok=0.001):
|
|
||||||
self.cities = cities
|
|
||||||
self.temperature = temperature
|
|
||||||
self.cooling_rate = cooling_rate
|
|
||||||
self.temperature_ok = temperature_ok
|
|
||||||
self.distances = []
|
|
||||||
self.temperatures = []
|
|
||||||
|
|
||||||
def run(self):
|
|
||||||
interration = 0
|
|
||||||
current_solution = self.cities.copy()
|
|
||||||
best_solution = self.cities.copy()
|
|
||||||
while self.temperature > self.temperature_ok:
|
|
||||||
new_solution = current_solution.copy()
|
|
||||||
# Swap two cities in the route
|
|
||||||
i = random.randint(0, len(new_solution) - 1)
|
|
||||||
j = random.randint(0, len(new_solution) - 1)
|
|
||||||
new_solution[i], new_solution[j] = new_solution[j], new_solution[i]
|
|
||||||
# Calculate the acceptance probability
|
|
||||||
current_energy = total_distance(current_solution)
|
|
||||||
new_energy = total_distance(new_solution)
|
|
||||||
delta = new_energy - current_energy
|
|
||||||
|
|
||||||
if delta < 0 or random.random() < math.exp(-delta / self.temperature):
|
|
||||||
current_solution = new_solution
|
|
||||||
if total_distance(current_solution) < total_distance(best_solution):
|
|
||||||
best_solution = current_solution
|
|
||||||
|
|
||||||
if interration % 10 == 0:
|
|
||||||
self.distances.append(total_distance(current_solution))
|
|
||||||
# Cool down
|
|
||||||
self.temperature *= self.cooling_rate
|
|
||||||
interration += 1
|
|
||||||
# Print every 1000 iterations
|
|
||||||
if interration % 10 == 0:
|
|
||||||
print("Iteration", interration, "with distance", total_distance(current_solution))
|
|
||||||
return best_solution, self.distances
|
|
||||||
Loading…
x
Reference in New Issue
Block a user