def test_limited_infection_caveman_graph(self): # A caveman graph has a bunch of cliques of the same size. # We can only approximate the limit by the size of the cliques. graph = nx.caveman_graph(10, 3) # 10 cliques of size 3 # 9 is multiple of 3, we can do match this limit precisely. infected = infection.limited_infection(graph, 9) self.assertEqual(9, len(infected)) # 10 is not a multiple of 3. We'll approximate with the next multiple of 3. infected = infection.limited_infection(graph, 10) self.assertEqual(12, len(infected))
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_limited_infection_disconnected(self): # A graph with no edges. Precise limit is always possible. graph = nx.Graph() nodes = range(1,10) graph.add_nodes_from(nodes) for i in nodes: infected = infection.limited_infection(graph, i) self.assertEqual(i, len(infected))
def test_limited_infection(monkeypatch): """Test that limited_infection properly uses subset sum output.""" users = [User(i, 1) for i in range(5)] users[0].connect(users[1]) users[1].connect(users[2]) users[3].connect(users[4]) # Override subset_sum_approx to just return the 0, 1, 2 group assert limited_infection(users, 3, .1, 2) == [users[0].infection] for user in users[:3]: assert user.version == 2 for user in users[3:]: assert user.version == 1
def test_limited_infection_percentage_10(self): correct_num_affected_users = [1000, 1000, 0, 0] for i, file_name in enumerate(self.test_file_list): affected_users = limited_infection(file_name, '1.34', percentage=0.1, amount=None, tolerance=0, userid=None) self.assertEqual(affected_users, correct_num_affected_users[i])
def test_limited_infection(self): infection.infected = [] infection.to_be_infected = [] self.assertEqual(infection.limited_infection(5), 2)
def test_limited_infection(self, infection): infection.load() infection.choose() states = infection.limited_infection(10, 3) assert infection._infection_size() == 10
# -*- coding: utf-8 -*- import argparse import infection import networkx as nx if __name__ == '__main__': parser = argparse.ArgumentParser() parser.add_argument('--num_nodes', help='Number of nodes in the graph.', default=100) parser.add_argument('--limit', help='Number of nodes in the graph.', default=50) args = parser.parse_args() graph = infection.create_random_khan_graph(int(args.num_nodes)) infected = infection.limited_infection(graph, int(args.limit)) infection.display_infected_graph(graph, infected)
def test_limited_infection_amount_2019_tolerance_1_percent(self): correct_num_affected_users = [2019, 2019, 0, 2000] for i, file_name in enumerate(self.test_file_list): affected_users = limited_infection(file_name, '1.34', percentage=None, amount=2019, tolerance=0.01, userid=None) self.assertEqual(affected_users, correct_num_affected_users[i])
def test_limited_infection_closest(self): infection.infected = [] infection.to_be_infected = [] infected_users = infection.limited_infection(6) self.assertTrue(infected_users == 2 or infected_users == 10)
def test_limited_infection_strict(self): infection.infected = [] infection.to_be_infected = [] self.assertEqual(infection.limited_infection(6,True), 0) self.assertEqual(infection.limited_infection(10,True), 10)
def test_limited_infection_fail(monkeypatch): """See what happens if we don't get a valid subset.""" monkeypatch.setattr('infection.subset_sum_approx', lambda *a: None) assert limited_infection([User(1)], 1, .1, 2) is None
number = sum(d[0] for d in data) / trials size = sum(d[1] for d in data) / trials print number, size #print data if __name__ == '__main__': size = 10 trials = 10 density = 3 import sys if len(sys.argv) > 1: size = int(sys.argv[1]) if len(sys.argv) > 2: trials = int(sys.argv[2]) #print "Random Model" #run_trials(lambda: create_random_users(size,density), trials) print print "User Model" run_trials(lambda: create_user_from_model(size), trials) import infection users = create_user_from_model(size) target = .1 * len(users) infected = infection.limited_infection(users, target) actual = sum(len(g) for g in infected) print "target:", target, "-> actual:", actual, " (", actual/float(target), ")"
assert(db.get_user('5').version == 15) assert(db.get_user('6').version == 15) """ Test limited_infection. Will infect at most the target amount. """ """ Exactly target can be infected. Only one combo of group sizes. target = 1 """ db = Database() limited_infection(db, target=1, new_ver=6) # user 7 and 8 are both in groups of size 1 # it's not deterministic which one is chosen because groups are stored in a # dictionary which has no order u7 = db.get_user('7') u8 = db.get_user('8') # only one of user 7 or 8 should have version 6 for i in range(1, 7): assert(db.get_user(str(i)).version == 0) assert((u7.version == 6 and u8.version == 0) or (u7.version == 0 and u8.version == 6))
def test_limited_infection_strict(self): infection.infected = [] infection.to_be_infected = [] self.assertEqual(infection.limited_infection(6, True), 0) self.assertEqual(infection.limited_infection(10, True), 10)