Beispiel #1
0
def _linear_relaxation(problem):
    bounds = perform_fbbt(
        problem,
        maxiter=10,
        timelimit=60,
    )

    bounds, monotonicity, convexity = \
        propagate_special_structure(problem, bounds)
    return LinearRelaxation(problem, bounds, monotonicity, convexity)
Beispiel #2
0
    def _perform_fbbt(self, run_id, problem, tree, node, maxiter=None):
        fbbt_start_time = current_time()
        logger.debug(run_id, 'Performing FBBT')

        objective_upper_bound = None
        if tree.upper_bound is not None:
            objective_upper_bound = tree.upper_bound

        fbbt_maxiter = self.fbbt_maxiter
        if maxiter is not None:
            fbbt_maxiter = maxiter
        branching_variable = None
        if not node.storage.is_root:
            branching_variable = node.storage.branching_variable
        bounds = perform_fbbt(
            problem,
            maxiter=fbbt_maxiter,
            timelimit=self.fbbt_timelimit,
            objective_upper_bound=objective_upper_bound,
            branching_variable=branching_variable,
        )

        self._bounds, self._monotonicity, self._convexity = \
            propagate_special_structure(problem, bounds)

        logger.debug(run_id, 'Set FBBT Bounds')
        cause_infeasibility = None
        for v in problem.variables:
            vv = problem.variable_view(v)
            new_bound = bounds[v]
            if new_bound is None:
                new_bound = Interval(None, None)

            new_lb = best_lower_bound(
                v.domain,
                new_bound.lower_bound,
                vv.lower_bound()
            )

            new_ub = best_upper_bound(
                v.domain,
                new_bound.upper_bound,
                vv.upper_bound()
            )

            if new_lb > new_ub:
                cause_infeasibility = v

        if cause_infeasibility is not None:
            logger.info(
                run_id, 'Bounds on variable {} cause infeasibility',
                cause_infeasibility.name
            )
        else:
            for v in problem.variables:
                vv = problem.variable_view(v)
                new_bound = bounds[v]

                if new_bound is None:
                    new_bound = Interval(None, None)

                new_lb = best_lower_bound(
                    v.domain,
                    new_bound.lower_bound,
                    vv.lower_bound()
                )

                new_ub = best_upper_bound(
                    v.domain,
                    new_bound.upper_bound,
                    vv.upper_bound()
                )

                if np.isinf(new_lb):
                    new_lb = -np.inf

                if np.isinf(new_ub):
                    new_ub = np.inf

                if np.abs(new_ub - new_lb) < mc.epsilon:
                    new_lb = new_ub

                logger.debug(run_id, '  {}: [{}, {}]', v.name, new_lb, new_ub)
                vv.set_lower_bound(new_lb)
                vv.set_upper_bound(new_ub)

        group_name = '_'.join([str(c) for c in node.coordinate])
        logger.tensor(run_id, group_name, 'lb', problem.lower_bounds)
        logger.tensor(run_id, group_name, 'ub', problem.upper_bounds)
        self._bac_telemetry.increment_fbbt_time(
            seconds_elapsed_since(fbbt_start_time)
        )