def main(): ''' main function ''' parser = argparse.ArgumentParser() parser.add_argument('type', help="total or limited") parser.add_argument('-l', '--limit', type=int, help="number to limit by for limited") parser.add_argument('-t', '--threshold', type=float, help="threshold value for limited (defualts to 0)") parser.add_argument('-r', '--random', type=float, help="use random test, takes in num nodes and edge probability as argument (creates new file in data folder)", nargs=2) parser.add_argument('-s', '--source', help="source node name") parser.add_argument('-i', '--input_file', help="input file location") parser.add_argument('-w', '--weighted', action='store_true', help="is the input weighted") parser.add_argument('-v', '--visualize', action='store_true', help="whether or not to visualize graph") parser.add_argument('-o', '--output', help="store visualization to output (requires ffmpeg) - paired with -v option") parser.add_argument('-g', '--graphviz', action='store_true', help="(optional) use graphviz to visualize (requires pygraphviz)") args = parser.parse_args() if args.random: args.input_file = random_test(args.random[0], args.random[1]) args.output = args.input_file.replace('.dat', '.mp4').replace('data', 'output') if not os.path.isfile(args.input_file) and not args.random: print("need to give valid input file") exit(1) g = graph.create_graph(args.input_file, args.weighted) iterations = [] if args.type == "limited": if not args.limit: print("need to give valid limit for 'limited' option") exit(1) if args.threshold: threshold = args.threshold else: threshold = 0 if args.source: iterations = infection.limited_infection(g, args.source, args.limit, threshold) else: iterations = infection.limited_infection(g, limit=args.limit, threshold=threshold) else: #arg.type == total or anything if args.source: iterations = infection.total_infection(g, args.source) else: iterations = infection.total_infection(g) if args.visualize: graph.animate(g, iterations, args.output, args.graphviz, args.weighted)
def infect(): """Run the specified infection algorithm on a given user graph.""" users = load_user_graph() if request.args.get('type') == 'total': try: user = users[int(request.args['user'])] except KeyError: raise BadRequest('Expected a valid user in param user.') except ValueError: raise BadRequest('User must be an integer.') infected = total_infection(user) return jsonify({'users': [user.id for user in infected]}) elif request.args.get('type') == 'limited': try: target = int(request.args['target']) except (KeyError, ValueError): raise BadRequest('Expected an integer target.') try: error = float(request.args['error']) / 100 except (KeyError, ValueError): raise BadRequest('Expected an float error.') if error < 0 or error > 1: raise BadRequest('Error must be between 0 and 100.') # Special case for target = n if target == len(users): return jsonify({'users': [user.id for user in users.values()]}) groups = limited_infection(users.values(), target, error) if groups is None: users = None else: users = [u.id for group in groups for u in group] return jsonify({'users': users}) raise BadRequest('Expected total or limited from query param type.')
def test_total_infection(self, infection): infection.load() infection.choose() states = infection.total_infection() # Assert everything infected at end assert functools.reduce(lambda acc, x: acc and x, [status for node, status in states[-1]])
def test_total_infection_disconnected(self): # A graph with no edges. graph = nx.Graph() nodes = [1, 2, 3, 4, 5] graph.add_nodes_from(nodes) # Infecting from any node should just infect itself. for i in nodes: infected = infection.total_infection(graph, i) self.assertItemsEqual([i], infected)
def test_total_infection_all_connected(self): # A graph where all nodes are connected. graph = nx.Graph() nodes = [1, 2, 3, 4, 5] graph.add_nodes_from(nodes) graph.add_edges_from([(1, 2), (2, 3), (3, 4), (4, 5)]) # Infecting from any node should infect the whole graph. for i in nodes: infected = infection.total_infection(graph, i) self.assertItemsEqual(nodes, infected)
def test_total_infection_with_cycle(self): # A graph with a cycle in it. There are no disconnected nodes. graph = nx.Graph() nodes = [1, 2, 3, 4, 5] graph.add_nodes_from(nodes) graph.add_edges_from([(1, 2), (2, 3), (3, 1), (4, 2), (4, 5)]) # Infecting from any node should infect the whole graph. for i in nodes: infected = infection.total_infection(graph, i) self.assertItemsEqual(nodes, infected)
def test_infection_size(self, infection): infection.load() infection.choose() infection.total_infection() assert infection._infection_size() == len(infection.nxgraph.nodes())
def test_total_infection(self): infection.infected = [] infection.to_be_infected = [] self.assertEqual(infection.total_infection(True), len(infection.user_base))
# -*- coding: utf-8 -*- import argparse import infection import networkx as nx import random if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--num_nodes', help='Number of nodes in the graph.', default=100) args = parser.parse_args() # Creates a fake random graph, and totally infects it from a random node. graph = infection.create_random_khan_graph(int(args.num_nodes)) infection_source = random.choice(graph.nodes()) infected = infection.total_infection(graph, infection_source) infection.display_infected_graph(graph, infected)
Infect the first component (1,2,3,4) and not the second (5,6) """ # infecting any of 1, 2, 3, or 4 should infect all four db = Database() # starting version is 0 for all users b/c I hardcoded it that way for testing for i in range(1, 5): assert(db.get_user(str(i)).version == 0) for i in range(5, 7): assert(db.get_user(str(i)).version == 0) u4 = db.get_user('4') # infect the four users with version # 2 total_infection(db, u4, 2, set()) for i in range(1, 5): assert(db.get_user(str(i)).version == 2) # and that users 5 and 6 are unaffected for i in range(5, 7): assert(db.get_user(str(i)).version == 0) """ Infect the second (5,6) without affecting the first (1,2,3,4) """ db = Database() u5 = db.get_user('5')
def test_total_infection(self): correct_num_affected_users = [51, 1, 10000, 101] for i, file_name in enumerate(self.test_file_list): affected_users = total_infection(file_name, 'id0000000000001', '1.17') self.assertEqual(affected_users, correct_num_affected_users[i])
def test_total_infection(circular_users): """This will test with a circular graph (0->1->2->0...).""" total_infection(circular_users[0], 2) for user in circular_users: assert user.version == 2