Beispiel #1
0
def knapsack_bab_solve(weights, values, capacity):
    class KnapsackBabPS(BabPartialSolution):
        def __init__(self, decisions: Tuple[int, ...], current_weight: int, current_value: int):
            self.decisions = decisions
            self.current_weight = current_weight
            self.current_value = current_value
            self.n = len(decisions)
            self._pes = self.calc_pes_bound()
            self._opt = self.calc_opt_bound()

        # TODO: IMPLEMENTAR - relajar problema (resolver mochila continua para los objetos que quedan)
        def calc_opt_bound(self) -> Union[int, float]:
            #return self.current_value + sum(values[self.n:])  # AHORA ES DEMASIADO OPTIMISTA (asume que puede coger todo lo que queda)
            espacio_libre = capacity - self.current_weight
            valor_mochila = self.current_value

            for i in range(self.n, len(weights)):
                if weights[i] <= espacio_libre:
                    espacio_libre -= weights[i]
                    valor_mochila += values[i]
                else:
                    #romper el objeto
                    valor_mochila += (valor_mochila/weights[i])+values[i]#revisar linea
                    break
            return valor_mochila
        # TODO: IMPLEMENTAR - utilizar algoritmo voraz (visto en el tema de voraces)
        def calc_pes_bound(self) -> Union[int, float]:
            # return self.current_value  # AHORA ES DEMASIADO PESIMISTA (asume que no puede coger nada más de lo que queda)
            espacio_libre = capacity - self.current_weight
            valor_mochila = self.current_value

            for i in range(self.n, len(weights)):
                if weights[i] <= espacio_libre:
                    espacio_libre -= weights[i]
                    valor_mochila += values[i]

            return valor_mochila

        def is_solution(self) -> bool:
            return self.n == len(values)

        def get_solution(self) -> Solution:
            return self.current_value, self.current_weight, self.decisions

        def successors(self) -> Iterable["KnapsackBabPS"]:
            if self.n < len(values):
                if weights[self.n] <= capacity - self.current_weight:
                    yield KnapsackBabPS(self.decisions + (1,), self.current_weight + weights[self.n],
                                        self.current_value + values[self.n])
                yield KnapsackBabPS(self.decisions + (0,), self.current_weight, self.current_value)

    initial_decisions = ()
    initial_weight = 0
    initial_value = 0
    initial_ps = KnapsackBabPS(initial_decisions, initial_weight, initial_value)
    return BabSolver.solve_maximization(initial_ps)
Beispiel #2
0
def binpacking_solve(objects: List[int], capacity: int):
    class BinPackingBabPS(BabPartialSolution):
        def __init__(self, decisions: Tuple[int, ...],
                     container_weights: Tuple[int, ...]):
            self.decisions = decisions
            self.container_weights = container_weights
            self.n = len(decisions)
            self._opt = self.calc_opt_bound()
            self._pes = self.calc_pes_bound()

        # TODO: IMPLEMENTAR - Relaja el problema. Trata los objetos que quedan como si fueran un líquido
        def calc_opt_bound(self) -> Union[int, float]:
            nuevo = list(deepcopy(self.container_weights))
            #return len(self.container_weights)
            return liquid_binpacking(objects[self.n:], capacity,
                                     nuevo)  # AHORA ES DEMASIADO OPTIMISTA

        # TODO: IMPLEMENTAR - Algoritmo voraz. Completa la solución parcial actual con "En el primero en el que quepa"
        def calc_pes_bound(self) -> Union[int, float]:
            nuevo = list(deepcopy(self.container_weights))
            #return len(self.container_weights) + (len(objects) - self.n)
            return primero_que_quepa(objects[self.n:], capacity,
                                     nuevo)  #AHORA ES DEMASIADO PESIMISTA

        def is_solution(self) -> bool:
            return self.n == len(objects)

        def get_solution(self) -> Solution:
            return self.decisions

        def successors(self) -> Iterable["BinPackingBabPS"]:
            if self.n < len(objects):
                object_weight = objects[self.n]
                for num_container, container_weight in enumerate(
                        self.container_weights):
                    if container_weight >= object_weight:
                        list_cw = list(
                            self.container_weights)  # copia tupla a lista
                        list_cw[num_container] -= object_weight
                        yield BinPackingBabPS(
                            self.decisions + (num_container, ), tuple(list_cw))
                num_container = len(self.container_weights)
                yield BinPackingBabPS(
                    self.decisions + (num_container, ),
                    self.container_weights + (capacity - object_weight, ))

    initial_ps = BinPackingBabPS((), tuple([capacity]))
    return BabSolver.solve_minimization(initial_ps)
Beispiel #3
0
def binpacking_solve(objects: List[int], capacity: int):
    class BinPackingBabPS(BabPartialSolution):
        def __init__(self, decisions: Tuple[int, ...],
                     container_weights: Tuple[int, ...]):
            self.decisions = decisions
            self.container_weights = container_weights
            self.n = len(decisions)
            self._opt = self.calc_opt_bound()
            self._pes = self.calc_pes_bound()

        # TODO: IMPLEMENTAR - Relaja el problema. Trata los objetos que quedan como si fueran un líquido
        def calc_opt_bound(self) -> Union[int, float]:
            # return len(self.container_weights)  # AHORA ES DEMASIADO OPTIMISTA
            if self.n == 0:
                return sum(objects) / capacity

            if self.n == len(objects):
                return len(self.container_weights)

            # hueco disponible
            min_object = objects[-1]
            free = sum(capacity - w for w in self.container_weights
                       if capacity - w >= min_object)  # hueco libre

            #objetos que caben
            pending = objects[self.n:]
            max_cap = max(capacity - w for w in self.container_weights)
            fit = sum(w for w in pending if w <= max_cap)

            # los que ponemos en huecos
            in_free = min(fit, free)

            return len(self.container_weights) + ceil(
                (sum(pending) - in_free) / capacity)

        # TODO: IMPLEMENTAR - Algoritmo voraz. Completa la solución parcial actual con "En el primero en el que quepa"
        def calc_pes_bound(self) -> Union[int, float]:
            # return len(self.container_weights) + (len(objects) - self.n)  # AHORA ES DEMASIADO PESIMISTA

            n = self.n
            cw = self.container_weights

            for obj in range(self.n, len(objects[self.n:])):
                pbin = 0  # peso contenedor
                for cont in range(len(cw)):
                    if capacity - cw[cont] > objects[obj]:
                        cw[cont] += objects[
                            obj]  # meto el peso en el contenedor
                        break
                else:
                    pass

            return len(cw)

        def is_solution(self) -> bool:
            return self.n == len(objects)

        def get_solution(self) -> Solution:
            return self.decisions

        def successors(self) -> Iterable["BinPackingBabPS"]:
            if self.n < len(objects):
                object_weight = objects[self.n]
                for num_container, container_weight in enumerate(
                        self.container_weights):
                    if container_weight + object_weight <= capacity:
                        list_cw = list(
                            self.container_weights)  # copia tupla a lista
                        list_cw[num_container] += object_weight
                        yield BinPackingBabPS(
                            self.decisions + (num_container, ), tuple(list_cw))
                num_container = len(self.container_weights)
                yield BinPackingBabPS(
                    self.decisions + (num_container, ),
                    self.container_weights + (object_weight, ))

    initial_ps = BinPackingBabPS((), ())
    return BabSolver.solve_minimization(initial_ps)
Beispiel #4
0
def binpacking_solve(objects: List[int], capacity: int):
    class BinPackingBabPS(BabPartialSolution):
        def __init__(self, decisions: Tuple[int, ...],
                     container_weights: Tuple[int, ...]):
            self.decisions = decisions
            self.container_weights = container_weights
            self.n = len(decisions)
            self._opt = self.calc_opt_bound()
            self._pes = self.calc_pes_bound()

        # TODO: IMPLEMENTAR - Relaja el problema. Trata los objetos que quedan como si fueran un líquido
        def calc_opt_bound(self) -> Union[int, float]:
            # return len(self.container_weights)  # AHORA ES DEMASIADO OPTIMISTA
            # los objetos pendientes decrecientes: si es > que el tamaño del contenedor, los sumo y los guardo en los que no_caben.
            # --- si son <  que el tamaño del contenedor, los sumo y los guardo en los que caben. Puede que sobren, si es asi suma:
            # --- (resto que caben + no_caben/nr_contenedores)+nr_contenedores
            #
            # el espacio libre en los contenedores: si es < que el tamaño del objeto, el contenedor esta cerrado
            max_hueco = 0
            if len(self.container_weights) > 0:
                max_hueco = capacity - min(self.container_weights)

            suma_objs_caben = suma_objs_nocaben = 0
            #creamos las jarras
            for num_obj in range(self.n, len(objects)):
                if objects[num_obj] <= max_hueco:
                    suma_objs_caben += objects[num_obj]
                else:
                    suma_objs_nocaben += objects[num_obj]
            for peso_contenedor in self.container_weights:
                espacio_libre_contenedor = capacity - peso_contenedor  #espacio libre en cada contenedor
                if espacio_libre_contenedor >= objects[-1]:
                    suma_objs_caben -= min(
                        suma_objs_caben, espacio_libre_contenedor
                    )  # rellano el contenedor y modifico cuanto le queda

            return len(self.container_weights) + ceil(
                (suma_objs_caben + suma_objs_nocaben) / capacity)

        # TODO: IMPLEMENTAR - Algoritmo voraz. Completa la solución parcial actual con "En el primero en el que quepa"
        def calc_pes_bound(self) -> Union[int, float]:
            #return len(self.container_weights) + (len(objects) - self.n)  # AHORA ES DEMASIADO PESIMISTA
            containers_weights = list(self.container_weights[:]) + [0] * (
                len(objects) - self.n
            )  # Lista de contenedores sera igual a la longitud de la lista usar como java no con append

            for num_object in range(self.n, len(objects)):
                for num_container in range(len(containers_weights)):
                    if objects[num_object] <= containers_weights[num_container]:
                        containers_weights[num_container] -= objects[
                            num_object]
                        break
            return len(containers_weights)

        def is_solution(self) -> bool:
            return self.n == len(objects)

        def get_solution(self) -> Solution:
            return self.decisions

        def successors(self) -> Iterable["BinPackingBabPS"]:
            if self.n < len(objects):
                object_weight = objects[self.n]
                for num_container, container_weight in enumerate(
                        self.container_weights):
                    if container_weight + object_weight <= capacity:
                        list_cw = list(
                            self.container_weights)  # copia tupla a lista
                        list_cw[num_container] += object_weight
                        yield BinPackingBabPS(
                            self.decisions + (num_container, ), tuple(list_cw))
                num_container = len(self.container_weights)
                yield BinPackingBabPS(
                    self.decisions + (num_container, ),
                    self.container_weights + (object_weight, ))

    initial_ps = BinPackingBabPS((), ())
    return BabSolver.solve_minimization(initial_ps)
def binpacking_solve(objects: List[int], capacity: int):
    class BinPackingBabPS(BabPartialSolution):
        def __init__(self, decisions: Tuple[int, ...],
                     container_weights: Tuple[int, ...]):
            self.decisions = decisions
            self.container_weights = container_weights
            self.n = len(decisions)
            self._opt = self.calc_opt_bound()
            self._pes = self.calc_pes_bound()

        # TODO: IMPLEMENTAR - Relaja el problema. Trata los objetos que quedan como si fueran un líquido
        def calc_opt_bound(self) -> Union[int, float]:
            max_hueco = 0
            if len(self.container_weights) > 0:
                max_hueco = capacity - min(self.container_weights)
            suma_objs_caben = suma_objs_nocaben = 0
            for i in range(self.n, len(objects)):
                if objects[i] <= max_hueco:
                    suma_objs_caben += objects[i]
                else:
                    suma_objs_nocaben += objects[i]

            for p in self.container_weights:
                espacio_libre_contenedor = capacity - p
                if espacio_libre_contenedor >= objects[-1]:
                    suma_objs_caben -= min(suma_objs_caben,
                                           espacio_libre_contenedor)
            return len(self.container_weights) + ceil(
                (suma_objs_caben + suma_objs_nocaben) / capacity)

            # return len(self.container_weights)  # AHORA ES DEMASIADO OPTIMISTA

        # TODO: IMPLEMENTAR - Algoritmo voraz. Completa la solución parcial actual con "En el primero en el que quepa"
        def calc_pes_bound(self) -> Union[int, float]:
            container_weigths = list(
                self.container_weights[:]) + [0] * (len(objects) - self.n)
            for i in range(self.n, len(objects)):
                for j, size in enumerate(container_weigths):
                    if container_weigths[j] + objects[i] <= capacity:
                        container_weigths[j] += objects[i]
                        break
            return len(container_weigths)
            #return len(self.container_weights) + (len(objects) - self.n)  # AHORA ES DEMASIADO PESIMISTA

        def is_solution(self) -> bool:
            return self.n == len(objects)

        def get_solution(self) -> Solution:
            return self.decisions

        def successors(self) -> Iterable["BinPackingBabPS"]:
            if self.n < len(objects):
                object_weight = objects[self.n]
                for num_container, container_weight in enumerate(
                        self.container_weights):
                    if container_weight + object_weight <= capacity:
                        list_cw = list(
                            self.container_weights)  # copia tupla a lista
                        list_cw[num_container] += object_weight
                        yield BinPackingBabPS(
                            self.decisions + (num_container, ), tuple(list_cw))
                num_container = len(self.container_weights)
                yield BinPackingBabPS(
                    self.decisions + (num_container, ),
                    self.container_weights + (object_weight, ))

    initial_ps = BinPackingBabPS((), ())
    return BabSolver.solve_minimization(initial_ps)
def knapsack_bab_solve(weights, values, capacity):
    class KnapsackBabPS(BabPartialSolution):
        def __init__(self, decisions: Tuple[int, ...], current_weight: int,
                     current_value: int):
            self.decisions = decisions
            self.current_weight = current_weight
            self.current_value = current_value
            self.n = len(decisions)
            self._pes = self.calc_pes_bound()
            self._opt = self.calc_opt_bound()

        # TODO: IMPLEMENTAR - relajar problema (resolver mochila continua para los objetos que quedan)
        def calc_opt_bound(self) -> Union[int, float]:
            # Guardamos el espacio libre y su valor
            freeSpace = capacity - self.current_weight
            value = self.current_value

            # Metemos objetos mientras quepan
            for obj in range(self.n, len(weights)):
                if weights[obj] <= freeSpace:
                    freeSpace -= weights[obj]
                    value += values[obj]
                else:
                    value += (values[obj] / weights[obj]) * freeSpace
                    break

            return value

        # TODO: IMPLEMENTAR - utilizar algoritmo voraz (visto en el tema de voraces)
        def calc_pes_bound(self) -> Union[int, float]:
            # Guardamos el espacio libre y su valor
            freeSpace = capacity - self.current_weight
            value = self.current_value

            # Metemos objetos mientras quepan
            for obj in range(self.n, len(weights)):
                if weights[obj] <= freeSpace:
                    freeSpace -= weights[obj]
                    value += values[obj]

            return value

        def is_solution(self) -> bool:
            return self.n == len(values)

        def get_solution(self) -> Solution:
            return self.current_value, self.current_weight, self.decisions

        def successors(self) -> Iterable["KnapsackBabPS"]:
            if self.n < len(values):
                if weights[self.n] <= capacity - self.current_weight:
                    yield KnapsackBabPS(self.decisions + (1, ),
                                        self.current_weight + weights[self.n],
                                        self.current_value + values[self.n])
                yield KnapsackBabPS(self.decisions + (0, ),
                                    self.current_weight, self.current_value)

    initial_decisions = ()
    initial_weight = 0
    initial_value = 0
    initial_ps = KnapsackBabPS(initial_decisions, initial_weight,
                               initial_value)
    return BabSolver.solve_maximization(initial_ps)