예제 #1
0
def main():
    parser = argparse.ArgumentParser(
        description=('Syntetic route generator'),
        formatter_class=argparse.ArgumentDefaultsHelpFormatter)

    parser.add_argument('--progressbar', action='store_true')
    parser.add_argument('--verbose', '-v', action='count', default=0)

    parser.add_argument('network')
    parser.add_argument('meta')
    parser.add_argument('all_trace_out', metavar='all-trace-out')
    parser.add_argument('syntetic_out', metavar='syntetic-out')
    parser.add_argument('--trace-count',
                        '-tc',
                        type=int,
                        dest='trace_count',
                        default=5000)
    parser.add_argument('--random-sample',
                        dest='random_sample',
                        action='store_true')

    parser.add_argument('--closeness-error',
                        '-ce',
                        type=float,
                        dest='closeness_error',
                        default=0.0)

    parser.add_argument('--core-limit-percentile',
                        '-cl',
                        type=int,
                        dest='core_limit',
                        default=0)

    parser.add_argument('--toggle-node-error-mode', action='store_true')

    arguments = parser.parse_args()

    arguments.verbose = min(len(helpers.LEVELS) - 1, arguments.verbose)
    logging.getLogger('compnet').setLevel(helpers.LEVELS[arguments.verbose])

    show_progress = arguments.progressbar

    g = helpers.load_network(arguments.network)
    g = g.simplify()

    meta = helpers.load_from_json(arguments.meta)

    if arguments.random_sample:
        random.shuffle(meta)

    meta = meta[:arguments.trace_count]

    N = g.vcount()

    cl = sorted([x['closeness'] for x in g.vs], reverse=True)
    logger.info('Min closeness: %s' % np.min(cl))
    logger.info('Max closeness: %s' % np.max(cl))
    logger.info('Mean closenss: %s' % np.mean(cl))
    logger.info('10%% closeness: %s' % np.percentile(cl, 10))
    logger.info('90%% closeness: %s' % np.percentile(cl, 90))

    logger.info('Core limit: [r]%d%%[/]' % arguments.core_limit)
    change_probability = 100 * arguments.closeness_error
    logger.info('Change probability: [r]%6.2f%%[/]' % change_probability)

    core_limit = np.percentile(cl, arguments.core_limit)
    logger.info('Core limit in closeness: [bb]%f[/]' % core_limit)

    if arguments.toggle_node_error_mode:
        logger.info('[r]Node error mode[/]')
        msg = (
            "If given node's closeness >= core_limit then the new ",
            "closeness in this node is ",
            #"rand(closeness_error ... old closeness)"
            "OLD_CLOSENSS * +/- closeness_error%")
        logger.info(''.join(msg))
        logger.info('Minimum node closeness: [g]%f[/]' %
                    arguments.closeness_error)
        for n in g.vs:
            if n['closeness'] < core_limit:
                continue
            # sign = -1 if random.uniform(-1, 1) < 0 else 1
            # n['closeness'] = n['closeness'] * (1 + sign * arguments.closeness_error)

            new_closeness = random.uniform(arguments.closeness_error,
                                           n['closeness'])
            n['closeness'] = new_closeness

    g_labeled = vft.label_graph_edges(g, vfmode=vft.CLOSENESS)
    peer_edge_count = len([x for x in g_labeled.es if x['dir'] == LinkDir.P])
    logger.info('Peer edge count: %d' % peer_edge_count)

    changed_edges = []

    if not arguments.toggle_node_error_mode:
        msg = ("If the closeness values of the endpoints in given edge is ",
               "larger than the core_limit and ",
               "random(0,1) < closeness_error then change the direction ",
               "for this edge")
        logger.info(''.join(msg))

        changed_u = changed_d = 0
        changed_edges = []
        changed_edgess = []
        for edge in g_labeled.es:
            s, t = edge.source, edge.target
            s_cl = g_labeled.vs[s]['closeness']
            t_cl = g_labeled.vs[t]['closeness']

            if (s_cl < core_limit or t_cl < core_limit): continue
            if random.uniform(0, 1) > arguments.closeness_error: continue
            # if abs(s_cl - t_cl) / min(s_cl, t_cl) > 0.02: continue

            new_edge_dir = LinkDir.U if random.uniform(0,
                                                       1) > 0.5 else LinkDir.D

            if new_edge_dir != edge['dir']:
                if edge['dir'] == LinkDir.U:
                    changed_u += 1
                else:
                    changed_d += 1

                edge['dir'] = new_edge_dir
                changed_edges.append(edge)
                changed_edgess.append((edge.source, edge.target))

            # if edge['dir'] == LinkDir.U:
            #     changed_u += 1
            #     changed_edgess.append((edge.source, edge.target))
            #     edge['dir'] = LinkDir.D
            #     changed_edges.append(edge)
            # elif edge['dir'] == LinkDir.D:
            #     changed_d += 1
            #     changed_edgess.append((edge.source, edge.target))
            #     edge['dir'] = LinkDir.U
            #     changed_edges.append(edge)
        logger.info('E count: %d' % g_labeled.ecount())
        logger.info('Changed U: %d' % changed_u)
        logger.info('Changed D: %d' % changed_d)
        logger.info('Changed: %d' % (changed_d + changed_u))

    changed_e = [(g_labeled.vs[e.source]['name'],
                  g_labeled.vs[e.target]['name']) for e in changed_edges]
    changed_e = changed_e + [(x[1], x[0]) for x in changed_e]

    changed_e = set(changed_e)

    vf_g_closeness = vft.convert_to_vf(g,
                                       vfmode=vft.CLOSENESS,
                                       labeled_graph=g_labeled)

    # e_colors = []
    # for e in vf_g_closeness.es:
    #     if e.source < N and e.target < N: col = 'grey'
    #     elif e.source < N and e.target >= N: col = 'blue'
    #     elif e.source >= N and e.target >= N: col = 'red'
    #     else: col = 'cyan'
    #     e_colors.append(col)
    # igraph.plot(vf_g_closeness, "/tmp/closeness.pdf",
    #             vertex_label=vf_g_closeness.vs['name'],
    #             vertex_size=0.2,
    #             edge_color=e_colors)

    pairs = [(g.vs.find(x[helpers.TRACE][0]).index,
              g.vs.find(x[helpers.TRACE][-1]).index, tuple(x[helpers.TRACE]))
             for x in meta]

    # pairs = list(set(pairs))

    # random.shuffle(pairs)

    # visited = set()
    # pairs2 = []
    # for x in pairs:
    #     k = (x[0], x[1])
    #     if k in visited: continue
    #     visited.add(k)
    #     visited.add((k[1], k[0]))
    #     pairs2.append(x)

    # pairs = pairs2

    traces = [x[2] for x in pairs]

    stretches = []
    syntetic_traces = []
    sh_traces = []
    base_traces = []
    original_traces = []
    bad = 0

    progress = progressbar1.DummyProgressBar(end=10, width=15)
    if show_progress:
        progress = progressbar1.AnimatedProgressBar(end=len(pairs), width=15)

    for s, t, trace_original in pairs:
        progress += 1
        progress.show_progress()

        trace_original_idx = [g.vs.find(x).index for x in trace_original]
        logger.debug('Original trace: %s -- %s -- %s',
                     [g.vs[x]['name'] for x in trace_original_idx],
                     vft.trace_to_string(g, trace_original_idx, vft.CLOSENESS),
                     [g.vs[x]['closeness'] for x in trace_original_idx])

        sh_routes = g.get_all_shortest_paths(s, t)
        sh_len = len(sh_routes[0])

        sh_routes_named = [[g.vs[y]['name'] for y in x] for x in sh_routes]
        sh_trace_name = random.choice(sh_routes_named)
        base_trace_name = random.choice(sh_routes_named)

        candidates = vf_g_closeness.get_all_shortest_paths(s + N, t + N)
        candidates = [vft.vf_route_converter(x, N) for x in candidates]
        # candidates = []

        if len(candidates) == 0:
            candidates = vft.get_shortest_vf_route(g_labeled,
                                                   s,
                                                   t,
                                                   mode='vf',
                                                   vf_g=vf_g_closeness,
                                                   _all=True,
                                                   vfmode=vft.CLOSENESS)

        if len(candidates) == 0:
            s_name, t_name = g.vs[s]['name'], g.vs[t]['name']
            logger.debug("!!!No syntetic route from %s to %s" %
                         (s_name, t_name))
            continue

        logger.debug('Candidates from %s to %s:' %
                     (g.vs[s]['name'], g.vs[t]['name']))

        for c in candidates:
            logger.debug('%s -- %s -- %s' %
                         ([g.vs[x]['name'] for x in c],
                          vft.trace_to_string(g_labeled, c, vft.PRELABELED),
                          [g.vs[x]['closeness'] for x in c]))

        chosen_one = random.choice(candidates)
        chosen_one_name = [g.vs[x]['name'] for x in chosen_one]

        # print chosen_one
        # print trace_original
        # pretty_plotter.pretty_plot(g, trace_original_idx,
        #                            chosen_one, changed_edgess,
        #                            spec_color=(0, 0, 0, 155))

        hop_stretch = len(chosen_one) - sh_len
        stretches.append(hop_stretch)

        trace_original_e = zip(trace_original, trace_original[1:])
        chosen_one_e = zip(chosen_one_name, chosen_one_name[1:])
        trace_affected = any([x in changed_e for x in trace_original_e])
        chosen_affected = any([x in changed_e for x in chosen_one_e])
        logger.debug('Trace affected: %s' % trace_affected)
        logger.debug('Chosen affected: %s' % chosen_affected)

        # if hop_stretch > 2:
        #     logger.debug('Base: %s' % trace_to_string(g_labeled, base_trace_name))
        #     logger.debug('SH: %s' % trace_to_string(g_labeled, sh_trace_name))
        #     logger.debug('Trace: %s' % trace_to_string(g_labeled, trace_original))
        #     logger.debug('Syntetic: %s' % trace_to_string(g_labeled, chosen_one_name))

        if trace_affected or chosen_affected or hop_stretch > 2:
            # pretty_plotter.pretty_plot_all(g, traces,
            #                                chosen_one, changed_edgess,
            #                                spec_color=(0, 0, 0, 255))
            bad += 1

        syntetic_traces.append(chosen_one_name)
        sh_traces.append(sh_trace_name)
        base_traces.append(base_trace_name)
        original_traces.append(trace_original)
        logger.debug('From %s to %s chosen one %s' %
                     (g.vs[s]['name'], g.vs[t]['name'], chosen_one_name))

    result = zip(base_traces, sh_traces, original_traces, syntetic_traces)
    helpers.save_to_json(arguments.all_trace_out, result)
    helpers.save_to_json(arguments.syntetic_out, syntetic_traces)

    print 'Bad: %d' % bad

    c = collections.Counter(stretches)
    trace_count = len(syntetic_traces)
    logger.info('Stretch dist:')
    for k in c:
        logger.info('\t%d: %5.2f%%[%d]' %
                    (k, 100 * c[k] / float(trace_count), c[k]))
    logger.info('Valid route count: %d' % trace_count)
    logger.info('Route count parameter: %d' % arguments.trace_count)
    logger.info('Generated valid pair count: %d' % len(pairs))
예제 #2
0
def purify(g, meta, flags, try_per_trace, show_progress=False):

    # generate valley-free graph
    if flags[FLAG_PRELABELED]:
        logger.info('Generate VF_G_PRE')
        vf_g_pre = vft.convert_to_vf(g, vfmode=vft.PRELABELED)
    else:
        logger.info('Skip prelabeled graph')

    if flags[FLAG_DEGREE]:
        logger.info('Generate VF_G_DEGREE')
        vf_g_degree = vft.convert_to_vf(g, vfmode=vft.DEGREE)
    else:
        logger.info('Skip degree graph')

    if flags[FLAG_CLOSENESS]:
        logger.info('Generate VF_G_CLOSENESS')
        vf_g_closeness = vft.convert_to_vf(g, vfmode=vft.CLOSENESS)
    else:
        logger.info('Skip closeness graph')

    # Randomize stretch dispersion
    stretches = [x[helpers.HOP_STRETCH] for x in meta]
    # a veletlen stretchek az eredeti stretchek veletlen, nem
    # visszateveses mintavetelezese. Mindez annyiszor, ahany
    # veletlen utat akarunk generalni minden valos trace vegpontja
    # kozott.
    stretch_list = [random.sample(stretches, len(stretches))
                    for x in xrange(0, try_per_trace)]
    # A kovetkezo ciklusban minden meta sorhoz rogton kiszamolunk
    # annyi random utat, amennyit parameterben megadtunk. Ehhez at kell
    # alakitani a stretch lista strukturat, hogy minden elem egy meta sorhoz
    # tartalmazza a random stretch ertekeket
    #
    # Pelda: elozo lepesnel kijott ez: [ [1,2,3,4], [2,4,1,3], [3,1,4,2] ]
    # vagyis elso lepesben a metaban tarolt tracek rendre 1,2,3,4 stretchet
    # kell felvegyenek, a masodikban 2,4,1,3 stb. A ciklusban viszont a meta
    # elso elemehez rogton ki akarjuk szamolni a veletlen stretchekhez tartozo
    # random utakat, vagyis [ [1,2,3], [2,4,1], [3,1,4], [4,3,2] ] formaban
    # van szukseg az ertekekre
    stretch_list = zip(*stretch_list)

    progress = progressbar1.DummyProgressBar(end=10, width=15)
    if show_progress:
        progress = progressbar1.AnimatedProgressBar(end=len(meta), width=15)

    for idx, record in enumerate(meta):
        progress += 1
        progress.show_progress()

        trace = vft.trace_in_vertex_id(g, [record[helpers.TRACE], ])
        if len(trace) != 1:
            print 'PROBLEM'
            print record
            continue
        trace = trace[0]

        if len(trace) == 1: continue

        sh_len = record[helpers.SH_LEN]
        s, t = trace[0], trace[-1]

        is_vf_prelabeled_l = []
        is_lp_prelabeled_hard_l = []
        is_lp_prelabeled_soft_l = []

        is_vf_degree_l = []
        is_lp_degree_hard_l = []
        is_lp_degree_soft_l = []

        is_vf_closeness_l = []
        is_lp_closeness_hard_l = []
        is_lp_closeness_soft_l = []

        stretch_dist = stretch_list[idx]
        real_stretch_dist = []
        for current_stretch in stretch_dist:
            random_length = sh_len + current_stretch
            random_path = helpers.random_route_walk(g, s, t, random_length)
            real_stretch_dist.append(len(random_path) - sh_len)
            if len(random_path) == 0:
                empty += 1

            if flags[FLAG_PRELABELED]:
                (is_vf_prelabeled,
                 is_lp_prelabeled_soft,
                 is_lp_prelabeled_hard) = vf_attributes(g,random_path,
                                                   vft.PRELABELED,
                                                   flags[FLAG_LP_SOFT],
                                                   flags[FLAG_LP_HARD],
                                                   vf_g_pre)
                is_vf_prelabeled_l.append(is_vf_prelabeled)
                is_lp_prelabeled_soft_l.append(is_lp_prelabeled_soft)
                is_lp_prelabeled_hard_l.append(is_lp_prelabeled_hard)

            if flags[FLAG_DEGREE]:
                (is_vf_degree,
                 is_lp_degree_soft,
                 is_lp_degree_hard) = vf_attributes(g, random_path,
                                                    vft.DEGREE,
                                                    flags[FLAG_LP_SOFT],
                                                    flags[FLAG_LP_HARD],
                                                    vf_g_degree)
                is_vf_degree_l.append(is_vf_degree)
                is_lp_degree_soft_l.append(is_lp_degree_soft)
                is_lp_degree_hard_l.append(is_lp_degree_hard)

            if flags[FLAG_CLOSENESS]:
                (is_vf_closeness,
                 is_lp_closeness_soft,
                 is_lp_closeness_hard) = vf_attributes(g, random_path,
                                                       vft.CLOSENESS,
                                                       flags[FLAG_LP_SOFT],
                                                       flags[FLAG_LP_HARD],
                                                       vf_g_closeness)
                is_vf_closeness_l.append(is_vf_closeness)
                is_lp_closeness_soft_l.append(is_lp_closeness_soft)
                is_lp_closeness_hard_l.append(is_lp_closeness_hard)

        result = {
            helpers.RANDOM_GULYAS_WALK_ROUTES_RQ_STRETCH: stretch_dist,
            helpers.RANDOM_GULYAS_WALK_ROUTES_STRETCH: real_stretch_dist,
            helpers.RANDOM_GULYAS_WALK_ROUTES_VF_PRELABELED: is_vf_prelabeled_l,
            helpers.RANDOM_GULYAS_WALK_ROUTES_VF_DEGREE: is_vf_degree_l,
            helpers.RANDOM_GULYAS_WALK_ROUTES_VF_CLOSENESS: is_vf_closeness_l,
            helpers.RANDOM_GULYAS_WALK_ROUTES_LP_SOFT_PRELABELED: is_lp_prelabeled_soft_l,
            helpers.RANDOM_GULYAS_WALK_ROUTES_LP_HARD_PRELABELED: is_lp_prelabeled_hard_l,
            helpers.RANDOM_GULYAS_WALK_ROUTES_LP_SOFT_DEGREE: is_lp_degree_soft_l,
            helpers.RANDOM_GULYAS_WALK_ROUTES_LP_HARD_DEGREE: is_lp_degree_hard_l,
            helpers.RANDOM_GULYAS_WALK_ROUTES_LP_SOFT_CLOSENESS: is_lp_closeness_soft_l,
            helpers.RANDOM_GULYAS_WALK_ROUTES_LP_HARD_CLOSENESS: is_lp_closeness_hard_l,
        }

        record.update(result)
예제 #3
0
    def test_soft_lp_check(self):
        self.sample_graph.add_vertices([
            'N8',
        ])
        self.prelabeled[8] = 0.5
        self.closenesses[8] = 0.5
        self.sample_graph.add_edges([['N5', 'N7'], ['N3', 'N7'], ['N8', 'N5'],
                                     ['N6', 'N8'], ['N7', 'N4']])

        lp_hard_routes = [['N0', 'N5', 'N6', 'N2'], ['N5', 'N6'],
                          ['N4', 'N6', 'N2'], ['N7', 'N4', 'N6', 'N3']]
        # Az egyetlen kulonbseg a soft es hard lp kozott
        # csak akkor johet elo, mikor U ellel kezdunk, es
        # a kov. hopnal lehet fel vagy le/peer elen menni
        # A soft ekkor mehet tovabb fel, a hard csak peer/le
        # elet valaszthat.
        lp_soft_routes = [['N0', 'N5', 'N4', 'N6', 'N2'],
                          ['N1', 'N5', 'N6', 'N8']]
        non_lp = [['N5', 'N4', 'N6'], ['N5', 'N6', 'N8'],
                  ['N5', 'N4', 'N6', 'N2']]

        vf_g = vft.convert_to_vf(self.sample_graph, vfmode=vft.CLOSENESS)

        for trace in lp_hard_routes:
            is_lp_hard = vft.is_local_preferenced(self.sample_graph,
                                                  trace,
                                                  vf_g=vf_g,
                                                  first_edge=False,
                                                  vfmode=vft.CLOSENESS)
            is_lp_soft = vft.is_local_preferenced(self.sample_graph,
                                                  trace,
                                                  vf_g=vf_g,
                                                  first_edge=True,
                                                  vfmode=vft.CLOSENESS)

            self.assertTrue(is_lp_hard)
            self.assertTrue(is_lp_soft)

        for trace in lp_soft_routes:
            is_lp_hard = vft.is_local_preferenced(self.sample_graph,
                                                  trace,
                                                  vf_g=vf_g,
                                                  first_edge=False,
                                                  vfmode=vft.CLOSENESS)
            is_lp_soft = vft.is_local_preferenced(self.sample_graph,
                                                  trace,
                                                  vf_g=vf_g,
                                                  first_edge=True,
                                                  vfmode=vft.CLOSENESS)

            self.assertFalse(is_lp_hard)
            self.assertTrue(is_lp_soft)

        for trace in non_lp:
            is_lp_hard = vft.is_local_preferenced(self.sample_graph,
                                                  trace,
                                                  vf_g=vf_g,
                                                  first_edge=False,
                                                  vfmode=vft.CLOSENESS)
            is_lp_soft = vft.is_local_preferenced(self.sample_graph,
                                                  trace,
                                                  vf_g=vf_g,
                                                  first_edge=True,
                                                  vfmode=vft.CLOSENESS)

            self.assertFalse(is_lp_hard)
            self.assertFalse(is_lp_soft)