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)
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)