예제 #1
0
파일: traffic.py 프로젝트: Kihy/IDS2-CIC
    def compute_position(self,
                         swarm,
                         bounds=None,
                         bh=BoundaryHandler(strategy="random")):
        """Update the position matrix
        This method updates the position matrix given the current position and
        the velocity. If bounded, it waives updating the position.
        Parameters
        ----------
        swarm : pyswarms.backend.swarms.Swarm
            a Swarm instance
        bounds : tuple of :code:`np.ndarray` or list (default is :code:`None`)
            a tuple of size 2 where the first entry is the minimum bound while
            the second entry is the maximum bound. Each array must be of shape
            :code:`(dimensions,)`.
        bh : pyswarms.backend.handlers.BoundaryHandler
            a BoundaryHandler instance
        Returns
        -------
        numpy.ndarray
            New position-matrix
        """

        temp_position = swarm.position.copy()
        temp_position += swarm.velocity

        if bounds is not None:
            temp_position = bh(temp_position, bounds)

        temp_position[:, swarm.discrete_index:] = np.rint(
            temp_position[:, swarm.discrete_index:])

        position = temp_position

        return position
예제 #2
0
 def test_return_values(self, swarm, bounds, bh_strat):
     """Test if method gives the expected shape and range"""
     bh = BoundaryHandler(strategy=bh_strat)
     p = P.compute_position(swarm, bounds, bh)
     assert p.shape == swarm.velocity.shape
     if bounds is not None:
         assert (bounds[0] <= p).all() and (bounds[1] >= p).all()
예제 #3
0
def test_bound_handling(bounds, positions_inbound, positions_out_of_bound,
                        strategy):
    bh = BoundaryHandler(strategy=strategy)
    # Test if it doesn't handle inbound positions
    inbound_handled = bh(positions_inbound, bounds)
    assert inbound_handled.all() == positions_inbound.all()

    # Test if all particles are handled to a position inside the boundaries
    outbound_handled = bh(positions_out_of_bound, bounds)
    lower_than_bound = outbound_handled >= bounds[0]
    greater_than_bound = outbound_handled <= bounds[1]
    assert lower_than_bound.all()
    assert greater_than_bound.all()
예제 #4
0
def differential_evolution(n_dims, evolutions, f, args, bounds, original_time):

    population = 20
    pbar = tqdm(range(evolutions), position=1)
    discrete_index = 1
    #initialization
    positions = generate_position(population, n_dims, bounds, discrete_index)

    # original point
    positions[0][1] = 0
    positions[0][0] = original_time

    position_history = []
    position_history.append(positions[:, 1:])
    bh = BoundaryHandler(strategy="nearest")
    costs, aux = f(positions, **args)  # Compute current cost

    mutation_candidates = [[idx for idx in range(population) if idx != i]
                           for i in range(population)]
    mutation_candidates = np.array(mutation_candidates)

    for e in range(evolutions):

        # evaluation
        trial_pop = []
        #mutation
        for i in range(population):
            mutation_candidate = np.random.choice(mutation_candidates[i],
                                                  3,
                                                  replace=False)
            a, b, c = positions[mutation_candidate]
            mutation_factor = 0.8
            mutant = a + mutation_factor * (b - c)
            #recombination
            crossp = 0.7
            cross_points = np.random.rand(n_dims) < crossp
            trial = np.where(cross_points, mutant, positions[i])

            trial_pop.append(trial)

        trial_pop = np.array(trial_pop)
        # round and bound population
        trial_pop[:, discrete_index:] = np.rint(trial_pop[:, discrete_index:])
        trial_pop = bh(trial_pop, bounds)
        #evaluation

        trial_costs, trial_aux = f(trial_pop, **args)

        mask_cost = trial_costs < costs
        mask_pos = np.expand_dims(mask_cost, axis=1)
        # update new positons Apply masks
        positions = np.where(~mask_pos, positions, trial_pop)
        costs = np.where(~mask_cost, costs, trial_costs)

        aux = np.where(~mask_pos, aux, trial_aux)
        position_history.append(positions[:, 1:])
        post_fix = "c: {:.4f}".format(np.min(costs))
        pbar.set_postfix_str(post_fix)
        pbar.update(1)

    #find best index when there may be multiple best costs
    best_indices = np.where(costs == costs.min())
    if len(best_indices) == 1:
        best_index = best_indices[0]
    else:
        tmp_pos = positions[best_indices]
        min_ind = np.argmin(tmp_pos[:, 1])
        best_index = best_indices[min_ind]

    best_index = np.argmin(costs)
    best_cost = costs[best_index]
    best_position = positions[best_index]
    best_aux = aux[best_index]
    std = np.std(positions, axis=0)
    return best_cost, best_position, best_aux, std, position_history
예제 #5
0
def optimize(options,
             n_dims,
             iterations,
             f,
             args,
             bounds,
             original_time,
             clamp=None,
             mutate_prob=-1):
    topology = Traffic()

    pos_history = []

    n_particles = 20

    # de params
    mutation_factor = 0.8
    crossp = 0.7
    mutation_candidates = [[idx for idx in range(n_particles) if idx != i]
                           for i in range(n_particles)]
    mutation_candidates = np.array(mutation_candidates)

    swarm = create_swarm(n_particles=n_particles,
                         dimensions=n_dims,
                         options=options,
                         bounds=bounds,
                         discrete_index=1)

    # set first particle to have original time and no craft packet
    swarm.position[0][1] = 0
    swarm.position[0][0] = original_time

    # swarm.position[1]=[1502269093.015671,100.000000,211.000000]

    # swarm.position[1]=np.array([1502269073.367330,18.000000,192.000000])
    # swarm.best_pos=np.array([0,0,0])

    pbar = tqdm(range(iterations), position=1)

    # file=open("tmp_pso.txt","a")
    for i in pbar:
        # pos_history.append(np.vstack((swarm.position[:,1:],np.expand_dims(swarm.best_pos[1:], axis=0))))

        # Part 1: Update personal best

        swarm.current_cost, swarm.current_aux = f(
            swarm.position, **args, verbose=False)  # Compute current cost
        # file.write("{}".format(i)+"\n")
        # file.write(pprint.pformat(swarm.current_cost)+"\n")
        # file.write(pprint.pformat(swarm.position)+"\n")

        if i == 0:
            swarm.pbest_cost, swarm.pbest_aux = swarm.current_cost, swarm.current_aux
            swarm.best_cost, swarm.best_aux = swarm.current_cost, swarm.current_aux
            swarm.best_pos = swarm.position
            swarm.pbest_iter = np.zeros((n_particles, ))
        # swarm.pbest_cost, swarm.pbest_aux= f(swarm.pbest_pos, **args)  # Compute personal best pos
        # print(swarm.pbest_cost)

        # binomially mutate
        if np.random.rand() < mutate_prob:
            tmp_pos = swarm.position
            swarm.trial_pos = topology.mutate_swarm(swarm, mutation_factor,
                                                    crossp,
                                                    mutation_candidates,
                                                    bounds)
            swarm.trial_cost, swarm.trial_aux = f(swarm.trial_pos, **args)
            # print("tc",swarm.trial_cost)
            # print("ta",swarm.trial_aux)
            # print("tp",swarm.trial_pos)
            swarm.position, swarm.current_cost, swarm.current_aux = topology.compute_mbest(
                swarm)
            # print("-"*50)

        swarm.pbest_pos, swarm.pbest_cost, swarm.pbest_aux, swarm.pbest_iter = topology.compute_pbest(
            swarm, i)  # Update and store

        # Part 2: Update global best
        # Note that gbest computation is dependent on your topology
        # if np.min(swarm.pbest_cost) < swarm.best_cost:
        # best index is global minimum, others are best in the neighbourhood
        swarm.best_pos, swarm.best_cost, swarm.best_aux, swarm.best_index = topology.compute_gbest_local(
            swarm, 2, 4)
        # best_iter=i
        # file.write(pprint.pformat(swarm.best_pos)+"\n")

        # Part 3: Update position and velocity matrices
        # Note that position and velocity updates are dependent on your topology
        swarm.velocity = topology.compute_velocity(swarm,
                                                   bounds=bounds,
                                                   clamp=clamp,
                                                   iter=i)
        if np.random.rand() < 0.5:
            strat = "random"
        else:
            strat = "nearest"
        swarm.position = topology.compute_position(
            swarm, bounds=bounds, bh=BoundaryHandler(strategy=strat))

        # print(swarm.position)
        # file.write(pprint.pformat(swarm.velocity)+"\n")
        #
        # file.write("-"*100+"\n")
        # post_fix="c: {:.4f}, n: {:.0f}".format(swarm.best_cost, np.trunc(swarm.best_pos[1]))
        # if n_dims==3:
        #     post_fix+=", p: {:.0f}".format(swarm.best_pos[2])
        post_fix = "c: {:.4f}".format(swarm.best_cost[swarm.best_index])
        pbar.set_postfix_str(post_fix)

        norm_pos = np.copy(swarm.position)
        norm_pos[:, 0] = norm_pos[:, 0] - bounds[0][0]
        norm_best = np.copy(swarm.best_pos)
        norm_best[:, 0] = norm_best[:, 0] - bounds[0][0]
        pos_history.append(np.vstack((norm_pos, norm_best)))

        # if i-best_iter>10:
        #     print("early stopping")
        #     break
    # print("best config found in {} iterations".format(best_iter))
    std = np.std(swarm.position, axis=0)
    # print("best conf", swarm.best_cost[swarm.best_index], swarm.best_pos[swarm.best_index], swarm.best_aux[swarm.best_index])

    # print(swarm.best_cost)
    #
    # bc=np.argmin(swarm.best_cost)
    # swarm.best_pos=swarm.best_pos[bc]
    # swarm.best_aux=swarm.best_aux[bc]

    # print(swarm.position)
    return swarm.best_cost[swarm.best_index], swarm.best_pos[
        swarm.best_index], swarm.best_aux[swarm.best_index], std, pos_history
예제 #6
0
def test_intermediate_strategy(
    bounds, positions_inbound, positions_out_of_bound
):
    bh = BoundaryHandler(strategy="intermediate")
예제 #7
0
def test_random_strategy(bounds, positions_inbound, positions_out_of_bound):
    bh = BoundaryHandler(strategy="random")
예제 #8
0
def test_shrink_strategy(bounds, positions_inbound, positions_out_of_bound):
    bh = BoundaryHandler(strategy="shrink")
예제 #9
0
def test_reflective_strategy(
    bounds, positions_inbound, positions_out_of_bound
):
    bh = BoundaryHandler(strategy="reflective")
    pass
예제 #10
0
def test_nearest_strategy(bounds, positions_inbound, positions_out_of_bound):
    bh = BoundaryHandler(strategy="nearest")
예제 #11
0
def test_periodic_strategy(bounds, positions_inbound, positions_out_of_bound):
    bh = BoundaryHandler(strategy="periodic")
예제 #12
0
    def __init__(
        self,
        n_particles,
        dimensions,
        options,
        bounds=None,
        bh_strategy="periodic",
        velocity_clamp=None,
        vh_strategy="unmodified",
        center=1.00,
        ftol=-np.inf,
        init_pos=None,
    ):
        """
        A custom optimizer modified from pyswarms.single.global_best
        https://github.com/ljvmiranda921/pyswarms/blob/master/pyswarms/single/global_best.py
        Attributes
        ----------
        n_particles : int
            number of particles in the swarm.
        dimensions : int
            number of dimensions in the space.
        options : dict with keys :code:`{'c1', 'c2', 'w'}`
            a dictionary containing the parameters for the specific
            optimization technique.
                * c1 : float
                    cognitive parameter
                * c2 : float
                    social parameter
                * w : float
                    inertia parameter
        bounds : tuple of numpy.ndarray, optional
            a tuple of size 2 where the first entry is the minimum bound while
            the second entry is the maximum bound. Each array must be of shape
            :code:`(dimensions,)`.
        bh_strategy : str
            a strategy for the handling of out-of-bounds particles.
        velocity_clamp : tuple, optional
            a tuple of size 2 where the first entry is the minimum velocity and
            the second entry is the maximum velocity. It sets the limits for
            velocity clamping.
        vh_strategy : str
            a strategy for the handling of the velocity of out-of-bounds particles.
        center : list (default is :code:`None`)
            an array of size :code:`dimensions`
        ftol : float
            relative error in objective_func(best_pos) acceptable for
            convergence. Default is :code:`-np.inf`
        init_pos : numpy.ndarray, optional
            option to explicitly set the particles' initial positions. Set to
            :code:`None` if you wish to generate the particles randomly.
        """
        super(PSOoptimizer, self).__init__(
            n_particles=n_particles,
            dimensions=dimensions,
            options=options,
            bounds=bounds,
            velocity_clamp=velocity_clamp,
            center=center,
            ftol=ftol,
            init_pos=init_pos,
        )

        # Initialize logger
        self.rep = Reporter(logger=logging.getLogger(__name__))
        # Initialize the resettable attributes
        self.reset()
        # Initialize the topology
        self.top = Star()
        self.bh = BoundaryHandler(strategy=bh_strategy)
        self.vh = VelocityHandler(strategy=vh_strategy)
        self.name = __name__

        # Populate memory of the handlers
        self.bh.memory = self.swarm.position
        self.vh.memory = self.swarm.position
        self.swarm.pbest_cost = np.full(self.swarm_size[0], np.inf)

        # Set reached requirement
        self.reached_requirement = 0
예제 #13
0
    def mutate_swarm(self, swarm, mutation_factor, crossp, mutation_candidates,bounds, bh=BoundaryHandler(strategy="nearest")):
        # evaluation
        trial_pop=[]
        positions=swarm.position
        n_particles=swarm.position.shape[0]
        n_dims=swarm.position.shape[1]
        #mutation
        for i in range(n_particles):
            mutation_candidate=np.random.choice(mutation_candidates[i], 3, replace=False)
            a,b,c=positions[mutation_candidate]
            mutation_factor=0.8
            mutant=a+mutation_factor*(b-c)
            #recombination
            crossp=0.7
            cross_points = np.random.rand(n_dims) < crossp
            trial = np.where(cross_points, mutant, positions[i])

            trial_pop.append(trial)
        trial_pop=np.array(trial_pop)
        # round and bound population

        trial_pop = bh(trial_pop, bounds)

        trial_pop[:, :swarm.discrete_index] = np.around(trial_pop[:, :swarm.discrete_index],decimals=6)
        trial_pop[:,swarm.discrete_index:]=np.rint(trial_pop[:,swarm.discrete_index:])
        return trial_pop
    def __init__(
        self,
        n_particles,
        dimensions_discrete,
        options,
        bounds,
        bh_strategy="periodic",
        init_pos=None,
        velocity_clamp=None,
        vh_strategy="unmodified",
        ftol=-np.inf,
        ftol_iter=1,
    ):
        """Initialize the swarm

        Attributes
        ----------
        n_particles : int
            number of particles in the swarm.
        dimensions_discrete : int
            number of discrete dimensions of the search space.
        options : dict with keys :code:`{'c1', 'c2', 'w', 'k', 'p'}`
            a dictionary containing the parameters for the specific
            optimization technique
                * c1 : float
                    cognitive parameter
                * c2 : float
                    social parameter
                * w : float
                    inertia parameter
                * k : int
                    number of neighbors to be considered. Must be a
                    positive integer less than :code:`n_particles`
                * p: int {1,2}
                    the Minkowski p-norm to use. 1 is the
                    sum-of-absolute values (or L1 distance) while 2 is
                    the Euclidean (or L2) distance.
        bounds : tuple of numpy.ndarray
            a tuple of size 2 where the first entry is the minimum bound while
            the second entry is the maximum bound. Each array must be of shape
            :code:`(dimensions,)`.
        init_pos : numpy.ndarray, optional
            option to explicitly set the particles' initial positions. Set to
            :code:`None` if you wish to generate the particles randomly.
        velocity_clamp : tuple, optional
            a tuple of size 2 where the first entry is the minimum velocity
            and the second entry is the maximum velocity. It
            sets the limits for velocity clamping.
        vh_strategy : String
            a strategy for the handling of the velocity of out-of-bounds particles.
            Only the "unmodified" and the "adjust" strategies are allowed.
        ftol : float
            relative error in objective_func(best_pos) acceptable for
            convergence
        ftol_iter : int
            number of iterations over which the relative error in
            objective_func(best_pos) is acceptable for convergence.
            Default is :code:`1`
        """
        # Initialize logger
        self.rep = Reporter(logger=logging.getLogger(__name__))
        # Assign k-neighbors and p-value as attributes
        self.k, self.p = options["k"], options["p"]

        self.dimensions_discrete = dimensions_discrete

        self.bits, self.bounds = self.discretePSO_to_binaryPSO(
            dimensions_discrete, bounds)

        # Initialize parent class
        super(BinaryPSO, self).__init__(
            n_particles=n_particles,
            dimensions=sum(self.bits),
            binary=True,
            options=options,
            init_pos=init_pos,
            velocity_clamp=velocity_clamp,
            ftol=ftol,
            ftol_iter=ftol_iter,
        )
        # self.bounds = bounds
        # Initialize the resettable attributes
        self.reset()
        # Initialize the topology
        self.top = Ring(static=False)
        self.vh = VelocityHandler(strategy=vh_strategy)
        self.bh = BoundaryHandler(strategy=bh_strategy)
        self.name = __name__
예제 #15
0
 def test_input_swarm(self, swarm, bh_strat):
     """Test if method raises AttributeError with wrong swarm"""
     bh = BoundaryHandler(strategy=bh_strat)
     with pytest.raises(AttributeError):
         P.compute_position(swarm, bounds=([-5, -5], [5, 5]), bh=bh)