def simulated_annealing(espai_estats, funcio, temperatura=100, refredament=0.9):
estat_actual = espai_estats.estat_inicial()
while True:
successors = espai_estats.estats_successors(estat_actual)
successors_ordenats = sorted(successors, key=funcio)
if funcio(successors_ordenats[0]) <= funcio(estat_actual):
estat_actual = successors_ordenats[0]
else:
delta = funcio(successors_ordenats[0]) - funcio(estat_actual)
probabilitat = math.exp(-delta / temperatura)
if random.random() < probabilitat:
estat_actual = successors_ordenats[0]
temperatura *= refredament
if temperatura < 0.00001:
return estat_actual
solucio = hill_climbing(tsp)
plot_tsp(tsp, solucio)
Cost: 50976.93306917217
Cost: 51376.91701004807
...
Cost: 11354.397010378212
Cost: 11350.41254307539
Cost final: 11350.41254307539
inline (I)
def simulated_annealing(problema, temp=100000, refredament=0.9999, iteracions=10000):
estat = problema.inicial
cost = problema.funcio_avaluacio(estat)
while temp > 0.1:
i = random.randint(1, len(estat) - 1)
j = random.randint(1,len(estat) - 1)
while i == j:
j = random.randint(1, len(estat) - 1)
estat[i], estat[j] = estat[j], estat[i]
cost_nou = problema.funcio_avaluacio(estat)
...
inline (II) ...
delta = cost_nou - cost
if delta < 0 or math.exp(-delta / temp) > random.uniform(0, 1):
cost = cost_nou
print("Cost: ", cost)
else:
estat[i], estat[j] = estat[j], estat[i]
temp = temp * refredament
print("Cost final: ", cost)
print("Estat final: ", estat)
return estat

def genetic_algorithm(espai_estats, funcio, num_individus=100, num_iteracions=100):
poblacio = [espai_estats.estat_inicial() for _ in range(num_individus)]
for _ in range(num_iteracions):
seleccionats = sorted(poblacio, key=funcio)[:num_individus]
nova_poblacio = []
for i in range(num_individus):
pare = random.choice(seleccionats)
mare = random.choice(seleccionats)
fill = creuament(pare, mare)
if random.random() < 0.1:
fill = espai_estats.mutacio(fill)
poblacio.append(fill)
poblacio = nova_poblacio
return poblacio[0]
def creuament(pare, mare):
punt = random.randint(0, len(pare))
fill = pare[:punt] + mare[punt:]
return fill
def mutacio(individu):
punt = random.randint(0, len(individu))
nou_valor = random.randint(0, 100)
individu[punt] = nou_valor
return individu
def backtrack():
return _backtrack([], 0)
def _backtrack(estat, posicio):
if posicio==len_solucio and es_solucio(estat):
return estat
for i in range(len_solucio):
estat.append(i)
if es_valid(estat) == 0:
solu = _backtrack(estat, posicio + 1)
if solu is not None:
return solu
estat.pop()
return None
def backtrack():
estat = [-1]*len_solucio
variables = list(range(len_solucio))
return _backtrack(estat, variables)
def _backtrack(estat, variables):
if es_solucio(estat):
return estat
var = selecciona_variable(variables)
for i in ordena_valors(var):
estat[var] = i
if es_valid(estat) == 0:
variables.remove(var)
solu = _backtrack(estat, variables)
if solu is not None:
return solu
variables.append(var)
estat[var] = -1
def minims_conflictes(espai_estats, funcio, max_iteracions):
inicial = espai_estats.estat_inicial()
actual = inicial
for _ in range(max_iteracions):
if espai_estats.es_solucio(actual):
return actual
i = random.randint(0, len(actual.tauler) - 1)
act_conflicts = funcio(actual)
for j in range(len(actual.tauler)):
if j != i:
actual[i], actual[j] = actual[j], actual[i]
new_conflicts = funcio(actual)
if new_conflicts <= act_conflicts:
act_conflicts = new_conflicts
else:
actual[i], actual[j] = actual[j], actual[i]
return actual