Example #1
0
def populate_graph(portals):
    a = nx.DiGraph()
    locs = []

    for num, row in enumerate(portals):
        a.add_node(num)
        a.node[num]['name'] = row[0]
        coord_parts = row[1].split(',')
        a.node[num]['pll'] = row[1]
        if len(row) > 2:
            a.node[num]['special'] = row[2]
        else:
            a.node[num]['special'] = None
        lat = int(float(coord_parts[0]) * 1.e6)
        lon = int(float(coord_parts[1]) * 1.e6)
        locs.append(np.array([lat, lon], dtype=float))

    n = a.order()
    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]['pos'] = i
        a.node[i]['geo'] = locs[i]
        a.node[i]['xyz'] = xyz[i]
        a.node[i]['xy'] = xy[i]

    return a
Example #2
0
def populateGraph(portals):
    a = nx.DiGraph()
    locs = []

    for num, portal in enumerate(portals):
        a.add_node(num)
        a.node[num]['name'] = portal[0]
        coords = (portal[1].split('pll='))
        coord_parts = coords[1].split(',')
        a.node[num]['pll'] = '%s,%s' % (coord_parts[0], coord_parts[1])
        lat = int(float(coord_parts[0]) * 1.e6)
        lon = int(float(coord_parts[1]) * 1.e6)
        locs.append(np.array([lat, lon], dtype=float))

    n = a.order()
    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]

    return a
Example #3
0
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()
Example #4
0
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)
Example #5
0
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))
Example #6
0
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()
Example #7
0
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)
Example #8
0
                break
            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
Example #9
0
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)