def create_ilp_formulation_for_restricted_median(cfg):
    try:
        model = gurobipy.Model(cfg.name_model)

        logger.info("START CREATING MODEL.")
        dot_rs = model.addVars(
            {x
             for x, cond in cfg.allowable_telomers.items() if cond},
            vtype=gurobipy.GRB.BINARY)

        rs = define_matching_vars(model=model,
                                  edge_set=cfg.allowable_ancestral_edges,
                                  edge_conditions=cfg.connection_constrs,
                                  vertex_set=dot_rs,
                                  vertex_conditions=cfg.allowable_telomers,
                                  name="rs")

        tilde_bs, hat_bs = [], []
        for i in range(cfg.number_of_genomes):
            tilde_b, hat_b = di_dist_without_singletons(model=model,
                                                        rs=rs,
                                                        cfg=cfg,
                                                        ind=i)
            tilde_bs.append(tilde_b)
            hat_bs.append(hat_b)

        logger.info("CREATING BIG CONSTRAINT")
        model.addConstr(tilde_bs[0].sum('*') + tilde_bs[1].sum('*') -
                        dot_rs.sum('*') - hat_bs[0].sum('*') -
                        hat_bs[1].sum('*') == len(cfg.ind_ancestral_set) // 2 +
                        cfg.number_of_cycles + cfg.number_of_even_paths // 2)

        logger.info("CREATING OBJECTIVE FUNCTION.")
        model.setObjective(
            tilde_bs[2].sum('*') - 0.5 * dot_rs.sum('*') - hat_bs[2].sum('*'),
            gurobipy.GRB.MAXIMIZE)

        logger.info("FINISH CREATE MODEL.")
        model.params.logFile = cfg.log_file
        model.params.MIPFocus = 2
        model.params.timeLimit = cfg.time_limit
        model.optimize()

        logger.info("The number of cycles and paths is " +
                    str(int(model.objVal)))
        answer = get_param_of_solution_for_restricted_median(model=model,
                                                             cfg=cfg,
                                                             rs=rs,
                                                             dot_rs=dot_rs)
        return answer
    except gurobipy.GurobiError as e:
        logger.error(
            "Some error has been raised. Please, report to github bug tracker. \n Text exception: {0}"
            .format(e))
def create_ilp_formulation_for_halvings_without_singletons(cfg):
    try:
        model = gurobipy.Model(cfg.name_model)

        logger.info("START CREATING MODEL.")
        dot_rs = model.addVars(
            {
                x
                for x, cond in cfg.allowable_ancestral_telomers.items() if cond
            },
            vtype=gurobipy.GRB.BINARY)

        rs = define_matching_vars(
            model=model,
            edge_set=cfg.allowable_ancestral_edges,
            edge_conditions=cfg.connection_ancestral_constrs,
            vertex_set=dot_rs,
            vertex_conditions=cfg.allowable_ancestral_telomers,
            name="rs")

        tilde_b, hat_b = di_dist_without_singletons(model=model,
                                                    rs=rs,
                                                    cfg=cfg,
                                                    ind=0)
        tilde_a, hat_a = ddi_dist_without_singletons(model=model,
                                                     rs=rs,
                                                     cfg=cfg)

        logger.info("CREATING OBJECTIVE FUNCTION.")
        model.setObjective(
            tilde_b.sum('*') + tilde_a.sum('*') - 1.5 * dot_rs.sum('*') -
            hat_b.sum('*') - hat_a.sum('*'), gurobipy.GRB.MAXIMIZE)

        logger.info("FINISH CREATE MODEL.")
        model.params.logFile = cfg.log_file
        model.params.MIPFocus = 2
        model.params.timeLimit = cfg.time_limit
        model.optimize()

        logger.info("The number of cycles and paths is " +
                    str(int(model.objVal)))
        answer = get_param_of_solution_for_halving_problem(model=model,
                                                           cfg=cfg,
                                                           rs=rs,
                                                           dot_rs=dot_rs)
        return answer
    except gurobipy.GurobiError as e:
        logger.error(
            "Some error has been raised. Please, report to github bug tracker. \n Text exception: {0}"
            .format(e))
        return None