示例#1
0
def getAgentOrder(a,nagents,orderedEdges):
    '''
    returns visits
    visits[i] = j means agent j should make edge i
    
    ALSO creates time attributes in a:
        
    Time that must be spent just walking
        a.walktime
    Time it takes to communicate completion of a sequence of links
        a.commtime
    Time spent navigating linking menu
        a.linktime
    '''
    geo = np.array([ a.node[i]['geo'] for i in xrange(a.order())])
    d = geometry.sphereDist(geo,geo)
    # print d
    order = [e[0] for e in orderedEdges]

    # Reduce sequences of links made from same portal to single entry
    condensed , mult = condenseOrder(order)

    link2agent , times = orderedTSP.getVisits(d,condensed,nagents)
    # print

    # Expand links made from same portal to original count
    link2agent = expandOrder(link2agent,mult)

    # If agents communicate sequential completions all at once, we avoid waiting for multiple messages
    # To find out how many communications will be sent, we count the number of same-agent link sequences
    condensed , mult = condenseOrder(link2agent)
    numCOMMs = len(condensed)

    # Time that must be spent just walking
    a.walktime = times[-1]/WALKSPEED
    # Waiting for link completion messages to be sent
    a.commtime = numCOMMs*COMMTIME
    # Time spent navigating linking menu
    a.linktime = a.size()*LINKTIME

    movements = [None]*nagents

    for i in xrange(len(link2agent)):
        try:    
            movements[link2agent[i]].append(i)
        except:
            movements[link2agent[i]] = [i]

    return movements
示例#2
0
def getAgentOrder(a, nagents, orderedEdges):
    '''
    returns visits
    visits[i] = j means agent j should make edge i
    
    ALSO creates time attributes in a:
        
    Time that must be spent just walking
        a.walktime
    Time it takes to communicate completion of a sequence of links
        a.commtime
    Time spent navigating linking menu
        a.linktime
    '''
    geo = np.array([a.node[i]['geo'] for i in xrange(a.order())])
    d = geometry.sphereDist(geo, geo)
    # print d
    order = [e[0] for e in orderedEdges]

    # Reduce sequences of links made from same portal to single entry
    condensed, mult = condenseOrder(order)

    link2agent, times = orderedTSP.getVisits(d, condensed, nagents)
    # print

    # Expand links made from same portal to original count
    link2agent = expandOrder(link2agent, mult)

    # If agents communicate sequential completions all at once, we avoid waiting for multiple messages
    # To find out how many communications will be sent, we count the number of same-agent link sequences
    condensed, mult = condenseOrder(link2agent)
    numCOMMs = len(condensed)

    # Time that must be spent just walking
    a.walktime = times[-1] / WALKSPEED
    # Waiting for link completion messages to be sent
    a.commtime = numCOMMs * COMMTIME
    # Time spent navigating linking menu
    a.linktime = a.size() * LINKTIME

    movements = [None] * nagents

    for i in xrange(len(link2agent)):
        try:
            movements[link2agent[i]].append(i)
        except:
            movements[link2agent[i]] = [i]

    return movements
示例#3
0
def getAgentOrder(a,nagents,orderedEdges):
    '''
    returns visits
    visits[i] = j means agent j should make edge i
    '''
    geo = np.array([ a.node[i]['geo'] for i in xrange(a.order())])
    d = geometry.sphereDist(geo,geo)
#    print d
    order = [e[0] for e in orderedEdges]
    link2agent , times = orderedTSP.getVisits(d,order,nagents)

    print 'Plan can be completed in time it takes one agent to walk',times[-1],'meters'

    movements = [None]*nagents

    # I realize that switching between these formats all the time is stupid
    # Consistency hasn't been my highest priority
    for i in xrange(len(link2agent)):
        try:    
            movements[link2agent[i]].append(i)
        except:
            movements[link2agent[i]] = [i]

    return movements
示例#4
0
def getGreedyAgentOrder_DONT_USE_THIS_FUNCTION(a,nagents,orderedEdges):
    '''
    a is a digraph
        node have 'pos' property with location
    nagents is the number of agents
    orderedEdges maps i to the ith edge to be made

    this greedily minimizes wait time (equating distance with time)
    the player who has the most time to spare is assigned the link
    '''
    m = len(orderedEdges)

    # movements[i][j] will be the index (in orderedEdges) of the jth edge that agent i should make
    movements = dict([ (i,[]) for i in range(nagents) ])

    # The ammount of time that has elapsed
    curtime = 0.

    # Last time at which the agents made links
    lastActTime = np.zeros(nagents)
    
    # agent locations
    agentpos = np.empty([nagents,2])

    # Find initial deployments: starts[i] is the agent who starts at node i
    starts = {}
    assigning = 0

    e=0
    for e in xrange(m):
        p = orderedEdges[e][0]
        if not p in starts:
            # Nobody is at this link's head yet
            movements[assigning].append(e)
            starts[p] = assigning
            
            agentpos[assigning] = a.node[p]['geo']

            assigning += 1
            if assigning >= nagents:
                break
        else:
            # the agent who is already at this link's head should make it
            movements[starts[p]].append(e)

    # No agents have actually moved yet

    # continue from startup loop
    for e in xrange(e+1,m):
        p,q = orderedEdges[e]
        ppos = a.node[p]['geo']

        dists = geometry.sphereDist(agentpos,ppos)
        radii = curtime-lastActTime # how far could they have moved
        waits = dists-radii # how long will the team wait if this agent moves
        waits[waits<0] = 0 # no time travel

        mover = np.argmin(waits)
        movements[mover].append(e)

        agentpos[mover] = ppos
        curtime += waits[mover] + linkTime
        lastActTime[mover] = curtime
    
    return movements
示例#5
0
def getGreedyAgentOrder_DONT_USE_THIS_FUNCTION(a, nagents, orderedEdges):
    '''
    a is a digraph
        node have 'pos' property with location
    nagents is the number of agents
    orderedEdges maps i to the ith edge to be made

    this greedily minimizes wait time (equating distance with time)
    the player who has the most time to spare is assigned the link
    '''
    m = len(orderedEdges)

    # movements[i][j] will be the index (in orderedEdges) of the jth edge that agent i should make
    movements = dict([(i, []) for i in range(nagents)])

    # The ammount of time that has elapsed
    curtime = 0.

    # Last time at which the agents made links
    lastActTime = np.zeros(nagents)

    # agent locations
    agentpos = np.empty([nagents, 2])

    # Find initial deployments: starts[i] is the agent who starts at node i
    starts = {}
    assigning = 0

    e = 0
    for e in xrange(m):
        p = orderedEdges[e][0]
        if not p in starts:
            # Nobody is at this link's head yet
            movements[assigning].append(e)
            starts[p] = assigning

            agentpos[assigning] = a.node[p]['geo']

            assigning += 1
            if assigning >= nagents:
                break
        else:
            # the agent who is already at this link's head should make it
            movements[starts[p]].append(e)

    # No agents have actually moved yet

    # continue from startup loop
    for e in xrange(e + 1, m):
        p, q = orderedEdges[e]
        ppos = a.node[p]['geo']

        dists = geometry.sphereDist(agentpos, ppos)
        radii = curtime - lastActTime  # how far could they have moved
        waits = dists - radii  # how long will the team wait if this agent moves
        waits[waits < 0] = 0  # no time travel

        mover = np.argmin(waits)
        movements[mover].append(e)

        agentpos[mover] = ppos
        curtime += waits[mover] + linkTime
        lastActTime[mover] = curtime

    return movements
示例#6
0
def improveEdgeOrderMore(a):
    '''
    A greedy algorithm to reduce the path length.
    Moves edges earlier or later, if they can be moved (dependencies are
    done in the proper order) and the move reduces the total length of the
    path.
    The algorithm tries to move 1 to 5 edges at the same time as a block
    to improve upon certain types of local optima.
    '''

    m = a.size()
    # If link i is e then orderedEdges[i]=e
    orderedEdges = [-1] * m

    geo = np.array([a.node[i]['geo'] for i in xrange(a.order())])
    d = geometry.sphereDist(geo, geo)

    def pathLength(d, edges):
        startps = [edges[i][0] for i in xrange(len(edges))]
        return np.sum(d[startps[:-1], startps[1:]])

    def dependsOn(subjects, objects):
        '''
        Returns True, if an edge inside 'objects' should be made before
        one (or more) of the edges inside 'subjects'
        '''
        for p, q in subjects:
            depends = a.edge[p][q]['depends']
            for u, v in objects:
                if depends.count((
                        u,
                        v,
                )) > 0 or depends.count(u) > 0:
                    return True

        return False

    def possiblePlaces(j, block):
        '''
        A generator returning the possible places of the given
        block of edges within the complete edge sequence.
        The current position (j) is not returned.
        '''
        pos = j
        # smaller index means made earlier
        while pos > 0 and not dependsOn(block, [orderedEdges[pos - 1]]):
            pos -= 1
            yield pos

        bsize = len(block)
        pos = j + bsize
        n = len(orderedEdges) + 1
        # bigger index means made later
        while pos < n - 1 and not dependsOn([orderedEdges[pos]], block):
            pos += 1
            yield pos

    for p, q in a.edges_iter():
        orderedEdges[a.edge[p][q]['order']] = (p, q)

    origLength = pathLength(d, orderedEdges)
    bestLength = origLength

    cont = True
    while cont:
        cont = False
        for j in xrange(m):
            best = j
            bestPath = orderedEdges
            currentLength = bestLength
            # max block size is 5 (6-1); chosen arbitrarily
            for block in xrange(1, 6):
                moving = orderedEdges[j:j + block]
                # if the first and last link in the block are from the same portal
                # and the link before or after the block is also from that portal,
                # moving the block will not improve the path length, and thus there
                # is no point in trying
                if moving[0][0] == moving[-1][0] and (
                    (j > 0 and moving[0][0] == orderedEdges[j - 1][0]) or
                    (j + block < m
                     and moving[0][0] == orderedEdges[j + block][0])):
                    continue

                removedEdgesLengthBase = 0
                addedEdgesLengthBase = 0
                if j > 0:
                    removedEdgesLengthBase += d[orderedEdges[j - 1][0],
                                                orderedEdges[j][0]]
                if j + block < m:
                    removedEdgesLengthBase += d[orderedEdges[j + block - 1][0],
                                                orderedEdges[j + block][0]]
                if j > 0 and j + block < m:
                    addedEdgesLengthBase += d[orderedEdges[j - 1][0],
                                              orderedEdges[j + block][0]]
                for possible in possiblePlaces(j, moving):
                    addedEdgesLength = addedEdgesLengthBase
                    removedEdgesLength = removedEdgesLengthBase
                    if possible > 0:
                        addedEdgesLength += d[orderedEdges[possible - 1][0],
                                              moving[0][0]]
                        if possible < m:
                            removedEdgesLength += d[orderedEdges[possible -
                                                                 1][0],
                                                    orderedEdges[possible][0]]
                    if possible < m:
                        addedEdgesLength += d[moving[-1][0],
                                              orderedEdges[possible][0]]

                    length = currentLength - removedEdgesLength + addedEdgesLength
                    if bestLength - length <= 1e-10:
                        continue

                    #print("Improved by %f meters in index %d (from %d, block %d)" % (bestLength-length, possible, best, block))

                    if possible < j:
                        # Move the links to be at an earlier index
                        bestPath = orderedEdges[   :possible] +\
                                    moving +\
                                    orderedEdges[possible  :j] +\
                                    orderedEdges[j+block: ]
                    else:
                        # Move to a later position
                        bestPath = orderedEdges[   :j] +\
                                    orderedEdges[j+block: possible] +\
                                    moving +\
                                    orderedEdges[possible  :]
                    #assert abs(length - pathLength(d,bestPath)) < 1e-10
                    best = possible
                    bestLength = length

            if best != j:
                #print("New order (%d -> %d): %s" % (j, best, bestPath))
                orderedEdges = bestPath
                cont = True

    length = pathLength(d, orderedEdges)
    print
    #print("Length reduction: original = %d, improved = %d, change = %d meters" % (origLength, length, length-origLength))

    for i in xrange(m):
        p, q = orderedEdges[i]
        a.edge[p][q]['order'] = i
示例#7
0
    def agentLinks(self):
        # Total distance traveled by each agent
        agentdists = np.zeros(self.nagents)
        # Total experience for each agent
        agentexps  = np.zeros(self.nagents,dtype=int)

        for i in range(self.nagents):
            movie = self.movements[i]
            # first portal in first link
            curpos = self.a.node[self.orderedEdges[movie[0]][0]]['geo']
            for e in movie[1:]:
                p,q = self.orderedEdges[e]
                newpos = self.a.node[p]['geo']
                dist = geometry.sphereDist(curpos,newpos)
                agentdists[i] += dist
                curpos = newpos

                agentexps[i] += 313 + 1250*len(self.a.edge[p][q]['fields'])

        # Different formatting for the agent's own links
        plainStr = '{0:4d}{1:1s} {2: 5d}{3:5d} {4:s}\n            {5:4d} {6:s}\n\n'
        hilitStr = '{0:4d}{1:1s} {2:_>5d}{3:5d} {4:s}\n            {5:4d} {6:s}\n\n'

        csv_file = open(self.outputDir+'links_for_agents.csv','w')
        
        for agent in range(self.nagents):
            with open(self.outputDir+'links_for_agent_%s_of_%s.txt'\
                    %(agent+1,self.nagents),'w') as fout:

                fout.write('Complete link schedule issued to agent %s of %s\n'\
                    %(agent+1,self.nagents))
                
                totalTime = self.a.walktime+self.a.linktime+self.a.commtime

                fout.write('\nTotal time estimate: %s minutes\n\n'%int(totalTime/60+.5))

                fout.write('Agent distance:   %s m\n'%int(agentdists[agent]))
                fout.write('Agent experience: %s AP\n'%(agentexps[agent]))

                fout.write('\nLinks marked with * can be made EARLY\n')

                fout.write('\nLink  Agent Map# Link Origin\n')
                fout.write('                 Link Destination\n')
                fout.write('-----------------------------------\n')
                #             1234112345612345 name
                csv_file.write('Link, Agent, MapNumOrigin, OriginName, MapNumDestination, DestinationName\n')
                
                for i in xrange(self.m):
                    p,q = self.orderedEdges[i]
                    
                    linkagent = self.link2agent[i]

                    # Put a star by links that can be completed early since they complete no fields
                    numfields = len(self.a.edge[p][q]['fields'])
                    if numfields == 0:
                        star = '*'
#                        print '%s %s completes nothing'%(p,q)
                    else:
                        star = ''
#                        print '%s %s completes'%(p,q)
#                        for t in self.a.edge[p][q]['fields']:
#                            print '   ',t

                    if linkagent != agent:
                        fout.write(plainStr.format(\
                            i,\
                            star,\
                            linkagent+1,\
                            self.nslabel[p],\
                            self.names[p],\
                            self.nslabel[q],\
                            self.names[q]\
                        ))
                    else:
                        fout.write(hilitStr.format(\
                            i,\
                            star,\
                            linkagent+1,\
                            self.nslabel[p],\
                            self.names[p],\
                            self.nslabel[q],\
                            self.names[q]\
                        ))
                    csv_file.write("{0}{1}, {2}, {3}, {4}, {5}, {6}\n".\
                                   format(i,star,linkagent+1,
                                          self.nslabel[p],self.names[p],
                                          self.nslabel[q],self.names[q]))
        csv_file.close()
示例#8
0
    def agentLinks(self):
        # Total distance traveled by each agent
        agentdists = np.zeros(self.nagents)
        # Total number of links, fields for each agent
        agentlinkcount = [0] * self.nagents
        agentfieldcount = [0] * self.nagents
        totalAP = 0
        totalDist = 0

        for i in range(self.nagents):
            movie = self.movements[i]
            # first portal in first link
            curpos = self.a.node[self.orderedEdges[movie[0]][0]]['geo']
            for e in movie[1:]:
                p, q = self.orderedEdges[e]
                newpos = self.a.node[p]['geo']
                dist = geometry.sphereDist(curpos, newpos)
                # print 'Agent %s walks %s to %s'%(i,dist,self.nslabel[p])
                agentdists[i] += dist
                curpos = newpos

                agentlinkcount[i] += 1
                agentfieldcount[i] += len(self.a.edge[p][q]['fields'])
                self.num_fields += len(self.a.edge[p][q]['fields'])
                totalAP += 313
                totalAP += 1250 * len(self.a.edge[p][q]['fields'])
                totalDist += dist

        # Different formatting for the agent's own links
        plainStr = '{0:4d}{1:1s} {2: 5d}{3:5d} {4:s} -> {5:d} {6:s}\n'
        hilitStr = '{0:4d}{1:1s} {2:_>5d}{3:5d} {4:s}\n            {5:4d} {6:s}\n\n'

        totalTime = self.a.walktime + self.a.linktime + self.a.commtime

        csv_file = open(self.outputDir + 'links_for_agents.csv', 'w')
        csv_file.write(
            'Link, Agent, MapNumOrigin, OriginName, MapNumDestination, DestinationName\n'
        )

        for agent in range(self.nagents):
            with open(self.outputDir+'links_for_agent_%s_of_%s.txt'\
                    %(agent+1,self.nagents),'w') as fout:
                fout.write('Complete link schedule issued to agent %s of %s           %s\n\n'\
                    %(agent+1,self.nagents,time.strftime('%Y-%m-%d %H:%M:%S %Z')))
                fout.write('\nLinks marked with * can be made EARLY\n')
                fout.write('----------- PLAN DATA ------------\n')
                fout.write('Minutes:                 %s minutes\n' %
                           int(totalTime / 60 + .5))
                fout.write('Total Distance:          %s meter\n' %
                           int(totalDist))
                fout.write('Total AP:                %s\n' % totalAP)
                fout.write('AP per Agent per minute: %0.2f AP/Agent/min\n' %
                           float(totalAP / self.nagents /
                                 (totalTime / 60 + .5)))
                fout.write('AP per Agent per meter:  %0.2f AP/Agent/m\n' %
                           float(totalAP / self.nagents / totalDist))

                agentAP = 313 * agentlinkcount[agent] + 1250 * agentfieldcount[
                    agent]

                fout.write('----------- AGENT DATA -----------\n')
                fout.write('Distance traveled: %s m (%s %%)\n' %
                           (int(agentdists[agent]),
                            int(100 * agentdists[agent] / totalDist)))
                fout.write('Links made:        %s\n' % (agentlinkcount[agent]))
                fout.write('Fields completed:  %s\n' %
                           (agentfieldcount[agent]))
                fout.write('Total experience:  %s AP (%s %%)\n' %
                           (agentAP, int(100 * agentAP / totalAP)))
                fout.write('----------------------------------\n')
                fout.write('Link  Agent Map# Link Origin\n')
                fout.write('                 Link Destination\n')
                fout.write('----------------------------------\n')
                #             1234112345612345 name

                last_link_from_other_agent = 0
                for i in xrange(self.m):
                    p, q = self.orderedEdges[i]

                    linkagent = self.link2agent[i]

                    # Put a star by links that can be completed early since they complete no fields
                    numfields = len(self.a.edge[p][q]['fields'])
                    if numfields == 0:
                        star = '*'
                        # print '%s %s completes nothing'%(p,q)
                    else:
                        star = ''
                        # print '%s %s completes'%(p,q)
                        # for t in self.a.edge[p][q]['fields']:
                        #     print '   ',t

                    if linkagent != agent:
                        fout.write(plainStr.format(\
                            i+1,\
                            star,\
                            linkagent+1,\
                            self.nslabel[p],\
                            self.names[p],\
                            self.nslabel[q],\
                            self.names[q]\
                        ))
                        last_link_from_other_agent = 1
                    else:
                        if last_link_from_other_agent:
                            fout.write('\n')
                        last_link_from_other_agent = 0
                        fout.write(hilitStr.format(\
                            i+1,\
                            star,\
                            linkagent+1,\
                            self.nslabel[p],\
                            self.names[p],\
                            self.nslabel[q],\
                            self.names[q]\
                        ))
                        csv_file.write("{0}{1}, {2}, {3}, {4}, {5}, {6}\n".\
                                   format(i,star,linkagent+1,
                                          self.nslabel[p],self.names[p],
                                          self.nslabel[q],self.names[q]))
        csv_file.close()
示例#9
0
    def agentLinks(self):
        # Total distance traveled by each agent
        agentdists = np.zeros(self.nagents)
        # Total experience for each agent
        agentexps = np.zeros(self.nagents, dtype=int)
        agentfields = np.zeros(self.nagents, dtype=int)

        for i in range(self.nagents):
            movie = self.movements[i]
            # first portal in first link
            curpos = self.a.node[self.orderedEdges[movie[0]][0]]['geo']
            for e in movie[1:]:
                p, q = self.orderedEdges[e]
                newpos = self.a.node[p]['geo']
                dist = geometry.sphereDist(curpos, newpos)
                agentdists[i] += dist
                curpos = newpos

                agentexps[i] += 313 + 1250 * len(self.a.edge[p][q]['fields'])
                agentfields[i] += len(self.a.edge[p][q]['fields'])

        # Different formatting for the agent's own links
        plainStr = '{0:4d}{1:1s} {2: 5d}{3:5d} {4:s}\n            {5:4d} {6:s}\n\n'
        hilitStr = '{0:4d}{1:1s} {2:_>5d}{3:5d} {4:s}\n            {5:4d} {6:s}\n\n'

        for agent in range(self.nagents):
            with open(self.outputDir+'links_for_agent_%s_of_%s.txt'\
                    %(agent+1,self.nagents),'w') as fout:

                fout.write('Complete link schedule issued to agent %s of %s\n'\
                    %(agent+1,self.nagents))

                totalTime = self.a.walktime + self.a.linktime + self.a.commtime

                fout.write('\nTotal time estimate: %s minutes\n\n' %
                           int(totalTime / 60 + .5))

                fout.write('Agent distance:   %s m\n' % int(agentdists[agent]))
                fout.write('Agent experience: %s AP\n' % (agentexps[agent]))

                print 'Agent fields: %s\n' % (agentfields[agent])
                print 'Agent experience: %s AP\n' % (agentexps[agent])

                fout.write('\nLinks marked with * can be made EARLY\n')

                fout.write('\nLink  Agent Map# Link Origin\n')
                fout.write('                 Link Destination\n')
                fout.write('-----------------------------------\n')
                #             1234112345612345 name

                seqLinks = []
                earlyLinks = []

                for i in xrange(self.m):
                    p, q = self.orderedEdges[i]

                    linkagent = self.link2agent[i]

                    # Put a star by links that can be completed early since they complete no fields
                    numfields = len(self.a.edge[p][q]['fields'])
                    if numfields == 0:
                        star = '*'
#                        print '%s %s completes nothing'%(p,q)
                    else:
                        star = ''
#                        print '%s %s completes'%(p,q)
#                        for t in self.a.edge[p][q]['fields']:
#                            print '   ',t

# print star, i, self.names[p], "-->", self.names[q]
                    if (star == '*'):
                        earlyLinks.append([i, p, q])
                    else:
                        seqLinks.append([i, self.names[p], self.names[q]])

                    if linkagent != agent:
                        fout.write(plainStr.format(\
                            i,\
                            star,\
                            linkagent+1,\
                            self.nslabel[p],\
                            self.names[p],\
                            self.nslabel[q],\
                            self.names[q]\
                        ))
                    else:
                        fout.write(hilitStr.format(\
                            i,\
                            star,\
                            linkagent+1,\
                            self.nslabel[p],\
                            self.names[p],\
                            self.nslabel[q],\
                            self.names[q]\
                        ))

                earlyPointsToOpt = []
                for i, point in enumerate(earlyLinks):
                    p, q = point[1], point[2]
                    x, y = self.xy[p][0], self.xy[p][1]
                    earlyPointsToOpt.append([i, float(x), float(y)])

                # print earlyPointsToOpt
                print 'Agent distance:   %s m\n' % int(agentdists[agent])

                costs, earlyPointsOptimized = tsp.simAnneal(
                    earlyPointsToOpt)  # NJA XXX
                for point in earlyPointsOptimized:
                    i, p, q = earlyLinks[point[0]]

                    print '*', i, self.names[p], "-->", self.names[q]

                for link in seqLinks:
                    print ' ', link[0], link[1], "-->", link[2]
示例#10
0
    def agentLinks(self):

        # Total distance traveled by each agent
        agentdists = np.zeros(self.nagents)
        # Total number of links, fields for each agent
        agentlinkcount  = [0]*self.nagents
        agentfieldcount = [0]*self.nagents
        totalAP         = 0
        totalDist       = 0

        for i in range(self.nagents):
            movie = self.movements[i]
            # first portal in first link
            curpos = self.a.node[self.orderedEdges[movie[0]][0]]['geo']
            for e in movie[1:]:
                p,q = self.orderedEdges[e]
                newpos = self.a.node[p]['geo']
                dist = geometry.sphereDist(curpos,newpos)
#                print 'Agent %s walks %s to %s'%(i,dist,self.nslabel[p])
                agentdists[i] += dist
                curpos = newpos

                agentlinkcount[i] += 1
                agentfieldcount[i] += len(self.a.edge[p][q]['fields'])
                totalAP += 313
                totalAP += 1250 * len(self.a.edge[p][q]['fields'])
                totalDist += dist

        # Different formatting for the agent's own links
#        plainStr = '{0:4d}{1:1s} {2: 5d}{3:5d} {4:s}\n            {5:4d} {6:s}\n\n'
        plainStr = '{0:4d}{1:1s} {2: 5d}{3:5d} {4:s} -> {5:d} {6:s}\n'
        hilitStr = '{0:4d}{1:1s} {2:_>5d}{3:5d} {4:s}\n            {5:4d} {6:s}\n\n'
        
        totalTime = self.a.walktime+self.a.linktime+self.a.commtime

        for agent in range(self.nagents):
            with open(self.outputDir+'links_for_agent_%s_of_%s.txt'\
                    %(agent+1,self.nagents),'w') as fout:

                fout.write('Complete link schedule issued to agent %s of %s           %s\n\n'\
                    %(agent+1,self.nagents,time.strftime('%Y-%m-%d %H:%M:%S %Z')))
                fout.write('\nLinks marked with * can be made EARLY\n')
                
                fout.write('----------- PLAN DATA ------------\n')
                fout.write('Minutes:                 %s minutes\n'%int(totalTime/60+.5))
                fout.write('Total Distance:          %s meter\n'%int(totalDist))
                fout.write('Total AP:                %s\n'%totalAP)
                fout.write('AP per Agent per minute: %0.2f AP/Agent/min\n'%float(totalAP/self.nagents/(totalTime/60+.5)))
                fout.write('AP per Agent per meter:  %0.2f AP/Agent/m\n'%float(totalAP/self.nagents/totalDist))

                agentAP = 313*agentlinkcount[agent] + 1250*agentfieldcount[agent]

                fout.write('----------- AGENT DATA -----------\n')
                fout.write('Distance traveled: %s m (%s %%)\n'%(int(agentdists[agent]),int(100*agentdists[agent]/totalDist)))
                fout.write('Links made:        %s\n'%(agentlinkcount[agent]))
                fout.write('Fields completed:  %s\n'%(agentfieldcount[agent]))
                fout.write('Total experience:  %s AP (%s %%)\n'%(agentAP,int(100*agentAP/totalAP)))


                fout.write('----------------------------------\n')
                fout.write('Link  Agent Map# Link Origin\n')
                fout.write('                 Link Destination\n')
                fout.write('----------------------------------\n')
                #             1234112345612345 name
                
                last_link_from_other_agent = 0
                for i in xrange(self.m):
                    p,q = self.orderedEdges[i]
                    
                    linkagent = self.link2agent[i]

                    # Put a star by links that can be completed early since they complete no fields
                    numfields = len(self.a.edge[p][q]['fields'])
                    if numfields == 0:
                        star = '*'
#                        print '%s %s completes nothing'%(p,q)
                    else:
                        star = ''
#                        print '%s %s completes'%(p,q)
#                        for t in self.a.edge[p][q]['fields']:
#                            print '   ',t

                    if linkagent != agent:
                        fout.write(plainStr.format(\
                            i,\
                            star,\
                            linkagent+1,\
                            self.nslabel[p],\
                            self.names[p],\
                            self.nslabel[q],\
                            self.names[q]\
                        ))
                        last_link_from_other_agent = 1
                    else:
                        if last_link_from_other_agent:
                            fout.write('\n')
                        last_link_from_other_agent = 0
                        fout.write(hilitStr.format(\
                            i,\
                            star,\
                            linkagent+1,\
                            self.nslabel[p],\
                            self.names[p],\
                            self.nslabel[q],\
                            self.names[q]\
                        ))
示例#11
0
    def agentLinks(self):
        # Total distance traveled by each agent
        agentdists = np.zeros(self.nagents)
        # Total experience for each agent
        agentexps = np.zeros(self.nagents, dtype=int)

        for i in range(self.nagents):
            movie = self.movements[i]
            # first portal in first link
            curpos = self.a.node[self.orderedEdges[movie[0]][0]]['geo']
            for e in movie[1:]:
                p, q = self.orderedEdges[e]
                newpos = self.a.node[p]['geo']
                dist = geometry.sphereDist(curpos, newpos)
                agentdists[i] += dist
                curpos = newpos

                agentexps[i] += 313 + 1250 * len(self.a.edge[p][q]['fields'])

        # Different formatting for the agent's own links
        plainStr = '{0:4d}{1:1s} {2: 5d}{3:5d} {4:s}\n            {5:4d} {6:s}\n\n'
        hilitStr = '{0:4d}{1:1s} {2:_>5d}{3:5d} {4:s}\n            {5:4d} {6:s}\n\n'

        csv_file = open(self.outputDir + 'links_for_agents.csv', 'w')

        for agent in range(self.nagents):
            with open(self.outputDir+'links_for_agent_%s_of_%s.txt'\
                    %(agent+1,self.nagents),'w') as fout:

                fout.write('Complete link schedule issued to agent %s of %s\n'\
                    %(agent+1,self.nagents))

                totalTime = self.a.walktime + self.a.linktime + self.a.commtime

                fout.write('\nTotal time estimate: %s minutes\n\n' %
                           int(totalTime / 60 + .5))

                fout.write('Agent distance:   %s m\n' % int(agentdists[agent]))
                fout.write('Agent experience: %s AP\n' % (agentexps[agent]))

                fout.write('\nLinks marked with * can be made EARLY\n')

                fout.write('\nLink  Agent Map# Link Origin\n')
                fout.write('                 Link Destination\n')
                fout.write('-----------------------------------\n')
                #             1234112345612345 name
                csv_file.write(
                    'Link, Agent, MapNumOrigin, OriginName, MapNumDestination, DestinationName\n'
                )

                for i in xrange(self.m):
                    p, q = self.orderedEdges[i]

                    linkagent = self.link2agent[i]

                    # Put a star by links that can be completed early since they complete no fields
                    numfields = len(self.a.edge[p][q]['fields'])
                    if numfields == 0:
                        star = '*'
#                        print '%s %s completes nothing'%(p,q)
                    else:
                        star = ''
#                        print '%s %s completes'%(p,q)
#                        for t in self.a.edge[p][q]['fields']:
#                            print '   ',t

                    if linkagent != agent:
                        fout.write(plainStr.format(\
                            i,\
                            star,\
                            linkagent+1,\
                            self.nslabel[p],\
                            self.names[p],\
                            self.nslabel[q],\
                            self.names[q]\
                        ))
                    else:
                        fout.write(hilitStr.format(\
                            i,\
                            star,\
                            linkagent+1,\
                            self.nslabel[p],\
                            self.names[p],\
                            self.nslabel[q],\
                            self.names[q]\
                        ))
                    csv_file.write("{0}{1}, {2}, {3}, {4}, {5}, {6}\n".\
                                   format(i,star,linkagent+1,
                                          self.nslabel[p],self.names[p],
                                          self.nslabel[q],self.names[q]))
        csv_file.close()
示例#12
0
    def agentLinks(self):
        # Total distance traveled by each agent
        agentdists = np.zeros(self.nagents)
        # Total experience for each agent
        agentexps  = np.zeros(self.nagents,dtype=int)

        for i in range(self.nagents):
            movie = self.movements[i]
            # first portal in first link
            curpos = self.a.node[self.orderedEdges[movie[0]][0]]['geo']
            for e in movie[1:]:
                p,q = self.orderedEdges[e]
                newpos = self.a.node[p]['geo']
                dist = geometry.sphereDist(curpos,newpos)
                agentdists[i] += dist
                curpos = newpos

                agentexps[i] += 313 + 1250*len(self.a.edge[p][q]['fields'])

        # Different formatting for the agent's own links
        plainStr = '{:4d}{:1s} {: 5d}{:5d} {:s}\n            {:4d} {:s}\n\n'
        hilitStr = '{:4d}{:1s} {:_>5d}{:5d} {:s}\n            {:4d} {:s}\n\n'
        
        for agent in range(self.nagents):
            with open(self.outputDir+'links_for_agent_%s_of_%s.txt'\
                    %(agent+1,self.nagents),'w') as fout:

                fout.write('Complete link schedule issued to agent %s of %s\n'\
                    %(agent+1,self.nagents))
                
                fout.write('Total distance  : %s m\n'%int(agentdists[agent]))
                fout.write('Total experience: %s AP\n'%(agentexps[agent]))
                fout.write('Links marked with * can be made EARLY\n')

                fout.write('\nLink  Agent Map# Link Origin\n')
                fout.write('                 Link Destination\n')
                #             1234112345612345 name
                
                for i in xrange(self.m):
                    p,q = self.orderedEdges[i]
                    
                    linkagent = self.link2agent[i]

                    # Put a star by links that can be completed early since they complete no fields
                    numfields = len(self.a.edge[p][q]['fields'])
                    if numfields == 0:
                        star = '*'
#                        print '%s %s completes nothing'%(p,q)
                    else:
                        star = ''
#                        print '%s %s completes'%(p,q)
#                        for t in self.a.edge[p][q]['fields']:
#                            print '   ',t

                    if linkagent != agent:
                        fout.write(plainStr.format(\
                            i,\
                            star,\
                            linkagent+1,\
                            self.nslabel[p],\
                            self.names[p],\
                            self.nslabel[q],\
                            self.names[q]\
                        ))
                    else:
                        fout.write(hilitStr.format(\
                            i,\
                            star,\
                            linkagent+1,\
                            self.nslabel[p],\
                            self.names[p],\
                            self.nslabel[q],\
                            self.names[q]\
                        ))
示例#13
0
    def agentLinks(self):
        # Total distance traveled by each agent
        agentdists = np.zeros(self.nagents)
        # Total experience for each agent
        agentexps  = np.zeros(self.nagents,dtype=int)
        agentfields  = np.zeros(self.nagents,dtype=int)


        for i in range(self.nagents):
            movie = self.movements[i]
            # first portal in first link
            curpos = self.a.node[self.orderedEdges[movie[0]][0]]['geo']
            for e in movie[1:]:
                p,q = self.orderedEdges[e]
                newpos = self.a.node[p]['geo']
                dist = geometry.sphereDist(curpos,newpos)
                agentdists[i] += dist
                curpos = newpos

                agentexps[i] += 313 + 1250*len(self.a.edge[p][q]['fields'])
                agentfields[i] += len(self.a.edge[p][q]['fields'])

        # Different formatting for the agent's own links
        plainStr = '{0:4d}{1:1s} {2: 5d}{3:5d} {4:s}\n            {5:4d} {6:s}\n\n'
        hilitStr = '{0:4d}{1:1s} {2:_>5d}{3:5d} {4:s}\n            {5:4d} {6:s}\n\n'
        
        for agent in range(self.nagents):
            with open(self.outputDir+'links_for_agent_%s_of_%s.txt'\
                    %(agent+1,self.nagents),'w') as fout:

                fout.write('Complete link schedule issued to agent %s of %s\n'\
                    %(agent+1,self.nagents))
                
                totalTime = self.a.walktime+self.a.linktime+self.a.commtime

                fout.write('\nTotal time estimate: %s minutes\n\n'%int(totalTime/60+.5))

                fout.write('Agent distance:   %s m\n'%int(agentdists[agent]))
                fout.write('Agent experience: %s AP\n'%(agentexps[agent]))
                
                print 'Agent fields: %s\n'%(agentfields[agent])
                print 'Agent experience: %s AP\n'%(agentexps[agent])

                fout.write('\nLinks marked with * can be made EARLY\n')

                fout.write('\nLink  Agent Map# Link Origin\n')
                fout.write('                 Link Destination\n')
                fout.write('-----------------------------------\n')
                #             1234112345612345 name
               
                seqLinks = []
                earlyLinks = []
                
                for i in xrange(self.m):
                    p,q = self.orderedEdges[i]
                    
                    linkagent = self.link2agent[i]

                    # Put a star by links that can be completed early since they complete no fields
                    numfields = len(self.a.edge[p][q]['fields'])
                    if numfields == 0:
                        star = '*'
#                        print '%s %s completes nothing'%(p,q)
                    else:
                        star = ''
#                        print '%s %s completes'%(p,q)
#                        for t in self.a.edge[p][q]['fields']:
#                            print '   ',t

                    # print star, i, self.names[p], "-->", self.names[q]
                    if(star == '*'):
                        earlyLinks.append( [i, p, q] )
                    else:
                        seqLinks.append( [i, self.names[p], self.names[q]] )

                    if linkagent != agent:
                        fout.write(plainStr.format(\
                            i,\
                            star,\
                            linkagent+1,\
                            self.nslabel[p],\
                            self.names[p],\
                            self.nslabel[q],\
                            self.names[q]\
                        ))
                    else:
                        fout.write(hilitStr.format(\
                            i,\
                            star,\
                            linkagent+1,\
                            self.nslabel[p],\
                            self.names[p],\
                            self.nslabel[q],\
                            self.names[q]\
                        ))

                earlyPointsToOpt = []
                for i,point in enumerate(earlyLinks):
                    p,q = point[1], point[2]
                    x,y = self.xy[p][0], self.xy[p][1]
                    earlyPointsToOpt.append( [i, float(x), float(y)] )

                # print earlyPointsToOpt
                print 'Agent distance:   %s m\n'%int(agentdists[agent])



                costs, earlyPointsOptimized = tsp.simAnneal(earlyPointsToOpt) # NJA XXX
                for point in earlyPointsOptimized:
                    i,p,q = earlyLinks[point[0]]
                    
                    print '*', i, self.names[p], "-->", self.names[q]

                for link in seqLinks:
                    print ' ', link[0], link[1], "-->", link[2]
示例#14
0
def improveEdgeOrderMore(a):
    '''
    A greedy algorithm to reduce the path length.
    Moves edges earlier or later, if they can be moved (dependencies are
    done in the proper order) and the move reduces the total length of the
    path.
    The algorithm tries to move 1 to 5 edges at the same time as a block
    to improve upon certain types of local optima.
    '''

    m = a.size()
    # If link i is e then orderedEdges[i]=e
    orderedEdges = [-1]*m

    geo = np.array([ a.node[i]['geo'] for i in xrange(a.order())])
    d = geometry.sphereDist(geo,geo)

    def pathLength(d, edges):
        startps = [edges[i][0] for i in xrange(len(edges))]
        return np.sum(d[startps[:-1], startps[1:]])

    def dependsOn(subjects, objects):
        '''
        Returns True, if an edge inside 'objects' should be made before
        one (or more) of the edges inside 'subjects'
        '''
        for p,q in subjects:
            depends = a.edge[p][q]['depends']
            for u,v in objects:
                if depends.count((u,v,)) + depends.count(u) > 0:
                    return True

        return False


    def possiblePlaces(j, block):
        '''
        A generator returning the possible places of the given
        block of edges within the complete edge sequence.
        The current position (j) is not returned.
        '''
        pos = j
        # smaller index means made earlier
        while pos > 0 and not dependsOn(block, [orderedEdges[pos-1]]):
            pos -= 1
            yield pos

        pos = j
        bsize = len(block)
        n = len(orderedEdges) - bsize + 1
        # bigger index means made later
        while pos < n-1 and not dependsOn([orderedEdges[pos+bsize]], block):
            pos += 1
            yield pos


    for p,q in a.edges_iter():
        orderedEdges[a.edge[p][q]['order']] = (p,q)

    origLength = pathLength(d, orderedEdges)
    bestLength = origLength

    cont = True
    while cont:
        cont = False
        for j in xrange(m):
            best = j
            bestPath = orderedEdges

            # max block size is 5 (6-1); chosen arbitrarily
            for block in xrange(1, 6):
                moving = orderedEdges[j:j+block]
                # if the first and last link in the block are from the same portal
                # and the link before or after the block is also from that portal,
                # moving the block will not improve the path length, and thus there
                # is no point in trying
                if moving[0][0] == moving[-1][0] and (
                        (j > 0 and moving[0][0] == orderedEdges[j-1][0]) or
                        (j + block < m and moving[0][0] == orderedEdges[j+block][0])):
                    filter = [] # skips the loop below
                else:
                    filter = True # do the loop

                for possible in filter and possiblePlaces(j, moving):
                    if possible < j:
                        # Move the links to be at an earlier index
                        path = orderedEdges[   :possible] +\
                                    moving +\
                                    orderedEdges[possible  :j] +\
                                    orderedEdges[j+block: ]
                    else:
                        # Move to a later position
                        path = orderedEdges[   :j] +\
                                    orderedEdges[j+block: possible+block] +\
                                    moving +\
                                    orderedEdges[possible+block  :]

                    length = pathLength(d,path)

                    if bestLength - length > 1e-10:
                        #print("Improved by %f meters in index %d (from %d, block %d)" % (bestLength-length, possible, best, block))
                        best = possible
                        bestLength = length
                        bestPath = path

            if best != j:
                #print("New order (%d -> %d): %s" % (j, best, bestPath))
                orderedEdges = bestPath
                cont = True

    length = pathLength(d, orderedEdges)
    print
    #print("Length reduction: original = %d, improved = %d, change = %d meters" % (origLength, length, length-origLength))

    for i in xrange(m):
        p,q = orderedEdges[i]
        a.edge[p][q]['order'] = i