def main(): args = docopt(__doc__) # We will take many samples in an attempt to reduce number of keys to farm # This is the number of samples to take since the last improvement EXTRA_SAMPLES = 20 np = geometry.np #GREEN = 'g' #BLUE = 'b' GREEN = '#3BF256' # Actual faction text colors in the app BLUE = '#2ABBFF' #GREEN = (0.0 , 1.0 , 0.0 , 0.3) #BLUE = (0.0 , 0.0 , 1.0 , 0.3) COLOR = GREEN if args['-b']: COLOR = BLUE output_directory = '' if args['<output_directory>'] != None: output_directory = args['<output_directory>'] if output_directory[-1] != '/': output_directory += '/' output_file = 'lastPlan.pkl' if args['<output_file>'] != None: output_file = args['<output_file>'] if not output_file[-3:] == 'pkl': print 'WARNING: output file should end in "pkl" or you cannot use it as input later' nagents = int(args['-n']) if nagents < 0: print 'Numer of agents should be positive' exit() input_file = args['<input_file>'] if input_file[-3:] != 'pkl': a = nx.DiGraph() locs = [] i = 0 # each line should be id,name,lat,long,keys with open(input_file,'r') as fin: for line in fin: parts = line.split(',') if len(parts) < 3: break a.add_node(i) a.node[i]['name'] = parts[0].strip() locs.append( np.array(parts[1:3],dtype=int) ) if len(parts) < 4: a.node[i]['keys'] = 0 else: a.node[i]['keys'] = int(parts[3]) i += 1 n = a.order() # number of nodes locs = np.array(locs,dtype=float) # This part assumes we're working with E6 latitude-longitude data locs = geometry.e6LLtoRads(locs) xyz = geometry.radstoxyz(locs) xy = geometry.gnomonicProj(locs,xyz) for i in xrange(n): a.node[i]['geo'] = locs[i] a.node[i]['xyz'] = xyz [i] a.node[i]['xy' ] = xy [i] # EXTRA_SAMPLES attempts to get graph with few missing keys # Try to minimuze TK + 2*MK where # TK is the total number of missing keys # MK is the maximum number of missing keys for any single portal bestgraph = None bestlack = np.inf bestTK = np.inf bestMK = np.inf sinceImprove = 0 while sinceImprove<EXTRA_SAMPLES: b = a.copy() sinceImprove += 1 if not maxfield.maxFields(b): print 'Randomization failure\nThe program may work if you try again. It is more likely to work if you remove some protals.' continue TK = 0 MK = 0 for j in xrange(n): keylack = max(b.in_degree(j)-b.node[j]['keys'],0) TK += keylack if keylack > MK: MK = keylack weightedlack = TK+2*MK if weightedlack < bestlack: sinceImprove = 0 print 'IMPROVEMENT:\n\ttotal: %s\n\tmax: %s\n\tweighted: %s'%\ (TK,MK,weightedlack) bestgraph = b bestlack = weightedlack bestTK = TK bestMK = MK else: print 'this time:\n\ttotal: %s\n\tmax: %s\n\tweighted: %s'%\ (TK,MK,weightedlack) if weightedlack == 0: print 'KEY PERFECTION' bestlack = weightedlack bestTK = TK bestMK = MK break if all([ b.node[i]['keys'] <= b.out_degree(i) for i in xrange(n) ]): print 'All keys used. Improvement impossible' break print '%s tries since improvement'%sinceImprove if bestgraph == None: print 'EXITING RANDOMIZATION LOOP WITHOUT SOLUTION!' print '' exit() print 'Choosing plan requiring %s additional keys, max of %s from single portal'%(bestTK,bestMK) a = bestgraph # Attach to each edge a list of fields that it completes for t in a.triangulation: t.markEdgesWithFields() agentOrder.improveEdgeOrder(a) with open(output_directory+output_file,'w') as fout: pickle.dump(a,fout) else: with open(input_file,'r') as fin: a = pickle.load(fin) # agentOrder.improveEdgeOrder(a) # with open(output_directory+output_file,'w') as fout: # pickle.dump(a,fout) PP = PlanPrinter.PlanPrinter(a,output_directory,nagents,COLOR) PP.keyPrep() PP.agentKeys() PP.planMap() PP.agentLinks()
def main(): description=("Ingress Maxfield - Maximize the number of links " "and fields, and thus AP, for a collection of " "portals in the game Ingress.") parser = argparse.ArgumentParser(description=description, prog="makePlan.py") parser.add_argument('-v','--version',action='version', version="Ingress Maxfield v{0}".format(_V_)) parser.add_argument('-g','--google',action='store_true', help='Make maps with google maps API. Default: False') parser.add_argument('-a','--api_key',default=None, help='Google API key for Google maps. Default: None') parser.add_argument('-n','--num_agents',type=int,default='1', help='Number of agents. Default: 1') parser.add_argument('-s','--samples',type=int,default=50, help="Number of iterations to " "perform. More iterations may improve " "results, but will take longer to process. " "Default: 50") parser.add_argument('input_file', help="Input semi-colon delimited portal file") args = vars(parser.parse_args()) # Number of iterations to complete since last improvement EXTRA_SAMPLES = args["samples"] GREEN = '#3BF256' # Actual faction text colors in the app BLUE = '#2ABBFF' # Use google? useGoogle = True api_key = args['api_key'] input_file = args['input_file'] output_directory = os.path.expanduser('~') + "/Ingress/Fielding/{}".format(os.path.split(args['input_file'])[1][:-4]) print(output_directory) # add ending separator if output_directory[-1] != os.sep: output_directory += os.sep # create directory if doesn't exist if not os.path.exists(output_directory): os.makedirs(output_directory) output_file = (os.path.split(args['input_file'])[1][:-4]) print(output_file) if output_file[-4:] != '.pkl': output_file += ".pkl" nagents = args["num_agents"] if nagents < 0: sys.exit("Number of agents should be positive") EXTRA_SAMPLES = args["samples"] if EXTRA_SAMPLES < 0: sys.exit("Number of extra samples should be positive") elif EXTRA_SAMPLES > 100: sys.exit("Extra samples may not be more than 100") if input_file[-3:] != 'pkl': # If the input file is a portal list, let's set things up a = nx.DiGraph() # network tool locs = [] # portal coordinates # each line should be name;intel_link;keys portals = pd.read_table(input_file,sep=';', comment='#',index_col=False, names=['name','link','keys'],dtype=str) portals = np.array(portals) portals = np.array([portal for portal in portals if (isinstance(portal[0], basestring) and isinstance(portal[1], basestring))]) print ("Found {0} portals in portal list.".format(len(portals))) if len(portals) < 3: sys.exit("Error: Must have more than 2 portals!") if len(portals) > _MAX_PORTALS_: sys.exit("Error: Portal limit is {0}".\ format(_MAX_PORTALS_)) for num,portal in enumerate(portals): if len(portal) < 3: print ("Error! Portal ",portal[0]," has a formatting problem.") sys.exit() a.add_node(num) a.node[num]['name'] = portal[0] coords = (portal[1].split('pll=')) if len(coords) < 2: print ("Error! Portal ",portal[0]," has a formatting problem.") sys.exit() coord_parts = coords[1].split(',') lat = int(float(coord_parts[0]) * 1.e6) lon = int(float(coord_parts[1]) * 1.e6) locs.append(np.array([lat,lon],dtype=float)) try: keys = int(portal[2]) a.node[num]['keys'] = keys except ValueError: a.node[num]['keys'] = 0 n = a.order() # number of nodes locs = np.array(locs,dtype=float) # Convert coords to radians, then to cartesian, then to # gnomonic projection locs = geometry.e6LLtoRads(locs) xyz = geometry.radstoxyz(locs) xy = geometry.gnomonicProj(locs,xyz) for i in range(n): a.node[i]['geo'] = locs[i] a.node[i]['xyz'] = xyz[i] a.node[i]['xy' ] = xy[i] # EXTRA_SAMPLES attempts to get graph with few missing keys # Try to minimuze TK + 2*MK where # TK is the total number of missing keys # MK is the maximum number of missing keys for any single # portal bestgraph = None bestlack = np.inf bestTK = np.inf bestMK = np.inf allTK = [] allMK = [] allWeights = [] sinceImprove = 0 while sinceImprove<EXTRA_SAMPLES: b = a.copy() sinceImprove += 1 if not maxfield.maxFields(b): print ('Randomization failure\nThe program may work if you try again. It is more likely to work if you remove some portals.') continue TK = 0 MK = 0 for j in range(n): keylack = max(b.in_degree(j)-b.node[j]['keys'],0) TK += keylack if keylack > MK: MK = keylack weightedlack = TK+2*MK allTK.append(TK) allMK.append(MK) allWeights.append(weightedlack) if weightedlack < bestlack: sinceImprove = 0 print ('IMPROVEMENT:\n\ttotal: %s\n\tmax: %s\n\tweighted: %s'%\ (TK,MK,weightedlack)) bestgraph = b bestlack = weightedlack bestTK = TK bestMK = MK else: print ('this time:\n\ttotal: %s\n\tmax: %s\n\tweighted: %s'%\ (TK,MK,weightedlack)) if weightedlack <= 0: print ('KEY PERFECTION') bestlack = weightedlack bestTK = TK bestMK = MK break # if num agent keys is zero, this code isn't true... # if all([ b.node[i]['keys'] <= b.out_degree(i) for i in xrange(n) ]): # print 'All keys used. Improvement impossible' # break print ('%s tries since improvement'%sinceImprove) if bestgraph == None: print ('EXITING RANDOMIZATION LOOP WITHOUT SOLUTION!') print ('') exit() print ('Choosing plan requiring %s additional keys, max of %s from single portal'%(bestTK,bestMK)) plt.clf() plt.scatter(allTK,allMK,c=allWeights,marker='o') plt.xlim(min(allTK)-1,max(allTK)+1) plt.ylim(min(allMK)-1,max(allMK)+1) plt.xlabel('Total keys required') plt.ylabel('Max keys required for a single portal') cbar = plt.colorbar() cbar.set_label('Optimization Weighting (lower=better)') plt.savefig(output_directory+'optimization.png') a = bestgraph # Attach to each edge a list of fields that it completes # catch no triangulation (bad portal file?) try: for t in a.triangulation: t.markEdgesWithFields() except AttributeError: print ("Error: problem with bestgraph... no triangulation...?") agentOrder.improveEdgeOrder(a) with open(output_directory+output_file,'wb') as fout: pickle.dump(a,fout) else: with open(input_file,'r') as fin: a = pickle.load(fin) # agentOrder.improveEdgeOrder(a) # with open(output_directory+output_file,'w') as fout: # pickle.dump(a,fout) PP = PlanPrinterMap.PlanPrinter(a,output_directory,nagents,color=BLUE,useGoogle=useGoogle, api_key=api_key) PP.keyPrep() PP.agentKeys() PP.planMap(useGoogle=useGoogle) PP.agentLinks() # These make step-by-step instructional images PP.animate(useGoogle=useGoogle) PP.split3instruct(useGoogle=useGoogle) print ("Number of portals: {0}".format(PP.num_portals)) print ("Number of links: {0}".format(PP.num_links)) print ("Number of fields: {0}".format(PP.num_fields)) portal_ap = (125*8 + 500 + 250)*PP.num_portals link_ap = 313 * PP.num_links field_ap = 1250 * PP.num_fields print ("AP from portals capture: {0}".format(portal_ap)) print ("AP from link creation: {0}".format(link_ap)) print ("AP from field creation: {0}".format(field_ap)) print ("Total AP: {0}".format(portal_ap+link_ap+field_ap))
def main(): description = ("Ingress Maxfield - Maximize the number of links " "and fields, and thus AP, for a collection of " "portals in the game Ingress.") parser = argparse.ArgumentParser(description=description, prog="makePlan.py") parser.add_argument('-v', '--version', action='version', version="Ingress Maxfield v{0}".format(_V_)) parser.add_argument('-g', '--google', action='store_true', help='Make maps with google maps API. Default: False') parser.add_argument('-a', '--api_key', default=None, help='Google API key for Google maps. Default: None') parser.add_argument('-n', '--num_agents', type=int, default='1', help='Number of agents. Default: 1') parser.add_argument('-s', '--samples', type=int, default=50, help="Number of iterations to " "perform. More iterations may improve " "results, but will take longer to process. " "Default: 50") parser.add_argument('input_file', help="Input semi-colon delimited portal file") parser.add_argument('-d', '--output_dir', default='', help="Directory for results. Default: " "this directory") parser.add_argument('-f', '--output_file', default='plan.pkl', help="Filename for pickle object. Default: " "plan.pkl") args = vars(parser.parse_args()) # Number of iterations to complete since last improvement EXTRA_SAMPLES = args["samples"] GREEN = '#3BF256' # Actual faction text colors in the app BLUE = '#2ABBFF' # Use google? useGoogle = args['google'] api_key = args['api_key'] output_directory = args["output_dir"] # add ending separator if output_directory[-1] != os.sep: output_directory += os.sep # create directory if doesn't exist if not os.path.isdir(output_directory): os.mkdir(output_directory) output_file = args["output_file"] if output_file[-4:] != '.pkl': output_file += ".pkl" nagents = args["num_agents"] if nagents < 0: sys.exit("Number of agents should be positive") EXTRA_SAMPLES = args["samples"] if EXTRA_SAMPLES < 0: sys.exit("Number of extra samples should be positive") elif EXTRA_SAMPLES > 100: sys.exit("Extra samples may not be more than 100") input_file = args['input_file'] if input_file[-3:] != 'pkl': # If the input file is a portal list, let's set things up a = nx.DiGraph() # network tool locs = [] # portal coordinates # each line should be name;intel_link;keys portals = pd.read_table(input_file, sep=';', comment='#', index_col=False, names=['name', 'link', 'keys'], dtype=str) portals = np.array(portals) portals = np.array([ portal for portal in portals if (isinstance(portal[0], basestring) and isinstance(portal[1], basestring)) ]) print "Found {0} portals in portal list.".format(len(portals)) if len(portals) < 3: sys.exit("Error: Must have more than 2 portals!") if len(portals) > _MAX_PORTALS_: sys.exit("Error: Portal limit is {0}".\ format(_MAX_PORTALS_)) for num, portal in enumerate(portals): if len(portal) < 3: print "Error! Portal ", portal[0], " has a formatting problem." sys.exit() a.add_node(num) a.node[num]['name'] = portal[0] coords = (portal[1].split('pll=')) if len(coords) < 2: print "Error! Portal ", portal[0], " has a formatting problem." sys.exit() coord_parts = coords[1].split(',') lat = int(float(coord_parts[0]) * 1.e6) lon = int(float(coord_parts[1]) * 1.e6) locs.append(np.array([lat, lon], dtype=float)) try: keys = int(portal[2]) a.node[num]['keys'] = keys except ValueError: a.node[num]['keys'] = 0 n = a.order() # number of nodes locs = np.array(locs, dtype=float) # Convert coords to radians, then to cartesian, then to # gnomonic projection locs = geometry.e6LLtoRads(locs) xyz = geometry.radstoxyz(locs) xy = geometry.gnomonicProj(locs, xyz) for i in xrange(n): a.node[i]['geo'] = locs[i] a.node[i]['xyz'] = xyz[i] a.node[i]['xy'] = xy[i] # EXTRA_SAMPLES attempts to get graph with few missing keys # Try to minimuze TK + 2*MK where # TK is the total number of missing keys # MK is the maximum number of missing keys for any single # portal bestgraph = None bestlack = np.inf bestTK = np.inf bestMK = np.inf allTK = [] allMK = [] allWeights = [] sinceImprove = 0 while sinceImprove < EXTRA_SAMPLES: b = a.copy() sinceImprove += 1 if not maxfield.maxFields(b): print 'Randomization failure\nThe program may work if you try again. It is more likely to work if you remove some portals.' continue TK = 0 MK = 0 for j in xrange(n): keylack = max(b.in_degree(j) - b.node[j]['keys'], 0) TK += keylack if keylack > MK: MK = keylack weightedlack = TK + 2 * MK allTK.append(TK) allMK.append(MK) allWeights.append(weightedlack) if weightedlack < bestlack: sinceImprove = 0 print 'IMPROVEMENT:\n\ttotal: %s\n\tmax: %s\n\tweighted: %s'%\ (TK,MK,weightedlack) bestgraph = b bestlack = weightedlack bestTK = TK bestMK = MK else: print 'this time:\n\ttotal: %s\n\tmax: %s\n\tweighted: %s'%\ (TK,MK,weightedlack) if weightedlack <= 0: print 'KEY PERFECTION' bestlack = weightedlack bestTK = TK bestMK = MK break # if num agent keys is zero, this code isn't true... # if all([ b.node[i]['keys'] <= b.out_degree(i) for i in xrange(n) ]): # print 'All keys used. Improvement impossible' # break print '%s tries since improvement' % sinceImprove if bestgraph == None: print 'EXITING RANDOMIZATION LOOP WITHOUT SOLUTION!' print '' exit() print 'Choosing plan requiring %s additional keys, max of %s from single portal' % ( bestTK, bestMK) plt.clf() plt.scatter(allTK, allMK, c=allWeights, marker='o') plt.xlim(min(allTK) - 1, max(allTK) + 1) plt.ylim(min(allMK) - 1, max(allMK) + 1) plt.xlabel('Total keys required') plt.ylabel('Max keys required for a single portal') cbar = plt.colorbar() cbar.set_label('Optimization Weighting (lower=better)') plt.savefig(output_directory + 'optimization.png') a = bestgraph # Attach to each edge a list of fields that it completes # catch no triangulation (bad portal file?) try: for t in a.triangulation: t.markEdgesWithFields() except AttributeError: print "Error: problem with bestgraph... no triangulation...?" agentOrder.improveEdgeOrder(a) with open(output_directory + output_file, 'w') as fout: pickle.dump(a, fout) else: with open(input_file, 'r') as fin: a = pickle.load(fin) # agentOrder.improveEdgeOrder(a) # with open(output_directory+output_file,'w') as fout: # pickle.dump(a,fout) PP = PlanPrinterMap.PlanPrinter(a, output_directory, nagents, useGoogle=useGoogle, api_key=api_key) PP.keyPrep() PP.agentKeys() PP.planMap(useGoogle=useGoogle) PP.agentLinks() # These make step-by-step instructional images PP.animate(useGoogle=useGoogle) PP.split3instruct(useGoogle=useGoogle) print "Number of portals: {0}".format(PP.num_portals) print "Number of links: {0}".format(PP.num_links) print "Number of fields: {0}".format(PP.num_fields) portal_ap = (125 * 8 + 500 + 250) * PP.num_portals link_ap = 313 * PP.num_links field_ap = 1250 * PP.num_fields print "AP from portals capture: {0}".format(portal_ap) print "AP from link creation: {0}".format(link_ap) print "AP from field creation: {0}".format(field_ap) print "Total AP: {0}".format(portal_ap + link_ap + field_ap)
def main(args): start_time = time.time() if args.log is not None: sys.stdout = open(args.log,'w',0) GREEN = '#3BF256' # Actual faction text colors in the app BLUE = '#2ABBFF' if args.res: color=BLUE else: color=GREEN # Use google? useGoogle = args.google api_key = args.api_key output_directory = args.output_dir # add ending separator if output_directory[-1] != os.sep: output_directory += os.sep # create directory if doesn't exist if not os.path.isdir(output_directory): os.mkdir(output_directory) output_file = args.output_file if output_file[-4:] != '.pkl': output_file += ".pkl" nagents = args.num_agents if nagents <= 0: print "Number of agents should be greater than zero" raise ValueError("Number of agents should be greater than zero") input_file = args.input_file if input_file[-3:] != 'pkl': # If the input file is a portal list, let's set things up a = nx.DiGraph() # network tool locs = [] # portal coordinates # each line should be name;intel_link;keys portals = pd.read_table(input_file,sep=';', comment='#',index_col=False, names=['name','link','keys','sbla'], dtype=str) portals = np.array(portals) portals = np.array([portal for portal in portals if (isinstance(portal[0], basestring) and isinstance(portal[1], basestring))]) print "Found {0} portals in portal list.".format(len(portals)) if len(portals) < 3: print "Error: Must have more than 2 portals!" raise ValueError("Error: Must have more than 2 portals!") if len(portals) > _MAX_PORTALS_: print "Error: Portal limit is {0}".format(_MAX_PORTALS_) raise ValueError("Error: Portal limit is {0}".format(_MAX_PORTALS_)) for num,portal in enumerate(portals): if len(portal) < 3: print "Error! Portal ",portal[0]," has a formatting problem." raise ValueError("Error! Portal ",portal[0]," has a formatting problem.") # loop over columns. Four possibilities: # 0. First entry is always portal name # 1. contains "pll=" it is the Intel URL # 2. contains an intenger, it is the number of keys # 3. contains "sbla", it is an SBLA portal loc = None keys = 0 sbla = False for pind,pfoobar in enumerate(portal): if str(pfoobar) == 'nan': continue if pind == 0: # This is the name a.add_node(num) a.node[num]['name'] = pfoobar.strip() continue if 'pll=' in pfoobar: # this is the URL if loc is not None: print "Error! Already found URL for this portal: {0}".format(portal[0]) raise ValueError("Error! Already found URL for this portal: {0}".format(portal[0])) coords = (pfoobar.strip().split('pll=')) if len(coords) < 2: print "Error! Portal ",portal[0]," has a formatting problem." raise ValueError("Error! Portal ",portal[0]," has a formatting problem.") coord_parts = coords[1].split(',') lat = int(float(coord_parts[0]) * 1.e6) lon = int(float(coord_parts[1]) * 1.e6) loc = np.array([lat,lon],dtype=float) continue try: # this is the number of keys keys = int(pfoobar.strip()) continue except ValueError: pass try: # this is SBLA sbla = pfoobar.strip() sbla = (sbla.lower() == 'sbla') continue except ValueError: pass # we should never get here unless there was a bad column print "Error: bad data value here:" print portal print pfoobar raise ValueError() if loc is None: print "Formatting problem: {0}".format(portal[0]) raise ValueError("Formatting problem: {0}".format(portal[0])) locs.append(loc) a.node[num]['keys'] = keys a.node[num]['sbla'] = sbla if sbla: print "{0} has SBLA".format(portal[0]) n = a.order() # number of nodes locs = np.array(locs,dtype=float) # Convert coords to radians, then to cartesian, then to # gnomonic projection locs = geometry.LLtoRads(locs) xyz = geometry.radstoxyz(locs) xy = geometry.gnomonicProj(locs,xyz) for i in xrange(n): a.node[i]['geo'] = locs[i] a.node[i]['xyz'] = xyz[i] a.node[i]['xy' ] = xy[i] # Below is remnants from "random optimization" technique """ # EXTRA_SAMPLES attempts to get graph with few missing keys # Try to minimuze TK + 2*MK where # TK is the total number of missing keys # MK is the maximum number of missing keys for any single # portal bestgraph = None bestlack = np.inf bestTK = np.inf bestMK = np.inf allTK = [] allMK = [] allWeights = [] sinceImprove = 0 while sinceImprove<EXTRA_SAMPLES: b = a.copy() sinceImprove += 1 if not maxfield.maxFields(b): print 'Randomization failure\nThe program may work if you try again. It is more likely to work if you remove some portals.' continue TK = 0 MK = 0 for j in xrange(n): keylack = max(b.in_degree(j)-b.node[j]['keys'],0) TK += keylack if keylack > MK: MK = keylack weightedlack = TK+2*MK allTK.append(TK) allMK.append(MK) allWeights.append(weightedlack) if weightedlack < bestlack: sinceImprove = 0 print 'IMPROVEMENT:\n\ttotal: %s\n\tmax: %s\n\tweighted: %s'%\ (TK,MK,weightedlack) bestgraph = b bestlack = weightedlack bestTK = TK bestMK = MK else: print 'this time:\n\ttotal: %s\n\tmax: %s\n\tweighted: %s'%\ (TK,MK,weightedlack) if weightedlack <= 0: print 'KEY PERFECTION' bestlack = weightedlack bestTK = TK bestMK = MK break # if num agent keys is zero, this code isn't true... # if all([ b.node[i]['keys'] <= b.out_degree(i) for i in xrange(n) ]): # print 'All keys used. Improvement impossible' # break print '%s tries since improvement'%sinceImprove if bestgraph == None: print 'EXITING RANDOMIZATION LOOP WITHOUT SOLUTION!' print '' exit() print 'Choosing plan requiring %s additional keys, max of %s from single portal'%(bestTK,bestMK) plt.clf() plt.scatter(allTK,allMK,c=allWeights,marker='o') plt.xlim(min(allTK)-1,max(allTK)+1) plt.ylim(min(allMK)-1,max(allMK)+1) plt.xlabel('Total keys required') plt.ylabel('Max keys required for a single portal') cbar = plt.colorbar() cbar.set_label('Optimization Weighting (lower=better)') plt.savefig(output_directory+'optimization.png') a = bestgraph """ with open(output_directory+output_file,'w') as fout: pickle.dump(a,fout) else: with open(input_file,'r') as fin: a = pickle.load(fin) # Optimize the plan to get shortest walking distance best_plan = None best_PP = None best_time = 1.e9 for foobar in xrange(args.attempts): if not args.quiet: tdiff = time.time() - start_time hrs = int(tdiff/3600.) mins = int((tdiff-3600.*hrs)/60.) secs = tdiff-3600.*hrs-60.*mins sys.stdout.write("\r[{0:20s}] {1}% ({2}/{3} iterations) : {4:02}h {5:02}m {6:05.2f}s".\ format('#'*(20*foobar/args.attempts), 100*foobar/args.attempts, foobar,args.attempts, hrs,mins,secs)) b = copy.deepcopy(a) maxfield.maxFields(b,allow_suboptimal=(not args.optimal)) # Attach to each edge a list of fields that it completes # catch no triangulation (bad portal file?) try: for t in b.triangulation: t.markEdgesWithFields() except AttributeError: print "Error: problem with bestgraph... no triangulation...?" agentOrder.improveEdgeOrder(b) PP = PlanPrinterMap.PlanPrinter(b,output_directory,nagents,useGoogle=useGoogle, api_key=api_key,color=color) totalTime = b.walktime+b.linktime+b.commtime if totalTime < best_time: best_plan = b best_PP = copy.deepcopy(PP) best_time = totalTime if not args.quiet: tdiff = time.time() - start_time hrs = int(tdiff/3600.) mins = int((tdiff-3600.*hrs)/60.) secs = tdiff-3600.*hrs-60.*mins sys.stdout.write("\r[{0:20s}] {1}% ({2}/{3} iterations) : {4:02}h {5:02}m {6:05.2f}s".\ format('#'*(20), 100,args.attempts,args.attempts, hrs,mins,secs)) print "" # generate plan details and map best_PP.keyPrep() best_PP.agentKeys() best_PP.planMap(useGoogle=useGoogle) best_PP.agentLinks() # These make step-by-step instructional images if not args.skipplot: best_PP.animate(useGoogle=useGoogle) best_PP.split3instruct(useGoogle=useGoogle) print "" print "" print "" print "Found best plan after {0} iterations.".format(args.attempts) totalTime = best_plan.walktime+best_plan.linktime+best_plan.commtime print "Total time: {0} minutes".format(int(totalTime/60. + 0.5)) print "Number of portals: {0}".format(best_PP.num_portals) print "Number of links: {0}".format(best_PP.num_links) print "Number of fields: {0}".format(best_PP.num_fields) portal_ap = (125*8 + 500 + 250)*best_PP.num_portals link_ap = 313 * best_PP.num_links field_ap = 1250 * best_PP.num_fields print "AP from portals capture: {0}".format(portal_ap) print "AP from link creation: {0}".format(link_ap) print "AP from field creation: {0}".format(field_ap) print "Total AP: {0}".format(portal_ap+link_ap+field_ap) tdiff = time.time() - start_time hrs = int(tdiff/3600.) mins = int((tdiff-3600.*hrs)/60.) secs = tdiff-3600.*hrs-60.*mins print "Runtime: {0:02}h {1:02}m {2:05.2f}s".format(hrs,mins,secs) plt.close('all')
def main(): args = docopt(__doc__) # We will take many samples in an attempt to reduce number of keys to farm # This is the number of samples to take since the last improvement EXTRA_SAMPLES = 20 np = geometry.np #GREEN = 'g' #BLUE = 'b' GREEN = '#3BF256' # Actual faction text colors in the app BLUE = '#2ABBFF' #GREEN = (0.0 , 1.0 , 0.0 , 0.3) #BLUE = (0.0 , 0.0 , 1.0 , 0.3) COLOR = BLUE if args['-b']: COLOR = GREEN output_directory = '' if args['<output_directory>'] != None: output_directory = args['<output_directory>'] if output_directory[-1] != '/': output_directory += '/' if( not os.path.isdir('./'+output_directory) ): print 'Output directory (%s) does not exist. Creating it.' % output_directory os.makedirs('./'+output_directory) output_file = 'lastPlan.pkl' if args['<output_file>'] != None: output_file = args['<output_file>'] if not output_file[-3:] == 'pkl': print 'WARNING: output file should end in "pkl" or you cannot use it as input later' nagents = int(args['-n']) if nagents < 0: print 'Numer of agents should be positive' exit() input_file = args['<input_file>'] if input_file[-3:] != 'pkl': a = nx.DiGraph() locs = [] i = 0 # each line should be id,name,lat,long,keys with open(input_file,'r') as fin: for line in fin: parts = line.split(',') if len(parts) < 3: break # allow masking of input csv file # note, if no 4th column, back to default behavior # unless you put "false" as the number of keys ;) use = parts[-1].strip().lower() if(use == "false"): continue a.add_node(i) a.node[i]['name'] = parts[0].strip() locs.append( np.array(parts[1:3],dtype=int) ) if len(parts) < 4: a.node[i]['keys'] = 0 else: a.node[i]['keys'] = int(parts[3]) i += 1 n = a.order() # number of nodes locs = np.array(locs,dtype=float) # This part assumes we're working with E6 latitude-longitude data locs = geometry.e6LLtoRads(locs) xyz = geometry.radstoxyz(locs) xy = geometry.gnomonicProj(locs,xyz) for i in xrange(n): a.node[i]['geo'] = locs[i] a.node[i]['xyz'] = xyz [i] a.node[i]['xy' ] = xy [i] # EXTRA_SAMPLES attempts to get graph with few missing keys # Try to minimuze TK + 2*MK where # TK is the total number of missing keys # MK is the maximum number of missing keys for any single portal bestgraph = None bestlack = np.inf bestTK = np.inf bestMK = np.inf sinceImprove = 0 while sinceImprove<EXTRA_SAMPLES: b = a.copy() sinceImprove += 1 if not maxfield.maxFields(b): print 'Randomization failure\nThe program may work if you try again. It is more likely to work if you remove some protals.' continue TK = 0 MK = 0 for j in xrange(n): keylack = max(b.in_degree(j)-b.node[j]['keys'],0) TK += keylack if keylack > MK: MK = keylack weightedlack = TK+2*MK if weightedlack < bestlack: sinceImprove = 0 print 'IMPROVEMENT:\n\ttotal: %s\n\tmax: %s\n\tweighted: %s'%\ (TK,MK,weightedlack) bestgraph = b bestlack = weightedlack bestTK = TK bestMK = MK else: print 'this time:\n\ttotal: %s\n\tmax: %s\n\tweighted: %s'%\ (TK,MK,weightedlack) if weightedlack == 0: print 'KEY PERFECTION' bestlack = weightedlack bestTK = TK bestMK = MK break if all([ b.node[i]['keys'] <= b.out_degree(i) for i in xrange(n) ]): print 'All keys used. Improvement impossible' break print '%s tries since improvement'%sinceImprove if bestgraph == None: print 'EXITING RANDOMIZATION LOOP WITHOUT SOLUTION!' print '' exit() print 'Choosing plan requiring %s additional keys, max of %s from single portal'%(bestTK,bestMK) a = bestgraph # Attach to each edge a list of fields that it completes for t in a.triangulation: t.markEdgesWithFields() agentOrder.improveEdgeOrder(a) with open(output_directory+output_file,'w') as fout: pickle.dump(a,fout) else: with open(input_file,'r') as fin: a = pickle.load(fin) # agentOrder.improveEdgeOrder(a) # with open(output_directory+output_file,'w') as fout: # pickle.dump(a,fout) PP = PlanPrinter.PlanPrinter(a,output_directory,nagents,COLOR) PP.keyPrep() PP.agentKeys() PP.planMap() PP.agentLinks()
def main(args): start_time = time.time() if args.log is not None: sys.stdout = open(args.log, 'w', 0) GREEN = '#3BF256' # Actual faction text colors in the app BLUE = '#2ABBFF' if args.res: color = BLUE else: color = GREEN # Use google? useGoogle = args.google api_key = args.api_key output_directory = args.output_dir # add ending separator if output_directory[-1] != os.sep: output_directory += os.sep # create directory if doesn't exist if not os.path.isdir(output_directory): os.mkdir(output_directory) output_file = args.output_file if output_file[-4:] != '.pkl': output_file += ".pkl" nagents = args.num_agents if nagents <= 0: print "Number of agents should be greater than zero" raise ValueError("Number of agents should be greater than zero") input_file = args.input_file if input_file[-3:] != 'pkl': # If the input file is a portal list, let's set things up a = nx.DiGraph() # network tool locs = [] # portal coordinates # each line should be name;intel_link;keys portals = pd.read_table(input_file, sep=';', comment='#', index_col=False, names=['name', 'link', 'keys', 'sbla'], dtype=str) portals = np.array(portals) portals = np.array([ portal for portal in portals if (isinstance(portal[0], basestring) and isinstance(portal[1], basestring)) ]) print "Found {0} portals in portal list.".format(len(portals)) intel_url = "https://www.ingress.com/intel?z=17&" # setup url for intel map ll_set = False pls = [] if len(portals) < 3: print "Error: Must have more than 2 portals!" raise ValueError("Error: Must have more than 2 portals!") if len(portals) > _MAX_PORTALS_: print "Error: Portal limit is {0}".format(_MAX_PORTALS_) raise ValueError( "Error: Portal limit is {0}".format(_MAX_PORTALS_)) for num, portal in enumerate(portals): if len(portal) < 3: print "Error! Portal ", portal[0], " has a formatting problem." raise ValueError("Error! Portal ", portal[0], " has a formatting problem.") # loop over columns. Four possibilities: # 0. First entry is always portal name # 1. contains "pll=" it is the Intel URL # 2. contains an intenger, it is the number of keys # 3. contains "sbla", it is an SBLA portal loc = None keys = 0 sbla = False for pind, pfoobar in enumerate(portal): if str(pfoobar) == 'nan': continue if pind == 0: # This is the name a.add_node(num) a.node[num]['name'] = pfoobar.strip() continue if 'pll=' in pfoobar: # this is the URL if loc is not None: print "Error! Already found URL for this portal: {0}".format( portal[0]) raise ValueError( "Error! Already found URL for this portal: {0}". format(portal[0])) coords = (pfoobar.strip().split('pll=')) if len(coords) < 2: print "Error! Portal ", portal[ 0], " has a formatting problem." raise ValueError("Error! Portal ", portal[0], " has a formatting problem.") coord_parts = coords[1].split(',') lat = int(float(coord_parts[0]) * 1.e6) lon = int(float(coord_parts[1]) * 1.e6) pls.append(coord_parts[0] + "," + coord_parts[1]) loc = np.array([lat, lon], dtype=float) if not ll_set: # use coordinates from first portal to center the map intel_url += "ll=" + coord_parts[ 0] + "," + coord_parts[1] + "&" ll_set = True continue try: # this is the number of keys keys = int(pfoobar.strip()) continue except ValueError: pass try: # this is SBLA sbla = pfoobar.strip() sbla = (sbla.lower() == 'sbla') continue except ValueError: pass # we should never get here unless there was a bad column print "Error: bad data value here:" print portal print pfoobar raise ValueError() if loc is None: print "Formatting problem: {0}".format(portal[0]) raise ValueError("Formatting problem: {0}".format(portal[0])) locs.append(loc) a.node[num]['keys'] = keys a.node[num]['sbla'] = sbla if sbla: print "{0} has SBLA".format(portal[0]) n = a.order() # number of nodes locs = np.array(locs, dtype=float) # Convert coords to radians, then to cartesian, then to # gnomonic projection locs = geometry.LLtoRads(locs) xyz = geometry.radstoxyz(locs) xy = geometry.gnomonicProj(locs, xyz) for i in xrange(n): a.node[i]['geo'] = locs[i] a.node[i]['xyz'] = xyz[i] a.node[i]['xy'] = xy[i] # build portal list for intel_url intel_url += "pls=" json_output = [] for p in xrange(len(pls)): if p < len(pls) - 1: intel_url += pls[p] + "," + pls[p + 1] intel_url += "_" json_output.append({ "type": "polyline", "latLngs": [{ "lat": pls[p].split(',')[0], "lng": pls[p].split(',')[1] }, { "lat": pls[p + 1].split(',')[0], "lng": pls[p + 1].split(',')[1] }], "color": "#a24ac3" }) elif p == len(pls) - 1: intel_url += pls[p] + "," + pls[0] json_output.append({ "type": "polyline", "latLngs": [{ "lat": pls[p].split(',')[0], "lng": pls[p].split(',')[1] }, { "lat": pls[0].split(',')[0], "lng": pls[0].split(',')[1] }], "color": "#a24ac3" }) print intel_url print json.dumps(json_output, indent=4) # Below is remnants from "random optimization" technique """ # EXTRA_SAMPLES attempts to get graph with few missing keys # Try to minimuze TK + 2*MK where # TK is the total number of missing keys # MK is the maximum number of missing keys for any single # portal bestgraph = None bestlack = np.inf bestTK = np.inf bestMK = np.inf allTK = [] allMK = [] allWeights = [] sinceImprove = 0 while sinceImprove<EXTRA_SAMPLES: b = a.copy() sinceImprove += 1 if not maxfield.maxFields(b): print 'Randomization failure\nThe program may work if you try again. It is more likely to work if you remove some portals.' continue TK = 0 MK = 0 for j in xrange(n): keylack = max(b.in_degree(j)-b.node[j]['keys'],0) TK += keylack if keylack > MK: MK = keylack weightedlack = TK+2*MK allTK.append(TK) allMK.append(MK) allWeights.append(weightedlack) if weightedlack < bestlack: sinceImprove = 0 print 'IMPROVEMENT:\n\ttotal: %s\n\tmax: %s\n\tweighted: %s'%\ (TK,MK,weightedlack) bestgraph = b bestlack = weightedlack bestTK = TK bestMK = MK else: print 'this time:\n\ttotal: %s\n\tmax: %s\n\tweighted: %s'%\ (TK,MK,weightedlack) if weightedlack <= 0: print 'KEY PERFECTION' bestlack = weightedlack bestTK = TK bestMK = MK break # if num agent keys is zero, this code isn't true... # if all([ b.node[i]['keys'] <= b.out_degree(i) for i in xrange(n) ]): # print 'All keys used. Improvement impossible' # break print '%s tries since improvement'%sinceImprove if bestgraph == None: print 'EXITING RANDOMIZATION LOOP WITHOUT SOLUTION!' print '' exit() print 'Choosing plan requiring %s additional keys, max of %s from single portal'%(bestTK,bestMK) plt.clf() plt.scatter(allTK,allMK,c=allWeights,marker='o') plt.xlim(min(allTK)-1,max(allTK)+1) plt.ylim(min(allMK)-1,max(allMK)+1) plt.xlabel('Total keys required') plt.ylabel('Max keys required for a single portal') cbar = plt.colorbar() cbar.set_label('Optimization Weighting (lower=better)') plt.savefig(output_directory+'optimization.png') a = bestgraph """ with open(output_directory + output_file, 'w') as fout: pickle.dump(a, fout) else: with open(input_file, 'r') as fin: a = pickle.load(fin) # Optimize the plan to get shortest walking distance best_plan = None best_PP = None best_time = 1.e9 for foobar in xrange(args.attempts): if not args.quiet: tdiff = time.time() - start_time hrs = int(tdiff / 3600.) mins = int((tdiff - 3600. * hrs) / 60.) secs = tdiff - 3600. * hrs - 60. * mins sys.stdout.write("\r[{0:20s}] {1}% ({2}/{3} iterations) : {4:02}h {5:02}m {6:05.2f}s".\ format('#'*(20*foobar/args.attempts), 100*foobar/args.attempts, foobar,args.attempts, hrs,mins,secs)) b = copy.deepcopy(a) maxfield.maxFields(b, allow_suboptimal=(not args.optimal)) # Attach to each edge a list of fields that it completes # catch no triangulation (bad portal file?) try: for t in b.triangulation: t.markEdgesWithFields() except AttributeError: print "Error: problem with bestgraph... no triangulation...?" agentOrder.improveEdgeOrder(b) PP = PlanPrinterMap.PlanPrinter(b, output_directory, nagents, useGoogle=useGoogle, api_key=api_key, color=color) totalTime = b.walktime + b.linktime + b.commtime if totalTime < best_time: best_plan = b best_PP = copy.deepcopy(PP) best_time = totalTime b = best_plan agentOrder.improveEdgeOrderMore(b) # Re-run to fix the animations and stars of edges that can be done early # (improveEdgeOrderMore may have modified the completion order) try: first = True for t in b.triangulation: t.markEdgesWithFields(clean=first) first = False except AttributeError: print "Error: problem with bestgraph... no triangulation...?" best_PP = PlanPrinterMap.PlanPrinter(b, output_directory, nagents, useGoogle=useGoogle, api_key=api_key, color=color) best_time = b.walktime + b.linktime + b.commtime if not args.quiet: tdiff = time.time() - start_time hrs = int(tdiff / 3600.) mins = int((tdiff - 3600. * hrs) / 60.) secs = tdiff - 3600. * hrs - 60. * mins sys.stdout.write("\r[{0:20s}] {1}% ({2}/{3} iterations) : {4:02}h {5:02}m {6:05.2f}s".\ format('#'*(20), 100,args.attempts,args.attempts, hrs,mins,secs)) print "" # generate plan details and map best_PP.keyPrep() best_PP.agentKeys() best_PP.planMap(useGoogle=useGoogle) best_PP.agentLinks() # These make step-by-step instructional images if not args.skipplot: best_PP.animate(useGoogle=useGoogle) best_PP.split3instruct(useGoogle=useGoogle) print "" print "" print "" print "Found best plan after {0} iterations.".format(args.attempts) totalTime = best_plan.walktime + best_plan.linktime + best_plan.commtime print "Total time: {0} minutes".format(int(totalTime / 60. + 0.5)) print "Number of portals: {0}".format(best_PP.num_portals) print "Number of links: {0}".format(best_PP.num_links) print "Number of fields: {0}".format(best_PP.num_fields) portal_ap = (125 * 8 + 500 + 250) * best_PP.num_portals link_ap = 313 * best_PP.num_links field_ap = 1250 * best_PP.num_fields print "AP from portals capture: {0}".format(portal_ap) print "AP from link creation: {0}".format(link_ap) print "AP from field creation: {0}".format(field_ap) print "Total AP: {0}".format(portal_ap + link_ap + field_ap) tdiff = time.time() - start_time hrs = int(tdiff / 3600.) mins = int((tdiff - 3600. * hrs) / 60.) secs = tdiff - 3600. * hrs - 60. * mins print "Runtime: {0:02}h {1:02}m {2:05.2f}s".format(hrs, mins, secs) plt.close('all')
def main(): args = docopt.docopt(__doc__) timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S") COLOR = GREEN if args['-g'] else BLUE nagents = int(args['-n']) if nagents <= 0: print 'Number of agents should be positive' exit() # We will take many samples in an attempt to reduce number of keys to farm # This is the number of samples to take since the last improvement EXTRA_SAMPLES = int(args['-s']) if EXTRA_SAMPLES not in range(1, 101): print 'Number of extra samples must be between 1 and 100' exit() input_file = args['<input_file>'] name, ext = os.path.splitext(os.path.basename(input_file)) try: os.makedirs(name) except OSError as exception: if exception.errno != errno.EEXIST: raise output_directory = name + os.sep output_file = name + '_' + timestamp + '.pkl' if ext != '.pkl': a = nx.DiGraph() np = geometry.np locs = [] # each line should be name,intel_link,keys with open(input_file) as fin: text, encoding = guess_bytes(fin.read()) rows = unicodecsv.reader(text.encode('utf-8').strip().split('\n'), encoding='utf-8') for i, row in enumerate(rows): a.add_node(i) a.node[i]['name'] = row[0] url = ','.join(row[1:4]).strip() if not url.startswith('http'): print 'Unable to parse input file. Did you forget to put quotes around a name containing a comma?' exit() coords = urlparse.parse_qs(urlparse.urlparse(url).query)['pll'][0] # this could have been done the quick and dirty way, but I chose this way. It just felt right coord_parts = coords.split(',') lat = int(float(coord_parts[0]) * 1.e6) lon = int(float(coord_parts[1]) * 1.e6) locs.append(np.array([lat, lon], dtype=int)) # why does this have to be a numpy array? if '.' in row[-1]: a.node[i]['keys'] = 0 else: a.node[i]['keys'] = int(row[-1]) n = a.order() # number of nodes if n > 65: print 'Limit of 65 portals may be optimized at once' exit() locs = np.array(locs, dtype=float) # This part assumes we're working with E6 latitude-longitude data locs = geometry.e6LLtoRads(locs) xyz = geometry.radstoxyz(locs) xy = geometry.gnomonicProj(locs,xyz) for i in xrange(n): a.node[i]['geo'] = locs[i] a.node[i]['xyz'] = xyz [i] a.node[i]['xy' ] = xy [i] # EXTRA_SAMPLES attempts to get graph with few missing keys # Try to minimuze TK + 2*MK where # TK is the total number of missing keys # MK is the maximum number of missing keys for any single portal bestgraph = None bestlack = np.inf bestTK = np.inf bestMK = np.inf allTK = [] allMK = [] allWeights = [] sinceImprove = 0 while sinceImprove < EXTRA_SAMPLES: b = a.copy() sinceImprove += 1 if not maxfield.maxFields(b): print 'Randomization failure\n\tThe program may work if you try again. It is more likely to work if you remove some portals.' continue TK = 0 MK = 0 for j in xrange(n): keylack = max(b.in_degree(j)-b.node[j]['keys'],0) TK += keylack if keylack > MK: MK = keylack weightedlack = TK+2*MK allTK.append(TK) allMK.append(MK) allWeights.append(weightedlack) if weightedlack < bestlack: sinceImprove = 0 print 'IMPROVEMENT:\ttotal: {}\tmax: {}\tweighted: {}\t{} tries since improvement'.format(TK, MK, weightedlack, sinceImprove) bestgraph = b bestlack = weightedlack bestTK = TK bestMK = MK else: print 'this time:\ttotal: {}\tmax: {}\tweighted: {}\t{} tries since improvement'.format(TK, MK, weightedlack, sinceImprove) if weightedlack <= 0: print 'KEY PERFECTION' bestlack = weightedlack bestTK = TK bestMK = MK break # if num agent keys is zero, this code isn't true... # if all([ b.node[i]['keys'] <= b.out_degree(i) for i in xrange(n) ]): # print 'All keys used. Improvement impossible' # break if bestgraph == None: print 'EXITING RANDOMIZATION LOOP WITHOUT SOLUTION!' print '' exit() print 'Choosing plan requiring {} additional keys, max of {} from single portal'.format(bestTK, bestMK) plt.clf() plt.scatter(allTK,allMK,c=allWeights,marker='o') plt.xlim(min(allTK)-1,max(allTK)+1) plt.ylim(min(allMK)-1,max(allMK)+1) plt.xlabel('Total keys required') plt.ylabel('Max keys required for a single portal') cbar = plt.colorbar() cbar.set_label('Optimization Weighting (lower=better)') plt.savefig(output_directory+'optimization.png') a = bestgraph # remember: a = nx.DiGraph() # Attach to each edge a list of fields that it completes for t in a.triangulation: t.markEdgesWithFields() agentOrder.improveEdgeOrder(a) with open(output_directory+output_file,'w') as fout: pickle.dump(a, fout) else: with open(input_file,'r') as fin: a = pickle.load(fin) # agentOrder.improveEdgeOrder(a) # with open(output_directory+output_file,'w') as fout: # pickle.dump(a,fout) PP = PlanPrinterMap.PlanPrinter(a, output_directory, nagents, COLOR) PP.keyPrep() PP.agentKeys() PP.planMap() PP.agentLinks() # These make step-by-step instructional images PP.animate() PP.split3instruct() print "Number of portals: {0}".format(PP.num_portals) print "Number of links: {0}".format(PP.num_links) print "Number of fields: {0}".format(PP.num_fields) portal_ap = (125*8 + 500 + 250)*PP.num_portals link_ap = 313 * PP.num_links field_ap = 1250 * PP.num_fields print "AP from portals capture: {0}".format(portal_ap) print "AP from link creation: {0}".format(link_ap) print "AP from field creation: {0}".format(field_ap) print "Total AP: {0}".format(portal_ap+link_ap+field_ap)
def main(): args = docopt(__doc__) np = geometry.np #GREEN = 'g' #BLUE = 'b' GREEN = '#3BF256' # Actual faction text colors in the app BLUE = '#2ABBFF' #GREEN = (0.0 , 1.0 , 0.0 , 0.3) #BLUE = (0.0 , 0.0 , 1.0 , 0.3) COLOR = GREEN if args['-b']: COLOR = BLUE output_directory = '' if args['<output_directory>'] != None: output_directory = args['<output_directory>'] if output_directory[-1] != '/': output_directory += '/' output_file = 'lastPlan.pkl' if args['<output_file>'] != None: output_file = args['<output_file>'] if not output_file[-3:] == 'pkl': print 'WARNING: output file should end in "pkl" or you cannot use it as input later' nagents = int(args['-n']) if nagents <= 0: print 'Numer of agents should be positive' exit() input_file = args['<input_file>'] if input_file[-3:] != 'pkl': a = nx.DiGraph() locs = [] # ------------- URL ------------- # name ; lat , lng ; keys urlpat = re.compile('^([^;]*);.*ll=([-0-9\.]+),([-0-9\.]+)\s*;?\s*(\d+)?') # name ; lat ; lng ; keys cvspat = re.compile('^([^;]*);\s*([-0-9\.]+)\s*;\s*([-0-9\.]+)\s*;?\s*(\d+)?') i = 0 # each line should be id,name,lat,long,keys with open(input_file,'r') as fin: for line in fin: m = urlpat.match(line) if m == None: m = cvspat.match(line) if m == None: continue g = m.groups() # print g a.add_node(i) a.node[i]['name'] = g[0] locs.append( np.array([float(g[1]),float(g[2])] )) if g[3] == None: a.node[i]['keys'] = 0 else: a.node[i]['keys'] = int(g[3]) i += 1 n = a.order() # number of nodes locs = np.array(locs,dtype=float) # print locs # This part assumes we're working with decimal latitude-longitude data locs = geometry.LLtoRads(locs) xyz = geometry.radstoxyz(locs) xy = geometry.gnomonicProj(locs,xyz) for i in xrange(n): a.node[i]['geo'] = locs[i] a.node[i]['xyz'] = xyz [i] a.node[i]['xy' ] = xy [i] maxfield.maxFields(a) ''' # EXTRA_SAMPLES attempts to get graph with few missing keys # Try to minimuze TK + 2*MK where # TK is the total number of missing keys # MK is the maximum number of missing keys for any single portal bestgraph = None bestlack = np.inf bestTK = np.inf bestMK = np.inf sinceImprove = 0 while sinceImprove<EXTRA_SAMPLES: b = a.copy() sinceImprove += 1 if not maxfield.maxFields(b): print 'Randomization failure\nThe program may work if you try again. It is more likely to work if you remove some protals.' continue TK = 0 MK = 0 for j in xrange(n): keylack = max(b.in_degree(j)-b.node[j]['keys'],0) TK += keylack if keylack > MK: MK = keylack weightedlack = TK+2*MK if weightedlack < bestlack: sinceImprove = 0 print 'IMPROVEMENT:\n\ttotal: %s\n\tmax: %s\n\tweighted: %s'%\ (TK,MK,weightedlack) bestgraph = b bestlack = weightedlack bestTK = TK bestMK = MK else: print 'this time:\n\ttotal: %s\n\tmax: %s\n\tweighted: %s'%\ (TK,MK,weightedlack) if weightedlack == 0: print 'KEY PERFECTION' bestlack = weightedlack bestTK = TK bestMK = MK break # if all([ b.node[i]['keys'] <= b.out_degree(i) for i in xrange(n) ]): # print 'All keys used. Improvement impossible' # break # print '%s tries since improvement'%sinceImprove if bestgraph == None: print 'EXITING RANDOMIZATION LOOP WITHOUT SOLUTION!' print '' exit() print 'Choosing plan requiring %s additional keys, max of %s from single portal'%(bestTK,bestMK) a = bestgraph ''' # Attach to each edge a list of fields that it completes for t in a.triangulation: t.markEdgesWithFields() agentOrder.improveEdgeOrder(a) with open(output_directory+output_file,'w') as fout: pickle.dump(a,fout) else: with open(input_file,'r') as fin: a = pickle.load(fin) # agentOrder.improveEdgeOrder(a) # with open(output_directory+output_file,'w') as fout: # pickle.dump(a,fout) PP = PlanPrinter.PlanPrinter(a,output_directory,nagents,COLOR) PP.keyPrep() PP.agentKeys() PP.planMap() PP.agentLinks()
sinceImprove += 1 print '%s tries since improvement'%sinceImprove if bestgraph == None: print 'EXITING RANDOMIZATION LOOP WITHOUT SOLUTION!' exit() print 'Choosing plan requiring %s additional keys, max of %s from single portal'%(bestTK,bestMK) a = bestgraph # Attach to each edge a list of fields that it completes for t in a.triangulation: t.markEdgesWithFields() agentOrder.improveEdgeOrder(a) with open(output_directory+output_file,'w') as fout: pickle.dump(a,fout) else: with open(input_file,'r') as fin: a = pickle.load(fin) # agentOrder.improveEdgeOrder(a) # with open(output_directory+output_file,'w') as fout: # pickle.dump(a,fout) PP = PlanPrinter.PlanPrinter(a,output_directory,nagents) PP.keyPrep() PP.agentKeys() PP.planMap() PP.agentLinks()
def main(): args = docopt(__doc__) # We will take many samples in an attempt to reduce number of keys to farm # This is the number of samples to take since the last improvement EXTRA_SAMPLES = 50 np = geometry.np #GREEN = 'g' #BLUE = 'b' GREEN = '#3BF256' # Actual faction text colors in the app BLUE = '#2ABBFF' #GREEN = (0.0 , 1.0 , 0.0 , 0.3) #BLUE = (0.0 , 0.0 , 1.0 , 0.3) COLOR = GREEN if args['-b']: COLOR = BLUE output_directory = '' if args['<output_directory>'] != None: output_directory = args['<output_directory>'] if output_directory[-1] != '/': output_directory += '/' output_file = 'lastPlan.pkl' if args['<output_file>'] != None: output_file = args['<output_file>'] if not output_file[-3:] == 'pkl': print 'WARNING: output file should end in "pkl" or you cannot use it as input later' nagents = int(args['-n']) if nagents < 0: print 'Number of agents should be positive' exit() EXTRA_SAMPLES = int(args['-s']) if EXTRA_SAMPLES < 0: print 'Number of extra samples should be positive' exit() elif EXTRA_SAMPLES > 100: print 'Extra samples may not be more than 100' exit() input_file = args['<input_file>'] if input_file[-3:] != 'pkl': a = nx.DiGraph() locs = [] i = 0 # each line should be name,intel_link,keys with open(input_file,'r') as fin: for line in fin: parts = line.split(';') if len(parts) < 2: break a.add_node(i) a.node[i]['name'] = parts[0].strip() coords = (parts[1].split('pll='))[1] coord_parts = coords.split(',') lat = int(float(coord_parts[0]) * 1.e6) lon = int(float(coord_parts[1]) * 1.e6) locs.append( np.array([lat,lon],dtype=int) ) if len(parts) < 3: a.node[i]['keys'] = 0 else: a.node[i]['keys'] = int(parts[3]) i += 1 if i > 65: print 'Limit of 65 portals may be optimized at once' exit() n = a.order() # number of nodes locs = np.array(locs,dtype=float) # This part assumes we're working with E6 latitude-longitude data locs = geometry.e6LLtoRads(locs) xyz = geometry.radstoxyz(locs) xy = geometry.gnomonicProj(locs,xyz) for i in xrange(n): a.node[i]['geo'] = locs[i] a.node[i]['xyz'] = xyz [i] a.node[i]['xy' ] = xy [i] # EXTRA_SAMPLES attempts to get graph with few missing keys # Try to minimuze TK + 2*MK where # TK is the total number of missing keys # MK is the maximum number of missing keys for any single portal bestgraph = None bestlack = np.inf bestTK = np.inf bestMK = np.inf allTK = [] allMK = [] allWeights = [] sinceImprove = 0 while sinceImprove<EXTRA_SAMPLES: b = a.copy() sinceImprove += 1 if not maxfield.maxFields(b): print 'Randomization failure\nThe program may work if you try again. It is more likely to work if you remove some protals.' continue TK = 0 MK = 0 for j in xrange(n): keylack = max(b.in_degree(j)-b.node[j]['keys'],0) TK += keylack if keylack > MK: MK = keylack weightedlack = TK+2*MK allTK.append(TK) allMK.append(MK) allWeights.append(weightedlack) if weightedlack < bestlack: sinceImprove = 0 print 'IMPROVEMENT:\n\ttotal: %s\n\tmax: %s\n\tweighted: %s'%\ (TK,MK,weightedlack) bestgraph = b bestlack = weightedlack bestTK = TK bestMK = MK else: print 'this time:\n\ttotal: %s\n\tmax: %s\n\tweighted: %s'%\ (TK,MK,weightedlack) if weightedlack <= 0: print 'KEY PERFECTION' bestlack = weightedlack bestTK = TK bestMK = MK break # if num agent keys is zero, this code isn't true... # if all([ b.node[i]['keys'] <= b.out_degree(i) for i in xrange(n) ]): # print 'All keys used. Improvement impossible' # break print '%s tries since improvement'%sinceImprove if bestgraph == None: print 'EXITING RANDOMIZATION LOOP WITHOUT SOLUTION!' print '' exit() print 'Choosing plan requiring %s additional keys, max of %s from single portal'%(bestTK,bestMK) plt.clf() plt.scatter(allTK,allMK,c=allWeights,marker='o') plt.xlim(min(allTK)-1,max(allTK)+1) plt.ylim(min(allMK)-1,max(allMK)+1) plt.xlabel('Total keys required') plt.ylabel('Max keys required for a single portal') cbar = plt.colorbar() cbar.set_label('Optimization Weighting (lower=better)') plt.savefig(output_directory+'optimization.png') a = bestgraph # Attach to each edge a list of fields that it completes for t in a.triangulation: t.markEdgesWithFields() agentOrder.improveEdgeOrder(a) with open(output_directory+output_file,'w') as fout: pickle.dump(a,fout) else: with open(input_file,'r') as fin: a = pickle.load(fin) # agentOrder.improveEdgeOrder(a) # with open(output_directory+output_file,'w') as fout: # pickle.dump(a,fout) PP = PlanPrinterMap.PlanPrinter(a,output_directory,nagents,COLOR) PP.keyPrep() PP.agentKeys() PP.planMap() PP.agentLinks() # These make step-by-step instructional images PP.animate() PP.split3instruct() print "Number of portals: {0}".format(PP.num_portals) print "Number of links: {0}".format(PP.num_links) print "Number of fields: {0}".format(PP.num_fields) portal_ap = (125*8 + 500 + 250)*PP.num_portals link_ap = 313 * PP.num_links field_ap = 1250 * PP.num_fields print "AP from portals capture: {0}".format(portal_ap) print "AP from link creation: {0}".format(link_ap) print "AP from field creation: {0}".format(field_ap) print "Total AP: {0}".format(portal_ap+link_ap+field_ap)