예제 #1
0
def get_vertices_and_steps(G, deadline, searchers):
    """Extract information from the user provided graph and information on searchers
    For each time step, find which vertices each searcher is allowed to be"""

    start = ext.get_searchers_positions(searchers)
    # S_ and Tau
    S, m = ext.get_set_searchers(start)
    Tau = ext.get_set_time(deadline)
    # get vertices
    V, n = ext.get_set_vertices(G)

    # shortest path lengths
    spl = ext.get_length_short_paths(G)

    # find V^tau(t) = {v in V} --> possible v(t) in optimal solution
    vertices_t = {}
    # find V^tau(v) = {t in Tau} --> possible t(v) in optimal solution
    times_v = {}

    start_idx = ext.get_python_idx(start)

    for s in S:
        s_idx = ext.get_python_idx(s)
        # initial position
        vertices_t[s, 0] = [start[s_idx]]

        # starting at t = 1 (idx = 1), it begins to move
        for t in Tau:
            vertices_t[s, t] = []
            # find the nodes that are within t of distance (thus can be reached at t)
            for v in V:
                v_idx = ext.get_python_idx(v)
                dummy_var = spl[start_idx[s_idx]][v_idx]
                if dummy_var <= t:
                    vertices_t[s, t].append(v)

        # find times allowed for each vertex
        for v in V:
            times_v[s, v] = []
            if v == start[s_idx]:
                times_v[s, v] = [0]

            for t in Tau:
                if v in vertices_t[s, t]:
                    times_v[s, v].append(t)

        # find dummy goal vertex and T + 1
        v_g = ext.get_label_dummy_goal(V)
        t_g = ext.get_last_t(Tau)
        # append dummy goal
        vertices_t[s,
                   t_g] = [v_g]  # at T + 1, searcher is at dummy goal vertex
        times_v[s, v_g] = [
            t_g
        ]  # the only time allowed for the dummy goal vertex is T + 1

    return start, vertices_t, times_v
예제 #2
0
def test_get_time():

    deadline = 3
    T = ext.get_set_time(deadline)
    assert T == [1, 2, 3]

    T_idx = ext.get_idx_time(deadline)
    assert T_idx == [0, 1, 2]

    T_ext = ext.get_set_time_u_0(deadline)
    T_ext2 = ext.get_set_time_u_0(T)
    assert T_ext == [0, 1, 2, 3]
    assert T_ext2 == [0, 1, 2, 3]
예제 #3
0
def set_solver_parameters(m,
                          gamma,
                          horizon,
                          my_vars,
                          timeout=30 * 60,
                          pre_solve=-1):
    """ Define my objective function to be maximized """
    h = ext.get_set_time(horizon)
    beta = get_var(my_vars, 'beta')
    m.setObjective(quicksum((gamma**t) * beta[0, t] for t in h), GRB.MAXIMIZE)

    m.setParam('TimeLimit', timeout)
    m.setParam('Threads', 8)
    m.setParam('Presolve', pre_solve)
    m.setParam('OutputFlag', 0)
예제 #4
0
def add_capture_constraints(md, g, my_vars: dict, searchers: dict, vertices_t,
                            b0: list, M: list, deadline: int):
    """Define constraints about belief and capture events
    :param vertices_t:
    :param md:
    :param g:
    :param my_vars:
    :param searchers:
    :param b0
    :param deadline
    """

    # capture-related variables
    beta = get_var(my_vars, 'beta')
    alpha = get_var(my_vars, 'alpha')
    psi = get_var(my_vars, 'psi')

    false_neg, zeta = cm.check_false_negatives(searchers)

    # if false negative model, there will exist a delta
    if false_neg:
        delta = get_var(my_vars, 'delta')
        beta_s = get_var(my_vars, 'beta_s')
    else:
        delta = {}
        beta_s = {}

    # searchers position
    X = get_var(my_vars, 'x')

    # sets
    V = ext.get_set_vertices(g)[0]
    S, m = ext.get_set_searchers(searchers)

    Tau = ext.get_set_time(deadline)
    V_ext = ext.get_set_vertices_u_0(g)

    # initial belief (user input), t = 0 (Eq. 13)
    for i in V_ext:
        md.addConstr(beta[i, 0] == b0[i])

    for t in Tau:
        # this is a dictionary
        my_vertices = cm.get_current_vertices(t, vertices_t, S)
        for v in V:
            # v_idx = ext.get_python_idx(v)
            # take Markovian model into account (Eq. 14)
            # NOTE M matrix is accessed by python indexing
            md.addConstr(alpha[v,
                               t] == quicksum(M[u - 1][v - 1] * beta[u, t - 1]
                                              for u in V))

            # find searchers position that could capture the target while it is in v
            list_u_capture = cm.get_u_for_capture(searchers, V, v)
            if list_u_capture and my_vertices:
                if false_neg:
                    for s in S:
                        md.addConstr(
                            quicksum(
                                X[s, u, t]
                                for u in filter(lambda x: x in my_vertices[
                                    s], list_u_capture)) >= psi[s, v, t])
                        md.addConstr(
                            quicksum(
                                X[s, u, t]
                                for u in filter(lambda x: x in my_vertices[
                                    s], list_u_capture)) <= psi[s, v, t])

                else:
                    md.addConstr(
                        quicksum(
                            quicksum(X[s, u, t] for u in filter(
                                lambda x: x in my_vertices[s], list_u_capture))
                            for s in S) >= psi[v, t])
                    md.addConstr(
                        quicksum(
                            quicksum(X[s, u, t] for u in filter(
                                lambda x: x in my_vertices[s], list_u_capture))
                            for s in S) <= m * psi[v, t])

            if false_neg:
                for s in S:

                    # first searcher
                    if s == S[0]:
                        md.addConstr(beta_s[0, v, t] == alpha[v, t])

                    # Eq. (38)
                    md.addConstr(delta[s, v, t] <= 1 - psi[s, v, t])
                    # Eq. (39)
                    md.addConstr(delta[s, v, t] <= beta_s[s - 1, v, t])
                    # Eq. (40)
                    md.addConstr(
                        delta[s, v, t] >= beta_s[s - 1, v, t] - psi[s, v, t])

                    # Eq. (37)
                    md.addConstr(beta_s[s, v,
                                        t] == ((1 - zeta) * delta[s, v, t]) +
                                 (zeta * beta_s[s - 1, v, t]))

                # last searcher
                md.addConstr(beta[v, t] == beta_s[S[-1], v, t])

            else:
                # (15)
                md.addConstr(beta[v, t] <= 1 - psi[v, t])
                # (16)
                md.addConstr(beta[v, t] <= alpha[v, t])
                # (17)
                md.addConstr(beta[v, t] >= alpha[v, t] - psi[v, t])

        # probability of being intercepted == what is left
        md.addConstr(beta[0, t] == 1 - quicksum(beta[v, t] for v in V))
예제 #5
0
def add_target_variables(md, g, deadline: int, searchers=None):
    """Add variables related to the target and capture events:
    belief variable, B
    interception-related variables: belief vector composition, beta
    belief evolution, alpha
    capture event, zeta and psi
    """
    # TODO change this to allow for different zetas (and unit-test it)

    V = ext.get_set_vertices(g)[0]

    T_ext = ext.get_set_time_u_0(deadline)
    T = ext.get_set_time(deadline)

    V_ext = ext.get_set_vertices_u_0(g)

    var_for_test = {}
    list_beta_name = []
    list_alpha_name = []
    list_delta_name = []

    [beta, beta_s, alpha, psi, delta] = ext.init_dict_variables(5)

    if searchers is not None:
        false_neg, zeta = cm.check_false_negatives(searchers)
        S = ext.get_set_searchers(searchers)[0]
    else:
        false_neg = False
        S = None

    # alpha and psi: only exist from 1, 2.., T
    for t in T:
        for v in V:
            dummy_a_name = "[%d,%d]" % (v, t)
            alpha[v, t] = md.addVar(vtype="CONTINUOUS",
                                    lb=0.0,
                                    ub=1.0,
                                    name="alpha" + dummy_a_name)

            list_alpha_name.append(dummy_a_name)

            if false_neg:
                for s in S:
                    dummy_delta_name = "[%d,%d,%d]" % (s, v, t)
                    psi[s, v, t] = md.addVar(vtype="BINARY",
                                             name="psi" + dummy_delta_name)
                    delta[s, v, t] = md.addVar(vtype="CONTINUOUS",
                                               lb=0.0,
                                               ub=1.0,
                                               name="delta" + dummy_delta_name)

                    list_delta_name.append(dummy_delta_name)
            else:
                psi[v, t] = md.addVar(vtype="BINARY",
                                      name="psi" + dummy_a_name)

    for t in T_ext:
        for v in V_ext:
            dummy_b_name = "[%d,%d]" % (v, t)
            list_beta_name.append(dummy_b_name)

            beta[v, t] = md.addVar(vtype="CONTINUOUS",
                                   lb=0.0,
                                   ub=1.0,
                                   name="beta" + dummy_b_name)

            if false_neg:
                # include 0 for searcher s = 1, s-1 = 0
                for s_ in [0] + S:
                    dummy_bs_name = "[%d,%d,%d]" % (s_, v, t)
                    beta_s[s_, v, t] = md.addVar(vtype="CONTINUOUS",
                                                 lb=0.0,
                                                 ub=1.0,
                                                 name="beta_s" + dummy_bs_name)

    var_for_test.update({'beta': list_beta_name})
    var_for_test.update({'alpha': list_alpha_name})

    if false_neg:
        my_vars = {
            'beta': beta,
            'beta_s': beta_s,
            'alpha': alpha,
            'psi': psi,
            'delta': delta
        }
        var_for_test.update({'delta': list_delta_name})
    else:
        my_vars = {'beta': beta, 'alpha': alpha, 'psi': psi}

    return my_vars, var_for_test
예제 #6
0
def get_vertices_and_steps_distributed(G, deadline, searchers, temp_s_path):
    """Extract information from the user provided graph and information on searchers
       For each time step, find which vertices each searcher is allowed to be
       Since this is the distributed version, use info on temporary searchers path (temp_s_path)"""

    start = ext.get_searchers_positions(searchers)
    # S_ and Tau
    S, m = ext.get_set_searchers(start)
    Tau = ext.get_set_time(deadline)
    # get vertices
    V, n = ext.get_set_vertices(G)

    # shortest path lengths
    spl = ext.get_length_short_paths(G)

    # find V^tau(t) = {v in V} --> possible v(t) in optimal solution
    vertices_t = {}
    # find V^tau(v) = {t in Tau} --> possible t(v) in optimal solution
    times_v = {}

    for s in S:
        # initial position
        vertices_t[s, 0] = [temp_s_path[(s, 0)]]
        st_idx = ext.get_python_idx(vertices_t.get((s, 0))[0])

        # starting at t = 1 (idx = 1), it begins to move
        for t in Tau:
            vertices_t[s, t] = []

            if s == temp_s_path['current_searcher']:
                # if it's planning for this searcher, consider all possibilities
                # find the nodes that are within t of distance (thus can be reached at t)

                for v in V:
                    v_idx = ext.get_python_idx(v)
                    dummy_var = spl[st_idx][v_idx]
                    if dummy_var <= t:
                        vertices_t[s, t].append(v)
            else:

                # if is not the planning searcher, just use the info on the temporary path
                # either the start vertex of the pre-computed path
                v = temp_s_path[s, t]
                vertices_t[s, t].append(v)

        # find times allowed for each vertex
        for v in V:
            times_v[s, v] = []
            if v == vertices_t[s, 0][0]:
                times_v[s, v] = [0]

            for t in Tau:
                if v in vertices_t[s, t]:
                    times_v[s, v].append(t)

        # find dummy goal vertex and T + 1
        v_g = ext.get_label_dummy_goal(V)
        t_g = ext.get_last_t(Tau)
        # append dummy goal
        vertices_t[s,
                   t_g] = [v_g]  # at T + 1, searcher is at dummy goal vertex
        times_v[s, v_g] = [
            t_g
        ]  # the only time allowed for the dummy goal vertex is T + 1

    return start, vertices_t, times_v