Module ortools_utils.advanced_solving.local_search
Expand source code
import logging
from abc import ABC, abstractmethod
from typing import List
logger = logging.getLogger(__name__)
class LNS_Variables_Choice(ABC):
@abstractmethod
def variables_to_block(self) -> List:
"""
At each call, must return the next variables to *freeze*
"""
pass
@abstractmethod
def nb_remaining_iterations(self) -> int:
"""Returns the remaining number of loops to go"""
pass
class LNS_Variables_Choice_Across_One_Dim(LNS_Variables_Choice):
def __init__(self, variables_to_dim, window_size: int, step: int, nb_iterations: int = 1):
self.variables_to_dim = variables_to_dim
self.taille_fenetre = window_size
self.pas_decalage = step
self.nb_iterations = nb_iterations
liste_val_ma_dim = sorted(list(set(self.variables_to_dim.values())))
nb_val = len(liste_val_ma_dim)
self.mes_intervalles = []
curs = 0
while curs < nb_val:
val_init = liste_val_ma_dim[curs]
proch_valeur = val_init + step
proch_curs = None
for j in range(curs + 1, nb_val):
if liste_val_ma_dim[j] >= proch_valeur:
proch_curs = j
break
nouv_interv = []
borne_sup_stricte = val_init + window_size
fin_liste_atteinte = False
while True:
if curs == nb_val:
fin_liste_atteinte = True
break
elif liste_val_ma_dim[curs] < borne_sup_stricte:
nouv_interv.append(liste_val_ma_dim[curs])
curs += 1
else:
break
self.mes_intervalles.append(nouv_interv)
logger.info("New interval found: {}".format(nouv_interv))
if fin_liste_atteinte:
break
else:
curs = proch_curs
logger.info("Final interval list: {}".format(self.mes_intervalles))
nb_fenetres = len(self.mes_intervalles)
if nb_fenetres < 2:
logger.info("LNS is useless with these parameters")
self.iteration_courante = 0
self.idx_fenetre_courante = None
self.idx_problem = 0
self.nb_tot_pbs = nb_iterations * nb_fenetres
def variables_to_block(self):
fen = self.mes_intervalles[self.idx_fenetre_courante]
list_var_a_bloquer = [v for v in self.variables_to_dim if self.variables_to_dim[v] not in fen]
self.idx_fenetre_courante += 1
self.idx_problem += 1
if self.idx_fenetre_courante == len(self.mes_intervalles):
self.iteration_courante += 1
self.idx_fenetre_courante = 0
return list_var_a_bloquer
def nb_remaining_iterations(self):
return self.nb_tot_pbs - self.idx_problem
Classes
class LNS_Variables_Choice
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code
class LNS_Variables_Choice(ABC): @abstractmethod def variables_to_block(self) -> List: """ At each call, must return the next variables to *freeze* """ pass @abstractmethod def nb_remaining_iterations(self) -> int: """Returns the remaining number of loops to go""" pass
Ancestors
- abc.ABC
Subclasses
Methods
def nb_remaining_iterations(self) ‑> int
-
Returns the remaining number of loops to go
Expand source code
@abstractmethod def nb_remaining_iterations(self) -> int: """Returns the remaining number of loops to go""" pass
def variables_to_block(self) ‑> List[~T]
-
At each call, must return the next variables to freeze
Expand source code
@abstractmethod def variables_to_block(self) -> List: """ At each call, must return the next variables to *freeze* """ pass
class LNS_Variables_Choice_Across_One_Dim (variables_to_dim, window_size: int, step: int, nb_iterations: int = 1)
-
Helper class that provides a standard way to create an ABC using inheritance.
Expand source code
class LNS_Variables_Choice_Across_One_Dim(LNS_Variables_Choice): def __init__(self, variables_to_dim, window_size: int, step: int, nb_iterations: int = 1): self.variables_to_dim = variables_to_dim self.taille_fenetre = window_size self.pas_decalage = step self.nb_iterations = nb_iterations liste_val_ma_dim = sorted(list(set(self.variables_to_dim.values()))) nb_val = len(liste_val_ma_dim) self.mes_intervalles = [] curs = 0 while curs < nb_val: val_init = liste_val_ma_dim[curs] proch_valeur = val_init + step proch_curs = None for j in range(curs + 1, nb_val): if liste_val_ma_dim[j] >= proch_valeur: proch_curs = j break nouv_interv = [] borne_sup_stricte = val_init + window_size fin_liste_atteinte = False while True: if curs == nb_val: fin_liste_atteinte = True break elif liste_val_ma_dim[curs] < borne_sup_stricte: nouv_interv.append(liste_val_ma_dim[curs]) curs += 1 else: break self.mes_intervalles.append(nouv_interv) logger.info("New interval found: {}".format(nouv_interv)) if fin_liste_atteinte: break else: curs = proch_curs logger.info("Final interval list: {}".format(self.mes_intervalles)) nb_fenetres = len(self.mes_intervalles) if nb_fenetres < 2: logger.info("LNS is useless with these parameters") self.iteration_courante = 0 self.idx_fenetre_courante = None self.idx_problem = 0 self.nb_tot_pbs = nb_iterations * nb_fenetres def variables_to_block(self): fen = self.mes_intervalles[self.idx_fenetre_courante] list_var_a_bloquer = [v for v in self.variables_to_dim if self.variables_to_dim[v] not in fen] self.idx_fenetre_courante += 1 self.idx_problem += 1 if self.idx_fenetre_courante == len(self.mes_intervalles): self.iteration_courante += 1 self.idx_fenetre_courante = 0 return list_var_a_bloquer def nb_remaining_iterations(self): return self.nb_tot_pbs - self.idx_problem
Ancestors
- LNS_Variables_Choice
- abc.ABC
Inherited members