Ejemplo n.º 1
0
    def test_grow_exogenous_regions_queen(self):
        """Number of regions is exogenous, aka given (Wqueen)"""
        am = AreaManager(self.Wqueen, self.Y)

        for regions in xrange(1, max_num_regions):
            rm = RegionMaker(am, pRegions=regions)
            self.assertEqual(regions, len(rm.region2Area))
            self.assertTrue(am.checkFeasibility(rm.returnRegions()))
Ejemplo n.º 2
0
    def test_grow_exogenous_regions_queen(self):
        """Number of regions is exogenous, aka given (Wqueen)"""
        am = AreaManager(self.Wqueen, self.Y)

        for regions in xrange(1, max_num_regions):
            rm = RegionMaker(am, pRegions=regions)
            self.assertEqual(regions, len(rm.region2Area))
            self.assertTrue(am.checkFeasibility(rm.returnRegions()))
Ejemplo n.º 3
0
 def test_impossible_solution_configuration_on_queen(self):
     """
     Using the Wqueen, test for an impossible region assignment
     """
     """
     Impossible solution:
     0110
     1010
     """
     possible_solution = [0, 1, 1, 0, 1, 0, 1, 0]
     am = AreaManager(self.Wqueen, self.Y)
     result = am.checkFeasibility(possible_solution)
     self.assertFalse(result)
Ejemplo n.º 4
0
 def test_possible_solution_configuration_on_rook(self):
     """
     Using the Wrook, test for a possible region assignment
     """
     """
     Possible solution:
     0112
     0002
     """
     possible_solution = [0, 1, 1, 2, 0, 0, 0, 2]
     am = AreaManager(self.Wrook, self.Y)
     result = am.checkFeasibility(possible_solution)
     self.assertTrue(result)
Ejemplo n.º 5
0
 def test_impossible_solution_configuration_on_rook(self):
     """
     Using the Wrook, test for a impossible region assignment.
     """
     """
     Possible solution:
     0011
     0101
     """
     possible_solution = [0, 0, 1, 1, 0, 1, 0, 1]
     am = AreaManager(self.Wrook, self.Y)
     result = am.checkFeasibility(possible_solution)
     self.assertFalse(result)
Ejemplo n.º 6
0
 def test_possible_solution_configuration_on_rook_w_one_region(self):
     """
     Using the Wrook, test for a possible region assignment where only
     one region exists.
     """
     """
     Possible solution:
     0000
     0000
     """
     possible_solution = [0, 0, 0, 0, 0, 0, 0, 0]
     am = AreaManager(self.Wrook, self.Y)
     result = am.checkFeasibility(possible_solution)
     self.assertTrue(result)
Ejemplo n.º 7
0
    def test_randomness_on_same_process(self):
        """This tests that running multiple instances of the region maker
        on the same script (process) will """
        am = AreaManager(self.Wrook, self.Y)
        regions = []
        for _reg in xrange(1, max_num_regions):
            rm = RegionMaker(am, pRegions=max_num_regions)
            self.assertEqual(max_num_regions, len(rm.region2Area))
            self.assertTrue(am.checkFeasibility(rm.returnRegions()))
            regions.append(rm.returnRegions())

        for regioni in xrange(len(regions) - 1):
            for regionj in xrange(regioni + 1, len(regions)):
                self.assertNotEqual(regions[regioni], regions[regionj])
Ejemplo n.º 8
0
    def test_randomness_on_same_process(self):
        """This tests that running multiple instances of the region maker
        on the same script (process) will """
        am = AreaManager(self.Wrook, self.Y)
        regions = []
        for _reg in xrange(1, max_num_regions):
            rm = RegionMaker(am, pRegions=max_num_regions)
            self.assertEqual(max_num_regions, len(rm.region2Area))
            self.assertTrue(am.checkFeasibility(rm.returnRegions()))
            regions.append(rm.returnRegions())

        for regioni in xrange(len(regions) - 1):
            for regionj in xrange(regioni + 1, len(regions)):
                self.assertNotEqual(regions[regioni], regions[regionj])
Ejemplo n.º 9
0
 def test_possible_solution_configuration_on_rook_w_empty_region(self):
     """
     Using the Wrook, test for a impossible region assignment where one
     area is missing.
     """
     """
     Possible solution:
     0022
     0202
     """
     possible_solution = [0, 0, 2, 2, 0, 2, 0, 2]
     am = AreaManager(self.Wrook, self.Y)
     result = am.checkFeasibility(possible_solution)
     self.assertFalse(result)
Ejemplo n.º 10
0
    def test_azp_gives_at_least_same_obj_func(self):
        instance = self.map_instance
        aream = AreaManager(instance.Wrook, instance.Y)
        rm = RegionMaker(aream, into_regions)

        ob_before = rm.objInfo
        rm.AZPImproving()
        ob_after = rm.objInfo

        self.assertTrue(ob_before >= ob_after)
Ejemplo n.º 11
0
    def test_false_possible_queen_region_movement(self):
        """
        An infeasible region removal yields an uncontiguos region. Using WQueen.
        """
        am = AreaManager(self.layer.Wqueen, self.layer.Y)
        rm = RegionMaker(am, initialSolution = self.possible_queen_solution)

        """ Removing area 47 from region 1 leaves area 58 as an island"""
        feasible = rm.checkFeasibility(1, 47, rm.region2Area)

        assert not feasible
Ejemplo n.º 12
0
    def test_true_possible_rook_region_movement(self):
        """
        A possible region change is in fact a feasible movement using rook contiguity.
        """
        am = AreaManager(self.layer.Wrook, self.layer.Y)
        rm = RegionMaker(am, initialSolution = self.possible_rook_solution)

        """ Removing area 29 from region 1 is an allowed movement"""
        feasible = rm.checkFeasibility(1, 29, rm.region2Area)

        assert feasible
Ejemplo n.º 13
0
    def test_false_possible_rook_region_movement(self):
        """
        Removing an area that breaks the contiguity constraint.
        """
        am = AreaManager(self.layer.Wrook, self.layer.Y)
        rm = RegionMaker(am, initialSolution = self.possible_rook_solution)

        """ Removing area 47 from region 1 leaves area 48 as an island"""
        feasible = rm.checkFeasibility(1, 47, rm.region2Area)

        assert not feasible
Ejemplo n.º 14
0
    def test_true_possible_queen_region_movement(self):
        """
        A region removal yields in fact a feasible solution using queen contiguity.
        """
        am = AreaManager(self.layer.Wqueen, self.layer.Y)
        rm = RegionMaker(am, initialSolution = self.possible_queen_solution)

        """ Removing area 49 from region 0 leaves areas attached by a point"""
        feasible = rm.checkFeasibility(0, 49, rm.region2Area)

        assert feasible
Ejemplo n.º 15
0
    def test_azprtabu_gives_at_least_same_obj_func(self):
        instance = self.map_instance
        aream = AreaManager(instance.Wrook, instance.Y)
        rm = RegionMaker(aream, into_regions)

        convTabu = len(instance.Y) / into_regions

        ob_before = rm.objInfo
        rm.reactiveTabuMove(convTabu)
        ob_after = rm.objInfo

        self.assertTrue(ob_before >= ob_after)
Ejemplo n.º 16
0
    def test_azptabu_gives_at_least_same_obj_func(self):
        instance = self.map_instance
        aream = AreaManager(instance.Wrook, instance.Y)
        rm = RegionMaker(aream, into_regions)

        convTabu = max(10, len(instance.Y) / into_regions)
        tabuLength = 10

        ob_before = rm.objInfo
        rm.AZPTabuMove(tabuLength=tabuLength, convTabu=convTabu)
        ob_after = rm.objInfo

        self.assertTrue(ob_before >= ob_after)
Ejemplo n.º 17
0
    def test_azpsa_gives_at_least_same_obj_func(self):
        instance = self.map_instance

        aream = AreaManager(instance.Wrook, instance.Y)
        rm = RegionMaker(aream, into_regions)

        alpha = 0.85
        maxiterations = 3

        ob_before = rm.objInfo
        rm.AZPSA(alpha, maxiterations)
        ob_after = rm.objInfo
        self.assertTrue(ob_before >= ob_after)
Ejemplo n.º 18
0
def _final_regions_are_contiguous_in_instance(instance):
    exp_name = instance.fieldNames[-1]
    clustering_results = instance.outputCluster[exp_name]
    final_region_assignment = clustering_results['r2a']
    am = AreaManager(instance.Wrook, instance.Y)
    return am.checkFeasibility(final_region_assignment)
Ejemplo n.º 19
0
    def test_grow_endogenous_range_regions(self):
        """Number of regions is endogenous with a range value"""
        am = AreaManager(self.Wqueen, self.Y)
        rm = RegionMaker(am)

        self.assertIsNotNone(rm)
Ejemplo n.º 20
0
    def test_grow_exogenous_regions_with_initial_solution(self):
        """Number of regions is exogenous, aka given, and an initial solution"""
        am = AreaManager(self.Wqueen, self.Y)
        rm = RegionMaker(am)

        self.assertIsNotNone(rm)
Ejemplo n.º 21
0
def _final_regions_are_contiguous_in_instance(instance):
    exp_name = instance.fieldNames[-1]
    clustering_results = instance.outputCluster[exp_name]
    final_region_assignment = clustering_results['r2a']
    am = AreaManager(instance.Wrook, instance.Y)
    return am.checkFeasibility(final_region_assignment)
Ejemplo n.º 22
0
def execArisel(y,
               w,
               pRegions,
               inits=3,
               initialSolution=[],
               convTabu=0,
               tabuLength=10):
    """Automatic Rationalization with Initial Seed Location

    ARiSeL, proposed by [Duque_Church2004]_ , aggregates N areas into P
    spatially contiguous regions while minimizing intra-regional heterogeneity
    (measured as the within-cluster sum of squares from each area to the
    attribute centroid of its cluster). This algorithm is a modification of
    Openshaw's AZP-tabu [Openshaw_Rao1995]_. In ARISeL the construction of a
    initial feasible solution is repeated several times (inits) before
    running Tabu Search algorithm [Glover1977]_.


    Duque and Church argue that:


        - constructing and initial feasible solution is computationally less
        expensive than performing local search.


        - local search by moving bordering areas between region do not allow
        an extensive search in the solution space and it is computationally
        expensive.


    Based on those two ideas, the authors propose to generate as many
    different initial feasible solutions and run Tabu search on the best
    initial solution obtained so far.


    The initial solution follows a "growing regions" strategy. It starts with
    a initial set of seeds (as many seed as regions) selected using the
    K-means++ algorithm. From those seeds, other neighbouring areas are
    assigned to its closest (in attribute space) growing region. This strategy
    has proven better results. ::

        Layer.cluster('arisel', vars, regions, <wType>, <std>, <inits>,
        <initialSolution>, <convTabu>, <tabuLength>,
        <dissolve>, <dataOperations>)

    :keyword vars: Area attribute(s) (e.g. ['SAR1','SAR2'])
    :type vars: list
    :keyword regions: Number of regions
    :type regions: integer
    :keyword wType: Type of first-order contiguity-based spatial matrix: 'rook'
    or 'queen'. Default value wType = 'rook'.
    :type wType: string
    :keyword std: If = 1, then the variables will be standardized.
    :type std: binary
    :keyword inits: number of initial feasible solutions to be constructed
    before applying Tabu Search.
    :type inits: integer. Default value inits = 5.
    :keyword initialSolution: List with a initial solution vector. It is useful
    when the user wants a solution that is not very different from a preexisting
    solution (e.g. municipalities,districts, etc.). Note that the number of
    regions will be the same as the number of regions in the initial feasible
    solution (regardless the value you assign to parameter "regions").
    IMPORTANT: make sure you are entering a feasible solution and according to
    the W matrix you selected, otherwise the algorithm will not converge.
    :type initialSolution: list
    :keyword convTabu: Stop the search after convTabu nonimproving moves
    (nonimproving moves are those moves that do not improve the current
    solution.
    Note that "improving moves" are different to "aspirational moves").
    If convTabu=0 the algorithm will stop after Int(M/N) nonimproving moves.
    Default value convTabu = 0.
    :type convTabu: integer
    :keyword tabuLength: Number of times a reverse move is prohibited. Default
    value *tabuLength = 10*.
    :type tabuLength: integer
    :keyword dissolve: If = 1, then you will get a "child" instance of the layer
    that contains the new regions. Default value *dissolve = 0*.  **Note:**.
    Each child layer is saved in the attribute *layer.results*.  The first
    algorithm that you run with *dissolve=1* will have a child layer in
    *layer.results[0]*; the second algorithm that you run with *dissolve=1* will
    be in *layer.results[1]*, and so on. You can export a child as a shapefile
    with *layer.result[<1,2,3..>].exportArcData('filename')*
    :type dissolve: binary
    :keyword dataOperations: Dictionary which maps a variable to a list of
    operations to run on it. The dissolved layer will contains in it's data all
    the variables specified in this dictionary. Be sure to check the input
    layer's fieldNames before use this utility.
    :type dataOperations: dictionary

    The dictionary structure must be as showed bellow.

    >>> X = {}
    >>> X[variableName1] = [function1, function2,....]
    >>> X[variableName2] = [function1, function2,....]

    Where functions are strings wich represents the name of the
    functions to be used on the given variableName. Functions
    could be,'sum','mean','min','max','meanDesv','stdDesv','med',
    'mode','range','first','last','numberOfAreas. By deffault just
    ID variable is added to the dissolved map.

    """
    lenY = len(y)
    start = 0.0
    time2 = 0.0

    print("Running original Arisel algorithm")
    print("Number of areas: ", lenY)
    if initialSolution:
        print("Number of regions: ", len(np.unique(initialSolution)))
        pRegions = len(set(initialSolution))
    else:
        print("Number of regions: ", pRegions)
    if pRegions >= lenY:
        message = "\n WARNING: You are aggregating "+str(lenY)+" into"+\
        str(pRegions)+" regions!!. The number of regions must be an integer"+\
        " number lower than the number of areas being aggregated"
        raise Exception(message)

    if convTabu <= 0:
        convTabu = old_div(lenY,
                           pRegions)  #   convTabu = 230*numpy.sqrt(pRegions)
    distanceType = "EuclideanSquared"
    distanceStat = "Centroid"
    objectiveFunctionType = "SS"
    selectionType = "Minimum"
    am = AreaManager(w, y, distanceType)
    extendedMemory = ExtendedMemory()

    pool = Pool(processes=cpu_count())
    procs = []

    start = tm.time()
    for dummy in range(inits):
        ans = pool.apply_async(constructPossible, [
            am, pRegions, initialSolution, distanceType, distanceStat,
            selectionType, objectiveFunctionType
        ])
        procs.append(ans)

    results = []
    for p in procs:
        results.append(p.get())

    tmp_ans = extendedMemory
    for rm in results:
        if rm.objInfo < tmp_ans.objInfo:
            tmp_ans = rm
    rm = tmp_ans
    extendedMemory.updateExtendedMemory(rm)

    rm.recoverFromExtendedMemory(extendedMemory)
    print("INITIAL SOLUTION: ", rm.returnRegions(), "\nINITIAL OF: ",
          rm.objInfo)
    rm.tabuMove(tabuLength=tabuLength, convTabu=convTabu)
    time2 = tm.time() - start
    Sol = rm.regions
    Of = rm.objInfo
    print("FINAL SOLUTION: ", Sol, "\nFINAL OF: ", Of)
    output = {
        "objectiveFunction": Of,
        "runningTime": time2,
        "algorithm": "arisel",
        "regions": len(Sol),
        "r2a": Sol,
        "distanceType": distanceType,
        "distanceStat": distanceStat,
        "selectionType": selectionType,
        "ObjectiveFuncionType": objectiveFunctionType
    }
    return output