def binpacking(weights, capacity): class BinpackinPS(PartialSolutionWithOptimization): def __init__(self, solution, contenedores: List[int]): self.contenedores = contenedores self.solution = solution self.n = len(solution) def successors(self) -> Iterable["PartialSolutionWithOptimization"]: if self.n < len(weights): for i, weight in enumerate(self.contenedores): if weight >= weights[self.n]: copia = deepcopy(self.contenedores) copia[i] -= weights[self.n] yield BinpackinPS(self.solution + (i, ), copia) copia = deepcopy(self.contenedores) copia.append(capacity - weights[self.n]) yield BinpackinPS(self.solution + (len(self.contenedores), ), copia) def f(self) -> Union[int, float]: return len(self.contenedores) def state(self) -> State: return self.n, tuple(self.contenedores) def is_solution(self) -> bool: return self.n == len(weights) def get_solution(self) -> Solution: return self.solution initial_ps = BinpackinPS((), []) return BacktrackingOptSolver.solve(initial_ps)
def knapsack_solve(weights, values, capacity): class KnapsackPS(PartialSolutionWithOptimization): def __init__(self, decisions: Tuple[int, ...], value: int, weight: int): # IMPLEMENTAR: Añade los parámetros que tú consideres self.decisions = decisions self.weight = weight self.value = value self.n = len(decisions) def is_solution(self) -> bool: # IMPLEMENTAR return self.n == len(weights) def get_solution(self) -> Solution: # IMPLEMENTAR return self.decisions def successors(self) -> Iterable["KnapsackPS"]:# IMPLEMENTAR if self.n < len(weights): if ...: yield KnapsackPS(self.decisions + (1,), self.value + values[self.n], self.weight + weights[self.n]) yield KnapsackPS(self.decisions + (0,), self.value, self.weight) def state(self) -> State: # IMPLEMENTAR return self.n, self.weight def f(self) -> Union[int, float]: # IMPLEMENTAR return -self.value initialPS = KnapsackPS( (), 0, 0) # IMPLEMENTAR: Añade los parámetros que tú consideres return BacktrackingOptSolver.solve(initialPS)
def coin_change_solver(coins: Tuple[int, ...], quantity: int) -> Solution: class CoinChangePS(PartialSolutionWithOptimization): def __init__(self, pending, solution=()): self.pending = pending self.solution = solution self.n = len(solution) def is_solution(self) -> bool: return self.n == len(coins) and self.pending == 0 def get_solution(self) -> Solution: return self.solution def successors(self) -> Iterable["PartialSolutionWithOptimization"]: if self.n >= len(coins): return [] for suc in range(self.pending//coins[self.n]+1): yield CoinChangePS(self.pending-suc*coins[self.n], self.solution+(suc,)) def state(self) -> State: return self.n, self.pending def f(self) -> Union[int, float]: return sum(self.solution) initial_ps = CoinChangePS(quantity) return BacktrackingOptSolver.solve(initial_ps)
def coin_solver(coins, quantity): class CoinChangePS(PartialSolutionWithOptimization): def __init__(self, solution, quantity): self.solution = solution self.n = len(self.solution) self.quantity = quantity def is_solution(self) -> bool: return self.n == len(coins) and self.quantity == 0 def get_solution(self) -> Solution: return self.solution def successors(self) -> Iterable["PartialSolutionWithOptimization"]: if self.n < len(coins): for decision in range(self.quantity // coins[self.n] + 1): yield CoinChangePS( self.solution + (decision, ), self.quantity - coins[self.n] * decision) def state(self) -> State: return self.quantity, self.n def f(self): return sum(self.solution) initialPS = CoinChangePS((), quantity) return BacktrackingOptSolver.solve(initialPS)
def knapsack_solve(weights, values, capacity): class KnapsackPS(PartialSolutionWithOptimization): def __init__(self, solution, weight, value, index): self.solution = solution self.weight = weight self.value = value self.index = index def is_solution(self) -> bool: return self.index == len(values) def get_solution(self) -> Solution: return self.value, self.weight, self.solution def successors(self) -> Iterable["KnapsackPS"]: if not self.is_solution(): if (self.weight + weights[self.index]) <= capacity: yield KnapsackPS(self.solution + (self.index, ), self.weight + weights[self.index], self.value + values[self.index], self.index + 1) yield KnapsackPS(self.solution, self.weight, self.value, self.index + 1) def state(self) -> State: # IMPLEMENTAR # return self # No utilzar return self.index, self.weight def f(self) -> Union[int, float]: # IMPLEMENTAR return -self.value initialPS = KnapsackPS( (), 0, 0, 0) # IMPLEMENTAR: Añade los parámetros que tú consideres return BacktrackingOptSolver.solve(initialPS)
def bricker_opt_solve(level): class BrikerOpt_PS(PartialSolutionWithOptimization): def __init__(self, block: Block, decisions: Tuple[Move, ...]): self.block = block self.decisions = decisions def is_solution(self) -> bool: return self.block.is_standing_at_pos(level.get_targetpos()) def get_solution(self) -> Solution: return self.decisions def successors(self) -> Iterable["BrikerVC_PS"]: for movement in self.block.valid_moves(level.is_valid): print(self.decisions) yield BrikerOpt_PS(self.block.move(movement), self.decisions + (movement, )) def state(self) -> State: return self.block def f(self) -> Union[int, float]: return len(self.decisions) # TODO: crea initial_ps y llama a BacktrackingOptSolver.solve initial_ps = BrikerOpt_PS( Block(level.get_startpos(), level.get_startpos()), ()) return BacktrackingOptSolver.solve(initial_ps)
def knapsack_solve(weights, values, capacity): class KnapsackPS(PartialSolutionWithOptimization): def __init__(self, solution=(), suma_pesos=0, suma_valores=0): # IMPLEMENTAR: Añade los parámetros que tú consideres self.solution = solution self.n = len(solution) self.suma_pesos = suma_pesos self.suma_valores = suma_valores def is_solution(self) -> bool: # IMPLEMENTAR return self.n == len(values) and self.suma_pesos <= capacity def get_solution(self) -> Solution: # IMPLEMENTAR return self.solution def successors(self) -> Iterable["KnapsackPS"]: # IMPLEMENTAR if self.n >= len(values): return [] yield KnapsackPS(self.solution + (0,), self.suma_pesos, self.suma_valores) if self.suma_pesos + weights[self.n] <= capacity: yield KnapsackPS(self.solution + (1,), self.suma_pesos + weights[self.n], self.suma_valores + values[self.n]) def state(self) -> State: # IMPLEMENTAR return self.n, self.suma_pesos def f(self) -> Union[int, float]: # IMPLEMENTAR return -self.suma_valores initialPS = KnapsackPS() # IMPLEMENTAR: Añade los parámetros que tú consideres return BacktrackingOptSolver.solve(initialPS)
def numeros_solver2(P, T): class NumerosPS(BacktrackingOptSolver): def __init__(self, ds, pending): """ :param ds: decisiones tomadas :param pending: se resta del parametro a medida que se elije un yield del successors """ self.ds = ds self.n = len(ds) self.pending = pending def is_solution(self): return self.n == len(P) and self.pending == 0 def get_solution(self): return self.ds def state(self): return self.n, self.pending # lo que dice la f def f(self): sum = 0 for nr in self.ds: # if nr != 0: no es necesario sum += 1 return sum def successors(self): if self.n < len(P): # for nr in P: si se usa el for hay que usar range porque siempre se llama al mismo numero al entrar nr = P[self.n] yield NumerosPS(self.ds + (0, ), self.pending) # OJO: se resta del numero T cuando hay que sumar, es decir, usar el 1 yield NumerosPS(self.ds + (1, ), self.pending - nr) # OJO: se suma del numero T cuando hay que restar, es decir, usar el -1 yield NumerosPS(self.ds + (-1, ), self.pending + nr) initial_ps = NumerosPS((), T) return BacktrackingOptSolver.solve(initial_ps)
def numeros_solver(P, T): class NumerosPS(BacktrackingOptSolver): def __init__(self, ds, suma_local): """ :param ds: decisiones tomadas :param suma_local: se suma al parametro a medida que se elije un yield del successors """ self.ds = ds self.n = len(ds) self.suma_local = suma_local def is_solution(self): return self.n == len(P) and self.suma_local == T def get_solution(self): return self.ds def state(self): return self.n, self.suma_local # lo que dice la f def f(self): sum = 0 for nr in self.ds: if nr != 0: sum += 1 return sum def successors(self): if self.n < len(P): # for nr in P: si se usa el for hay que usar range porque siempre se llama al mismo numero al entrar nr = P[self.n] yield NumerosPS(self.ds + (0, ), self.suma_local) yield NumerosPS(self.ds + (1, ), self.suma_local + nr) yield NumerosPS(self.ds + (-1, ), self.suma_local - nr) initial_ps = NumerosPS((), 0) return BacktrackingOptSolver.solve(initial_ps)
def vallado_solver(L, C, P, M): """ Funcion que devuelve el coste minimo de vallas Parameters: L (list): longitud vallas C (list): cantidad vallas disponibles P (list): precio por valla M (int): longitud de la valla a comprobar """ class ValladoPs(PartialSolutionWithOptimization): def __init__(self, ds, longitud_local): self.ds = ds self.n = len(ds) self.longitud_local = longitud_local def is_solution(self): return self.n == len(L) and self.longitud_local == 0 def get_solution(self): return self.ds def state(self): return self.n, self.longitud_local def f(self): sum = 0 for i in range(len(self.ds)): sum += P[i] * self.ds[i] return sum def successors(self): if self.n < len(L): for c in range(0, min(C[self.n], self.longitud_local // L[self.n]) + 1): yield ValladoPs(self.ds + (c,), self.longitud_local - (L[self.n] * c)) initial_ps = ValladoPs((), M) return BacktrackingOptSolver.solve(initial_ps)
def knapsack_solve(weights, values, capacity): class KnapsackPS(PartialSolutionWithOptimization): def __init__(self, pending, solution ): # IMPLEMENTAR: Añade los parámetros que tú consideres self.pending = pending self.n = len(solution) self.solution = solution pass def is_solution(self) -> bool: # IMPLEMENTAR return len(self.solution) == len(weights) def get_solution(self) -> Solution: # IMPLEMENTAR return self.solution def successors(self) -> Iterable["KnapsackPS"]: # IMPLEMENTAR if self.n < len(values): if weights[self.n] <= self.pending: yield KnapsackPS(self.pending - weights[self.n], self.solution + (1, )) yield KnapsackPS(self.pending, self.solution + (0, )) def state(self) -> State: # IMPLEMENTAR # return len(self.solution), sum(self.solution[i] * weights[i] for i in range(len(self.solution)) ) return len(self.solution), self.pending def f(self) -> Union[int, float]: # IMPLEMENTAR # sum = 0 # for s in range(len(self.solution)): # sum += self.solution[s] * values[s] # return -sum return -sum(self.solution[i] * values[i] for i in range(len(self.solution))) initialPS = KnapsackPS( capacity, ()) # IMPLEMENTAR: Añade los parámetros que tú consideres return BacktrackingOptSolver.solve(initialPS)
def knapsack_solve(weights, values, capacity): class KnapsackPS(PartialSolutionWithOptimization): def __init__(self, solution, weights, values, capacity ): # IMPLEMENTAR: Añade los parámetros que tú consideres self.solution = solution self.n = len(solution) self.weights = weights self.values = values self.capacity = capacity def is_solution(self) -> bool: # IMPLEMENTAR return self.n == len(weights) def get_solution(self) -> Solution: # IMPLEMENTAR return self.solution def successors(self) -> Iterable["KnapsackPS"]: # IMPLEMENTAR if self.n < len(weights): yield KnapsackPS(self.solution + (0, ), weights, values, self.capacity) if self.capacity >= weights[self.n]: yield KnapsackPS(self.solution + (1, ), weights, values, self.capacity - weights[self.n]) def state(self) -> State: # IMPLEMENTAR return self.n, self.capacity def f(self) -> Union[int, float]: # IMPLEMENTAR return -sum(decision * values[i] for i, decision in enumerate(self.solution)) initialPS = KnapsackPS( (), weights, values, capacity) # IMPLEMENTAR: Añade los parámetros que tú consideres return BacktrackingOptSolver.solve(initialPS)
def partido_solver(M, K, VS, VN, C): class PartidoPS(PartialSolutionWithOptimization): def __init__(self, ds, m): self.ds = ds self.n = len(ds) self.m = m def is_solution(self) -> bool: return self.n == K and self.m == 0 def get_solution(self) -> Solution: return self.ds def f(self) -> Union[int, float]: suma = 0 for i in range(self.n): if self.ds[i] == 0: suma += VN[i] elif self.ds[i] == 1: suma += VS[i] return suma def state(self) -> State: return self.n, self.m def successors(self) -> Iterable["PartialSolutionWithOptimization"]: if self.n < K: coste = C[self.n] # decidir si voy o no if coste <= self.m: yield PartidoPS(self.ds + (1, ), self.m - coste) yield PartidoPS(self.ds + (0, ), self.m) initial_ps = PartidoPS((), M) return BacktrackingOptSolver.solve(initial_ps)