• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

thouska / spotpy / 7709518362

30 Jan 2024 10:11AM UTC coverage: 77.332% (-0.2%) from 77.518%
7709518362

push

github

thouska
Merge branch 'master' of https://github.com/thouska/spotpy

4162 of 5382 relevant lines covered (77.33%)

3.33 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.22
/src/spotpy/algorithms/abc.py
1
# -*- coding: utf-8 -*-
2
"""
6✔
3
Copyright (c) 2018 by Tobias Houska
4
This file is part of Statistical Parameter Optimization Tool for Python(SPOTPY).
5
:author: Patrick Lauer
6
"""
7

8
import random
6✔
9

10
import numpy as np
6✔
11

12
from . import _algorithm
6✔
13

14

15
class abc(_algorithm):
6✔
16
    """
17
    This class holds the Artificial Bee Colony (ABC) algorithm, based on Karaboga (2007).
18
    D. Karaboga, AN IDEA BASED ON HONEY BEE SWARM FOR NUMERICAL OPTIMIZATION,TECHNICAL REPORT-TR06, Erciyes University, Engineering Faculty, Computer Engineering Department 2005.
19
    D. Karaboga, B. Basturk, A powerful and Efficient Algorithm for Numerical Function Optimization: Artificial Bee Colony (ABC) Algorithm, Journal of Global Optimization, Volume:39, Issue:3,pp:459-171, November 2007,ISSN:0925-5001 , doi: 10.1007/s10898-007-9149-x
20

21
    """
22

23
    def __init__(self, *args, **kwargs):
6✔
24
        """
25
        Input
26
        ----------
27
        spot_setup: class
28
            model: function
29
                Should be callable with a parameter combination of the parameter-function
30
                and return an list of simulation results (as long as evaluation list)
31
            parameter: function
32
                When called, it should return a random parameter combination. Which can
33
                be e.g. uniform or Gaussian
34
            objectivefunction: function
35
                Should return the objectivefunction for a given list of a model simulation and
36
                observation.
37
            evaluation: function
38
                Should return the true values as return by the model.
39

40
        dbname: str
41
            * Name of the database where parameter, objectivefunction value and simulation results will be saved.
42

43
        dbformat: str
44
            * ram: fast suited for short sampling time. no file will be created and results are saved in an array.
45
            * csv: A csv file will be created, which you can import afterwards.
46

47
        parallel: str
48
            * seq: Sequentiel sampling (default): Normal iterations on one core of your cpu.
49
            * mpi: Message Passing Interface: Parallel computing on cluster pcs (recommended for unix os).
50

51
        save_sim: boolean
52
            * True:  Simulation results will be saved
53
            * False: Simulation results will not be saved
54
        """
55
        kwargs["optimization_direction"] = "maximize"
4✔
56
        kwargs["algorithm_name"] = "Artificial Bee Colony (ABC) algorithm"
4✔
57
        super(abc, self).__init__(*args, **kwargs)
4✔
58

59
    def sample(
6✔
60
        self, repetitions, eb=48, a=(1 / 10), peps=0.0001, ownlimit=False, limit=24
61
    ):
62
        """
63

64

65
        Parameters
66
        ----------
67
        repetitions: int
68
            maximum number of function evaluations allowed during optimization
69
        eb: int
70
            number of employed bees (half of population size)
71
        a: float
72
            mutation factor
73
        peps: float
74
            Convergence criterium
75
        ownlimit: boolean
76
            determines if an userdefined limit is set or not
77
        limit: int
78
            sets the limit
79
        """
80
        self.set_repetiton(repetitions)
4✔
81
        print(
4✔
82
            "Starting the ABC algotrithm with " + str(repetitions) + " repetitions..."
83
        )
84
        # Initialize ABC parameters:
85
        randompar = self.parameter()["random"]
4✔
86
        self.nopt = randompar.size
4✔
87
        random.seed()
4✔
88
        if ownlimit == True:
4✔
89
            self.limit = limit
×
90
        else:
91
            self.limit = eb
4✔
92
        lb, ub = self.parameter()["minbound"], self.parameter()["maxbound"]
4✔
93
        # Initialization
94
        work = []
4✔
95
        icall = 0
4✔
96
        gnrng = 1e100
4✔
97
        # Calculate the objective function
98
        param_generator = ((rep, self.parameter()["random"]) for rep in range(eb))
4✔
99
        for rep, randompar, simulations in self.repeat(param_generator):
4✔
100
            # Calculate fitness
101
            like = self.postprocessing(
4✔
102
                rep, randompar, simulations, chains=1, negativlike=True
103
            )
104
            c = 0
4✔
105
            p = 0
4✔
106
            work.append([like, randompar, like, randompar, c, p])
4✔
107
            icall += 1
4✔
108
            if self.status.stop:
4✔
109
                print("Stopping sampling")
×
110
                break
×
111

112
        while icall < repetitions and gnrng > peps:
4✔
113
            psum = 0
4✔
114
            # Employed bee phase
115
            # Generate new input parameters
116
            for i, val in enumerate(work):
4✔
117
                k = i
4✔
118
                while k == i:
4✔
119
                    k = random.randint(0, (eb - 1))
4✔
120
                j = random.randint(0, (self.nopt - 1))
4✔
121
                work[i][3][j] = work[i][1][j] + random.uniform(-a, a) * (
4✔
122
                    work[i][1][j] - work[k][1][j]
123
                )
124
                if work[i][3][j] < lb[j]:
4✔
125
                    work[i][3][j] = lb[j]
4✔
126
                if work[i][3][j] > ub[j]:
4✔
127
                    work[i][3][j] = ub[j]
4✔
128

129
            # Calculate the objective function
130
            param_generator = ((rep, work[rep][3]) for rep in range(eb))
4✔
131
            for rep, randompar, simulations in self.repeat(param_generator):
4✔
132
                # Calculate fitness
133
                clike = self.postprocessing(
4✔
134
                    icall + eb, randompar, simulations, chains=2, negativlike=True
135
                )
136
                if clike > work[rep][0]:
4✔
137
                    work[rep][1] = work[rep][3]
4✔
138
                    work[rep][0] = clike
4✔
139
                    work[rep][4] = 0
4✔
140
                else:
141
                    work[rep][4] = work[rep][4] + 1
4✔
142
                icall += 1
4✔
143
                if self.status.stop:
4✔
144
                    print("Stopping samplig")
×
145
                    break  # Probability distribution for roulette wheel selection
×
146
            bn = []
4✔
147
            for i, val in enumerate(work):
4✔
148
                psum = psum + (1 / work[i][0])
4✔
149
            for i, val in enumerate(work):
4✔
150
                work[i][5] = (1 / work[i][0]) / psum
4✔
151
                bn.append(work[i][5])
4✔
152
            bounds = np.cumsum(bn)
4✔
153
            # Onlooker bee phase
154
            # Roulette wheel selection
155
            for i, val in enumerate(work):
4✔
156
                pn = random.uniform(0, 1)
4✔
157
                k = i
4✔
158
                while k == i:
4✔
159
                    k = random.randint(0, eb - 1)
4✔
160
                for t, vol in enumerate(bounds):
4✔
161
                    if bounds[t] - pn >= 0:
4✔
162
                        z = t
4✔
163
                        break
4✔
164
                j = random.randint(0, (self.nopt - 1))
4✔
165
                # Generate new input parameters
166
                try:
4✔
167
                    work[i][3][j] = work[z][1][j] + random.uniform(-a, a) * (
4✔
168
                        work[z][1][j] - work[k][1][j]
169
                    )
170
                except UnboundLocalError:
×
171
                    z = 0
×
172
                    work[i][3][j] = work[z][1][j] + random.uniform(-a, a) * (
×
173
                        work[z][1][j] - work[k][1][j]
174
                    )
175
                if work[i][3][j] < lb[j]:
4✔
176
                    work[i][3][j] = lb[j]
4✔
177
                if work[i][3][j] > ub[j]:
4✔
178
                    work[i][3][j] = ub[j]
4✔
179
            # Calculate the objective function
180
            param_generator = ((rep, work[rep][3]) for rep in range(eb))
4✔
181
            for rep, randompar, simulations in self.repeat(param_generator):
4✔
182
                # Calculate fitness
183
                clike = self.postprocessing(
4✔
184
                    icall + eb, randompar, simulations, chains=3, negativlike=True
185
                )
186
                if clike > work[rep][0]:
4✔
187
                    work[rep][1] = work[rep][3]
4✔
188
                    work[rep][0] = clike
4✔
189
                    work[rep][4] = 0
4✔
190
                else:
191
                    work[rep][4] = work[rep][4] + 1
4✔
192
                icall += 1
4✔
193
                if self.status.stop:
4✔
194
                    print("Stopping samplig")
4✔
195
                    break
4✔
196
            # Scout bee phase
197
            for i, val in enumerate(work):
4✔
198
                if work[i][4] >= self.limit:
4✔
199
                    work[i][1] = self.parameter()["random"]
×
200
                    work[i][4] = 0
×
201
                    t, work[i][0], simulations = self.simulate((icall, work[i][1]))
×
202
                    clike = self.postprocessing(
×
203
                        icall + eb, randompar, simulations, chains=4, negativlike=True
204
                    )
205
                    work[i][0] = clike
×
206
                    icall += 1
×
207
                    if self.status.stop:
×
208
                        print("Stopping samplig")
×
209
                        break
×
210
            gnrng = -self.status.objectivefunction_max
4✔
211
            if icall >= repetitions:
4✔
212
                print("*** OPTIMIZATION SEARCH TERMINATED BECAUSE THE LIMIT")
4✔
213
                print("ON THE MAXIMUM NUMBER OF TRIALS ")
4✔
214
                print(repetitions)
4✔
215
                print("HAS BEEN EXCEEDED.")
4✔
216

217
            if gnrng < peps:
4✔
218
                print(
4✔
219
                    "THE POPULATION HAS CONVERGED TO A PRESPECIFIED SMALL PARAMETER SPACE AT RUN"
220
                )
221
                print(icall)
4✔
222
        self.final_call()
4✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc