[GRASS-SVN] r60823 - in grass-addons/grass7/raster/r.agent: . libagent tests

svn_grass at osgeo.org svn_grass at osgeo.org
Fri Jun 13 13:52:10 PDT 2014


Author: mic
Date: 2014-06-13 13:52:10 -0700 (Fri, 13 Jun 2014)
New Revision: 60823

Modified:
   grass-addons/grass7/raster/r.agent/libagent/ant.py
   grass-addons/grass7/raster/r.agent/libagent/anthill.py
   grass-addons/grass7/raster/r.agent/r.agent.aco
   grass-addons/grass7/raster/r.agent/tests/test_ant.py
Log:
add option to consider cost layer values

Modified: grass-addons/grass7/raster/r.agent/libagent/ant.py
===================================================================
--- grass-addons/grass7/raster/r.agent/libagent/ant.py	2014-06-13 17:32:50 UTC (rev 60822)
+++ grass-addons/grass7/raster/r.agent/libagent/ant.py	2014-06-13 20:52:10 UTC (rev 60823)
@@ -12,6 +12,7 @@
 from random import uniform #, choice, randint
 import agent
 import error
+#from grass.script import core as grass
 
 class Ant(agent.Agent):
     """Implementation of an Ant Agent for an Anthill, an ACO kind of World."""
@@ -40,7 +41,12 @@
         if self.world.decisionbase == "random":
             # TODO: for now like 'else'..
             self.decide = self.randomposition
+        if self.world.decisionbase == "marked":
+            self.decide = self.markedposition
+        if self.world.decisionbase == "costlymarked":
+            self.decide = self.costlymarkedposition
         else:
+            #standard is marked for the moment..
             self.decide = self.markedposition
         if self.world.evaluationbase == "standard":
             self.evaluate = self.check
@@ -49,8 +55,8 @@
 
     def check(self, positions):
         """
-        Check a list of positions for a position with a value of interest (<0)
-        in the penalty layer, if such a position is really found, the ant
+        Evaluate a list of positions for a position with a value of interest
+        (<0) in the penalty layer, if such a position really is found, the ant
         happily turns back home by setting the next step to it's last.
         If it was only the homeposition, the ant removes it from the list and
         goes on.
@@ -79,6 +85,45 @@
                     return True
         return False
 
+    def costlymarkedposition(self, positions):
+        """
+        Avoiding high values on the costsurface, combined with the
+        marked pheromone values on a certain layer combined with a random
+        value, pick a posiiton out of a list of positions.
+        @param positions list of possible positions
+        @return position the decision for a position
+        """
+        # sort out illegal positions
+        copyofpositions = positions[:]
+        for i in xrange(0, len(positions)):
+            p = copyofpositions[i]
+            penalty = self.world.getpenalty(p)
+            if (( penalty < self.world.minpenalty ) or
+                ( penalty > self.world.maxpenalty )):
+                positions.remove(p)
+        if not positions:
+            # die as there is nowwhere to go to
+            self.snuffit()
+            # make sure to not walk again..
+            return [0,0,99,99]
+
+        position = positions[0]
+        # compare the remaining
+        tmpval = - self.world.getpenalty(position) * self.world.costweight +\
+                self.world.getpheromone(position) * self.world.pheroweight +\
+                uniform(self.world.minrandom, self.world.maxrandom) *\
+                self.world.randomweight
+        for i in xrange(1, len(positions)):
+            p = positions[i]
+            newval = - self.world.getpenalty(p) * self.world.costweight +\
+                    self.world.getpheromone(p) * self.world.pheroweight +\
+                    uniform(self.world.minrandom, self.world.maxrandom) *\
+                    self.world.randomweight
+            if ( newval > tmpval ):
+                position = p
+                tmpval = newval
+        return position
+
     def markedposition(self, positions):
         """
         Based on the value on a certain layer combined with a random
@@ -145,7 +190,7 @@
         @return boolean whether still alive
         """
         # we are all only getting older..
-        if self.age() == False:
+        if not self.age():
             # exit if we died in the meantime..
             return False
         # past this point we must have decided yet where to go to next..

Modified: grass-addons/grass7/raster/r.agent/libagent/anthill.py
===================================================================
--- grass-addons/grass7/raster/r.agent/libagent/anthill.py	2014-06-13 17:32:50 UTC (rev 60822)
+++ grass-addons/grass7/raster/r.agent/libagent/anthill.py	2014-06-13 20:52:10 UTC (rev 60823)
@@ -51,7 +51,8 @@
         self.sites = []
         # default values
         ## let ant die if penalty grows too big
-        self.maxpenalty = 0
+        self.maxpenalty = 99999
+        self.minpenalty = 0
         ## max/min possible value of pheromone intensity
         self.maxpheromone = maxsize
         self.minpheromone = 0
@@ -75,7 +76,7 @@
         ## maximum number of ants on the playground
         self.maxants = self.playground.gettotalcount()
         ## the ants ttl will be set by user or based on playground size
-        self.antslife = self.playground.getdiagonalcount()
+        self.antslife = 2 * self.playground.getdiagonalcount()
         self.decisionbase = "standard"
         self.evaluationbase = "standard"
         self.numberofpaths = 0

Modified: grass-addons/grass7/raster/r.agent/r.agent.aco
===================================================================
--- grass-addons/grass7/raster/r.agent/r.agent.aco	2014-06-13 17:32:50 UTC (rev 60822)
+++ grass-addons/grass7/raster/r.agent/r.agent.aco	2014-06-13 20:52:10 UTC (rev 60823)
@@ -13,6 +13,8 @@
               for details.
 """
 
+##TODO it is time to make this all multithreaded..
+
 #%Module
 #% description: Agents wander around on the terrain, marking paths to new locations.
 #%End
@@ -90,16 +92,16 @@
 #% key: highcostlimit
 #% type: integer
 #% gisprompt: number
-#% description: Penalty values above this point an ant considers as illegal/bogus
+#% description: Penalty values above this point an ant considers as illegal/bogus when in 'costlymarked' modus
 #% options: 0-<max integer on system would make sense>
 #% required : no
 #%end
-#%option                                                       
+#%option
 #% key: lowcostlimit
 #% type: integer
 #% gisprompt: number
-#% description: Penalty values below this point an ant considers as illegal/bogus
-#% options: <min integer on system would make sense>-0
+#% description: Penalty values below this point an ant considers as illegal/bogus when in 'costlymarked' modus
+#% options: -99999-99999
 #% required : no
 #%end
 #%option
@@ -164,7 +166,7 @@
 #% gisprompt: algorithm
 #% description: Algorithm used for walking step
 #% answer: standard
-#% options: standard,random,test
+#% options: standard,marked,costlymarked,random,test
 #% required : yes
 #%end
 #%option
@@ -190,7 +192,7 @@
 #% gisprompt: number
 #% description: How is the pheromone value (P) weighted when walking (p*P:r*R:c*C)
 #% answer: 1
-#% options: 0-999
+#% options: 0-99999
 #% required : yes
 #%end
 #%option
@@ -199,7 +201,7 @@
 #% gisprompt: number
 #% description: How is the random value (R) weighted when walking (p*P:r*R:c*C)
 #% answer: 1
-#% options: 0-999
+#% options: 0-99999
 #% required : yes
 #%end
 #%option
@@ -208,7 +210,7 @@
 #% gisprompt: number
 #% description: How is the penalty value (C) weighted when walking (p*P:r*R:c*C)
 #% answer: 0
-#% options: 0-999
+#% options: 0-99999
 #% required : yes
 #%end
 
@@ -323,6 +325,10 @@
         elif flags['s'] and options['outrounds'] > 0:
             world.addsequencenumber = True
 
+        if options['lowcostlimit']:
+            world.minpenalty = int(options['lowcostlimit'])
+        if options['highcostlimit']:
+            world.maxpenalty = int(options['highcostlimit'])
         if options['maxpheromone']:
             world.maxpheromone = int(options['maxpheromone'])
             world.maxrandom = world.maxpheromone

Modified: grass-addons/grass7/raster/r.agent/tests/test_ant.py
===================================================================
--- grass-addons/grass7/raster/r.agent/tests/test_ant.py	2014-06-13 17:32:50 UTC (rev 60822)
+++ grass-addons/grass7/raster/r.agent/tests/test_ant.py	2014-06-13 20:52:10 UTC (rev 60823)
@@ -35,16 +35,37 @@
 
     def test_markedpositions(self):
         self.world.pheroweight = 1
+        # we do not explicitly test random here..
         self.world.randomweight = 1
+        self.world.minrandom = 0
+        self.world.maxrandom = 1
         positions = [[0,0,0,0],[1,1,3,0]]
         self.pg.layers[anthill.Anthill.RESULT][0][0] = 0
         self.pg.layers[anthill.Anthill.RESULT][1][1] = 999
-        self.world.minrandom = 0
-        self.world.maxrandom = 1
         p = self.agent.markedposition(positions)
         self.assertEqual([1,1], p[:2])
-        # we do not test random here..
 
+    def test_costlymarkedpositions(self):
+        self.world.costweight = 1
+        # we do not test random or pheromone at all here..
+        self.world.pheroweight = 0
+        self.world.randomweight = 0
+        positions = [[0,0,0,0],[1,1,3,0]]
+        self.pg.layers[anthill.Anthill.COST][0][0] = 0
+        self.pg.layers[anthill.Anthill.COST][1][1] = 2
+        p = self.agent.costlymarkedposition(positions)
+        self.assertEqual([0,0], p[:2])
+        # test if min/max works
+        self.world.minpenalty = 1
+        self.world.maxpenalty = 3
+        p = self.agent.costlymarkedposition(positions)
+        self.assertEqual([1,1], p[:2])
+        # now test if the ant is really dying if min/max wrong
+        self.world.minpenalty = 3
+        self.assertLess(p[3],1)
+        p = self.agent.costlymarkedposition(positions)
+        self.assertGreater(p[3],1)
+
     def test_choose(self):
         # every second step should be a goal..
         self.assertEqual(0, self.world.numberofpaths)



More information about the grass-commit mailing list