示例#1
0
    def localsearch(self):
        '''
        '''
        swapping = True
        swap_iteration = 0
        total_moves = 0

        sln = self.solncolumn
        ids = np.arange(len(sln))

        k = int(self.nregions)
        changed_regions = [1] * k
        nr = range(k)
        while swapping:
            moves_made = 0
            regionIds = [r+1 for r in nr if changed_regions[r]]
            shuffle(regionIds)
            changed_regions = [0] * k
            
            for seed in regionIds:
                local_swapping = True
                local_attempts = 0
                while local_swapping:
                    local_moves = 0
                    members = ids[sln == seed].tolist()
                    neighbors = set()

                    for member in members:
                        neighbors |= set(self.w.neighbors[member])
                   
                    neighbors -= set(members)
                    candidates = []

                    for neighbor in neighbors:
                        rid = sln[neighbor]
                        block = ids[sln == rid].tolist()
                        if len(block) <= self.floor:
                            continue
                        if check_contiguity(self.w, block, neighbor):
                            candidates.append(neighbor)
                        
                    if not candidates:
                        local_swapping = False
                    else:
                        nc = len(candidates)
                        best = None
                        cv = 0.0  #TODO Needs to be a high positive number with an aspiration func
                        for area in candidates:
                            current_internal = members
                            rid = sln[area]
                            current_outter = ids[sln == rid].tolist()
                            currentwss = self.objective_func([current_internal, current_outter])
                            new_internal = copy.copy(current_internal)
                            new_outter = copy.copy(current_outter)
                            new_internal.append(area)
                            new_outter.remove(area)
                            newwss = self.objective_func([new_internal, new_outter])
                            change = newwss - currentwss
                            old_region = int(sln[area])
                            if (area, old_region) in self.tabulist:
                                continue
                            elif change < cv:
                                best = area
                                cv = change
                            else:
                                pass
                                #Aspiration function here

                        if best:
                            area = best
                            moves_made += 1
                            old_region = int(sln[area])
                            #changed_regions is 0 based
                            changed_regions[seed - 1] = 1
                            changed_regions[old_region - 1] = 1
                            #print "Moving area: {} from {} to {}".format(area, old_region, seed)
                            sln[area] = seed 
                            self.tabulist.appendleft((area, old_region))
                            self.failures = 0
                        else:
                            self.failures += 1
                            local_swapping = False
                            #swapping = False

                if self.failures >= self.maxfailures:
                    swapping = False
            if moves_made == 0:
                swapping = False

        new_obj = self.objective_func(sln=sln)
        diversify = False
        #print sln.reshape(8,8), globalobj
        with self.lock:
            current_obj_vector = self.solnspace[:,0]
            if new_obj < current_obj_vector.all():
                sortedidx = np.argsort(current_obj_vector)[::-1]
                idx = sortedidx[0:self.intensificationsize]
                for i in idx:
                    self.solnspace[i][1:] = sln
                    self.solnspace[i][0] = new_obj
            elif new_obj < current_obj_vector[self.index]:
                self.solnspace[self.index][1:] = sln
                self.solnspace[self.index][0] = new_obj
            else:
                diversify = True
        
        if diversify:
            pass

        #Manual 1 iteration breaker
        #self.maxiterations = 0
        return
    def build_contig_regions(self, num_regions, cardinality, w,
                                maxiter, compact, max_swaps):
        if compact:
            grow_region = self.grow_compact
        else:
            grow_region = self.grow_free
        iter = 0
        while iter < maxiter:

            # regionalization setup
            regions = []
            size_pre = 0
            counter = -1
            area2region = {}
            self.feasible = False
            swap_count = 0
            cards = copy.copy(cardinality)
            cards.sort()  # try to build largest regions first (pop from end of list)
            candidates = copy.copy(self.ids)  # these are already shuffled

            # begin building regions
            while candidates and swap_count < max_swaps:
                # setup test to determine if swapping is needed
                if size_pre == len(regions):
                    counter += 1
                else:
                    counter = 0
                    size_pre = len(regions)
                # test if swapping is needed
                if counter == len(candidates):

                    # start swapping
                    # swapping simply changes the candidate list
                    swap_in = None   # area to become new candidate
                    while swap_in is None:  # PEP8 E711
                        swap_count += 1
                        swap_out = candidates.pop(0)  # area to remove from candidates
                        swap_neighs = copy.copy(w.neighbors[swap_out])
                        swap_neighs = list(np.random.permutation(swap_neighs))
                        # select area to add to candidates (i.e. remove from an existing region)
                        for i in swap_neighs:
                            if i not in candidates:
                                join = i  # area linking swap_in to swap_out
                                swap_index = area2region[join]
                                swap_region = regions[swap_index]
                                swap_region = list(np.random.permutation(swap_region))
                                for j in swap_region:
                                    # test to ensure region connectivity after removing area
                                    swap_region_test = swap_region[:] + [swap_out]
                                    if check_contiguity(w, swap_region_test, j):
                                        swap_in = j
                                        break
                            if swap_in is not None:  # PEP8 E711
                                break
                        else:
                            candidates.append(swap_out)
                    # swapping cleanup
                    regions[swap_index].remove(swap_in)
                    regions[swap_index].append(swap_out)
                    area2region.pop(swap_in)
                    area2region[swap_out] = swap_index
                    candidates.append(swap_in)
                    counter = 0

                # setup to build a single region
                building = True
                seed = candidates.pop(0)
                region = [seed]
                potential = [i for i in w.neighbors[seed] if i in candidates]
                test_card = cards.pop()

                # begin building single region
                while building and len(region) < test_card:
                    if potential:
                        region, candidates, potential = grow_region(
                            w, test_card,
                                        region, candidates, potential)
                    else:
                        # not enough potential neighbors to reach test_card size
                        building = False
                        cards.append(test_card)
                        if len(region) in cards:
                            # constructed region matches another candidate region size
                            cards.remove(len(region))
                        else:
                            # constructed region doesn't match a candidate region size
                            candidates.extend(region)
                            region = []

                # cleanup when successful region built
                if region:
                    regions.append(region)
                    region_index = len(regions) - 1
                    for i in region:
                        area2region[i] = region_index   # area2region needed for swapping
            # handling of regionalization result
            if len(regions) < num_regions:
                # regionalization failed
                self.ids = list(np.random.permutation(self.ids))
                regions = []
                iter += 1
            else:
                # regionalization successful
                self.feasible = True
                iter = maxiter
        self.regions = regions