dega2 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
dega2-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Ali Zaidi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
dega2-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,122 @@
1
+ Metadata-Version: 2.4
2
+ Name: dega2
3
+ Version: 0.1.0
4
+ Summary: DEGA-2: A optimization a function over the efficient set of multi-objective integer variables using the genetics algorithms
5
+ Author-email: Ali Zaidi <a.zaidi@crlca.dz>
6
+ License-Expression: MIT
7
+ Keywords: optimization,genetic algorithm,multi-objective,integer programming
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Intended Audience :: Science/Research
10
+ Classifier: Topic :: Scientific/Engineering :: Mathematics
11
+ Requires-Python: >=3.9
12
+ Description-Content-Type: text/markdown
13
+ License-File: LICENSE
14
+ Requires-Dist: numpy
15
+ Requires-Dist: tqdm
16
+ Provides-Extra: plot
17
+ Requires-Dist: matplotlib; extra == "plot"
18
+ Provides-Extra: test
19
+ Requires-Dist: pytest; extra == "test"
20
+ Dynamic: license-file
21
+
22
+ # DEGA-2
23
+
24
+ A optimisation of function over the efficient set of multi-objective integer variables using a genetics algorithms, by Ali Zaidi.
25
+
26
+ It minimizes a function `phi·x` subject to linear constraints `a·x <= b`
27
+ (`x` integer, and `x >= 0` by default), using `p` objectives `c·x` for the
28
+ non-dominance test.
29
+
30
+ ## Installation
31
+
32
+ ```bash
33
+ pip install dega2
34
+ # with the convergence plot:
35
+ pip install "dega2[plot]"
36
+ ```
37
+
38
+ ## Entering your problem and parameters
39
+
40
+ ### 1. Interactive assistant
41
+
42
+ ```bash
43
+ dega2
44
+ ```
45
+
46
+ The assistant asks for the problem (file, keyboard entry, or a random example),
47
+ then for the parameters (population size, alpha, number of explored variables,
48
+ iterations, `x >= 0` constraints). Press Enter to accept the suggested value.
49
+
50
+ ### 2. `.json` file
51
+
52
+ ```bash
53
+ dega2 --exemple my_problem.json # writes a template to edit
54
+ dega2 -f my_problem.json # runs the computation
55
+ ```
56
+
57
+ File format:
58
+
59
+ ```json
60
+ {
61
+ "a": [[2, 3, 1], [1, 1, 2]],
62
+ "b": [20, 15],
63
+ "c": [[3, -1, 2], [-2, 4, 1]],
64
+ "phi": [-3, -2, -4],
65
+ "parametres": {
66
+ "n_population": 20, "alpha": 4, "explor": 3,
67
+ "iterations": 10, "positivity": true
68
+ }
69
+ }
70
+ ```
71
+
72
+ - `a`: constraint matrix (m rows, n columns); `b`: right-hand side (m values)
73
+ - `c`: objectives matrix (p rows, n columns); `phi`: function to minimize (n values)
74
+ - `parametres` is optional. Command-line options (`--population`, `--alpha`,
75
+ `--explor`, `-T`, `--sans-positivite`, `--seed`, `--no-plot`) take precedence over
76
+ the file. A `.npz` file (keys `a`, `b`, `c`, `phi`) is also accepted.
77
+
78
+ ### 3. In Python code
79
+
80
+ ```python
81
+ import numpy as np
82
+ import dega2
83
+
84
+ a = np.array([[2, 3, 1], [1, 1, 2]])
85
+ b = np.array([20, 15])
86
+ c = np.array([[3, -1, 2], [-2, 4, 1]])
87
+ phi = np.array([-3, -2, -4])
88
+
89
+ res = dega2.solve(a, b, c, phi, n_population=20, explor=3, iterations=10, seed=0)
90
+
91
+ print(res.phi) # best value of phi
92
+ print(res.x) # best solution
93
+ res.plot() # convergence curve (requires matplotlib)
94
+
95
+ # or from a file:
96
+ a, b, c, phi, params = dega2.charger_probleme("my_problem.json")
97
+ res = dega2.solve(a, b, c, phi, **params)
98
+ ```
99
+
100
+ `solve` parameters: `n_population=80`, `alpha=4`, `explor=3`,
101
+ `iterations=None` (2·n by default), `positivity=True`, `seed=None`, `verbose=True`.
102
+ `solve` returns a `Result` object: `x`, `phi`, `history` (minimum of phi at each
103
+ iteration), `population`, `time`, `iterations`.
104
+
105
+ Note: the algorithm builds a population of `n_population` feasible solutions that
106
+ are mutually non-dominated. With very few objectives or variables, such a
107
+ population may not exist; `dega2` then stops with an error message (reduce
108
+ `n_population` or add objectives).
109
+
110
+ ## Random demonstration
111
+
112
+ ```bash
113
+ dega2 --demo --seed 1
114
+ dega2 --demo -n 20 -p 5 --no-plot
115
+ ```
116
+
117
+ ## Tests
118
+
119
+ ```bash
120
+ pip install -e ".[test]"
121
+ pytest
122
+ ```
dega2-0.1.0/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # DEGA-2
2
+
3
+ A optimisation of function over the efficient set of multi-objective integer variables using a genetics algorithms, by Ali Zaidi.
4
+
5
+ It minimizes a function `phi·x` subject to linear constraints `a·x <= b`
6
+ (`x` integer, and `x >= 0` by default), using `p` objectives `c·x` for the
7
+ non-dominance test.
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ pip install dega2
13
+ # with the convergence plot:
14
+ pip install "dega2[plot]"
15
+ ```
16
+
17
+ ## Entering your problem and parameters
18
+
19
+ ### 1. Interactive assistant
20
+
21
+ ```bash
22
+ dega2
23
+ ```
24
+
25
+ The assistant asks for the problem (file, keyboard entry, or a random example),
26
+ then for the parameters (population size, alpha, number of explored variables,
27
+ iterations, `x >= 0` constraints). Press Enter to accept the suggested value.
28
+
29
+ ### 2. `.json` file
30
+
31
+ ```bash
32
+ dega2 --exemple my_problem.json # writes a template to edit
33
+ dega2 -f my_problem.json # runs the computation
34
+ ```
35
+
36
+ File format:
37
+
38
+ ```json
39
+ {
40
+ "a": [[2, 3, 1], [1, 1, 2]],
41
+ "b": [20, 15],
42
+ "c": [[3, -1, 2], [-2, 4, 1]],
43
+ "phi": [-3, -2, -4],
44
+ "parametres": {
45
+ "n_population": 20, "alpha": 4, "explor": 3,
46
+ "iterations": 10, "positivity": true
47
+ }
48
+ }
49
+ ```
50
+
51
+ - `a`: constraint matrix (m rows, n columns); `b`: right-hand side (m values)
52
+ - `c`: objectives matrix (p rows, n columns); `phi`: function to minimize (n values)
53
+ - `parametres` is optional. Command-line options (`--population`, `--alpha`,
54
+ `--explor`, `-T`, `--sans-positivite`, `--seed`, `--no-plot`) take precedence over
55
+ the file. A `.npz` file (keys `a`, `b`, `c`, `phi`) is also accepted.
56
+
57
+ ### 3. In Python code
58
+
59
+ ```python
60
+ import numpy as np
61
+ import dega2
62
+
63
+ a = np.array([[2, 3, 1], [1, 1, 2]])
64
+ b = np.array([20, 15])
65
+ c = np.array([[3, -1, 2], [-2, 4, 1]])
66
+ phi = np.array([-3, -2, -4])
67
+
68
+ res = dega2.solve(a, b, c, phi, n_population=20, explor=3, iterations=10, seed=0)
69
+
70
+ print(res.phi) # best value of phi
71
+ print(res.x) # best solution
72
+ res.plot() # convergence curve (requires matplotlib)
73
+
74
+ # or from a file:
75
+ a, b, c, phi, params = dega2.charger_probleme("my_problem.json")
76
+ res = dega2.solve(a, b, c, phi, **params)
77
+ ```
78
+
79
+ `solve` parameters: `n_population=80`, `alpha=4`, `explor=3`,
80
+ `iterations=None` (2·n by default), `positivity=True`, `seed=None`, `verbose=True`.
81
+ `solve` returns a `Result` object: `x`, `phi`, `history` (minimum of phi at each
82
+ iteration), `population`, `time`, `iterations`.
83
+
84
+ Note: the algorithm builds a population of `n_population` feasible solutions that
85
+ are mutually non-dominated. With very few objectives or variables, such a
86
+ population may not exist; `dega2` then stops with an error message (reduce
87
+ `n_population` or add objectives).
88
+
89
+ ## Random demonstration
90
+
91
+ ```bash
92
+ dega2 --demo --seed 1
93
+ dega2 --demo -n 20 -p 5 --no-plot
94
+ ```
95
+
96
+ ## Tests
97
+
98
+ ```bash
99
+ pip install -e ".[test]"
100
+ pytest
101
+ ```
@@ -0,0 +1,33 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "dega2"
7
+ version = "0.1.0"
8
+ description = "DEGA-2: A optimization a function over the efficient set of multi-objective integer variables using the genetics algorithms"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [{ name = "Ali Zaidi", email = "a.zaidi@crlca.dz" }]
14
+ keywords = ["optimization", "genetic algorithm", "multi-objective", "integer programming"]
15
+ classifiers = [
16
+ "Programming Language :: Python :: 3",
17
+ "Intended Audience :: Science/Research",
18
+ "Topic :: Scientific/Engineering :: Mathematics",
19
+ ]
20
+ dependencies = [
21
+ "numpy",
22
+ "tqdm",
23
+ ]
24
+
25
+ [project.optional-dependencies]
26
+ plot = ["matplotlib"]
27
+ test = ["pytest"]
28
+
29
+ [project.scripts]
30
+ dega2 = "dega2.cli:main"
31
+
32
+ [tool.setuptools.packages.find]
33
+ where = ["src"]
dega2-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,51 @@
1
+ import numpy as np
2
+
3
+ from . import ConsChekGA4, DomChekGA4
4
+
5
+
6
+ def explorer(population1, n_population, explor, p_cof1, index_p, p_cofphi1, index_phi,
7
+ n_pop, n_pop_phi):
8
+ """Phase d'exploration, vectorisée : pour chaque variable j, on ajoute +1 ou -1
9
+ sur toute la ligne concernée (au lieu de boucler colonne par colonne)."""
10
+ blocs_phi, blocs_p = [], []
11
+ tab_ind1, tab_ind1_ph = [], []
12
+ n_p = n_pop - n_pop_phi # nombre de colonnes modifiées dans la 2e moitié
13
+
14
+ for j in range(explor):
15
+ a1 = np.array(population1[:, 0:n_pop_phi])
16
+ a2 = np.array(population1[:, n_pop_phi:n_population])
17
+
18
+ r_phi = index_phi[0, j]
19
+ r_p = index_p[0, j]
20
+ a1[r_phi, :] += 1 if p_cofphi1[2, j] < 0 else -1
21
+ a2[r_p, :n_p] += 1 if p_cof1[2, j] < 0 else -1
22
+
23
+ tab_ind1_ph.extend([r_phi] * n_pop_phi)
24
+ tab_ind1.extend([r_p] * n_p)
25
+ blocs_phi.append(a1)
26
+ blocs_p.append(a2)
27
+
28
+ a3 = np.concatenate(blocs_phi, axis=1) # une seule concaténation
29
+ a4 = np.concatenate(blocs_p, axis=1)
30
+ return a3, a4, tab_ind1, tab_ind1_ph
31
+
32
+
33
+ def Build_PT(population1, n_population, explor, p_cof1, index_p, p_cofphi1, index_phi,
34
+ phi, alpha, a, b, c, n_pop, n_pop_phi, n):
35
+
36
+ ###################### Variables exploration ##############################
37
+ a3, a4, tab_ind1, tab_ind1_ph = explorer(
38
+ population1, n_population, explor, p_cof1, index_p, p_cofphi1, index_phi,
39
+ n_pop, n_pop_phi)
40
+
41
+ ############ Check the constraints and dominance of new populations ########
42
+ tab_ind11 = tab_ind1.copy()
43
+ tab_ind11_phi = tab_ind1_ph.copy()
44
+
45
+ [pop1, pop1_phi, tab_ind11, tab_ind11_phi] = ConsChekGA4.chek(
46
+ a3, a4, a, b, tab_ind11_phi, tab_ind11)
47
+
48
+ [pop2, tab_ind11_phi, tab_ind11] = DomChekGA4.nd_update(
49
+ c, population1, pop1, pop1_phi, tab_ind11, tab_ind11_phi)
50
+
51
+ return pop2, tab_ind1, tab_ind11, tab_ind1_ph, tab_ind11_phi
@@ -0,0 +1,13 @@
1
+ import numpy as np
2
+
3
+
4
+ def chek(pop, a, b):
5
+ if pop.shape[1] == 0:
6
+ return pop
7
+ return pop[:, (a @ pop <= b).all(axis=0)]
8
+
9
+
10
+
11
+
12
+
13
+
@@ -0,0 +1,19 @@
1
+ import numpy as np
2
+
3
+
4
+ def _realisables(a, b, pop):
5
+ """Indices des colonnes de `pop` qui vérifient a @ x <= b (test fait pour toutes
6
+ les colonnes en un seul produit matriciel)."""
7
+ if pop.shape[1] == 0:
8
+ return np.arange(0)
9
+ return np.flatnonzero((a @ pop <= b).all(axis=0))
10
+
11
+
12
+ def chek(pop_phi, pop, a, b, tab_ind11_phi, tab_ind11):
13
+ idx = _realisables(a, b, pop)
14
+ idx_phi = _realisables(a, b, pop_phi)
15
+
16
+ return (pop[:, idx],
17
+ pop_phi[:, idx_phi],
18
+ [tab_ind11[k] for k in idx],
19
+ [tab_ind11_phi[k] for k in idx_phi])
@@ -0,0 +1,19 @@
1
+ import numpy as np
2
+
3
+
4
+ def non_dominance(c, pop):
5
+ obj_val = np.dot(c, pop)
6
+ idx = np.arange(obj_val.shape[1])
7
+ i = 0
8
+ while i < len(idx) - 1:
9
+ oi = obj_val[:, idx[i]][:, None]
10
+ reste = obj_val[:, idx[i + 1:]]
11
+ le = (oi <= reste).all(axis=0) # i domine (faiblement) j -> j supprimé
12
+ gt = (oi > reste).all(axis=0) # j domine strictement i -> i supprimé
13
+ if gt.any():
14
+ jg = int(gt.argmax()) # premier j qui domine i
15
+ idx = np.delete(idx, np.append(np.flatnonzero(le[:jg]) + i + 1, i))
16
+ else:
17
+ idx = np.delete(idx, np.flatnonzero(le) + i + 1)
18
+ i += 1
19
+ return pop[:, idx]
@@ -0,0 +1,78 @@
1
+ import numpy as np
2
+
3
+
4
+ def _indices_non_domines(obj):
5
+ """Équivalent exact de la boucle de `non_dominance`, mais sans np.delete répétés
6
+ et avec la comparaison de i contre tous les j restants faite en une seule fois.
7
+ Renvoie les indices (dans l'ordre d'origine) des colonnes conservées."""
8
+ idx = np.arange(obj.shape[1])
9
+ i = 0
10
+ while i < len(idx) - 1:
11
+ oi = obj[:, idx[i]][:, None]
12
+ reste = obj[:, idx[i + 1:]]
13
+ le = (oi <= reste).all(axis=0) # i domine (faiblement) j -> j supprimé
14
+ gt = (oi > reste).all(axis=0) # j domine strictement i -> i supprimé
15
+ if gt.any():
16
+ jg = int(gt.argmax()) # premier j qui domine i
17
+ a_supprimer = np.append(np.flatnonzero(le[:jg]) + i + 1, i)
18
+ idx = np.delete(idx, a_supprimer) # i reste à la même position
19
+ else:
20
+ idx = np.delete(idx, np.flatnonzero(le) + i + 1)
21
+ i += 1
22
+ return idx
23
+
24
+
25
+ def non_dominance(c, pop, tab_ind3):
26
+ obj_val = np.dot(c, pop)
27
+ idx = _indices_non_domines(obj_val)
28
+ return pop[:, idx], [tab_ind3[k] for k in idx], obj_val[:, idx]
29
+
30
+
31
+ def _filtrer_contre(obj_p, idx_p, obj_ref, idx_ref, limite_fixe=None):
32
+ """Compare chaque individu de la population (idx_p) à l'ensemble de référence
33
+ (idx_ref) : un individu de référence dominé est supprimé, et l'individu de la
34
+ population est supprimé dès qu'un élément de référence le domine strictement.
35
+ `limite_fixe` reproduit la borne de balayage de la 2e boucle d'origine."""
36
+ i = 0
37
+ while i < len(idx_p):
38
+ oi = obj_p[:, idx_p[i]][:, None]
39
+ L = len(idx_ref) if limite_fixe is None else min(limite_fixe, len(idx_ref))
40
+ ref = obj_ref[:, idx_ref[:L]]
41
+ le = (oi <= ref).all(axis=0)
42
+ gt = (oi > ref).all(axis=0)
43
+ if gt.any():
44
+ jg = int(gt.argmax())
45
+ idx_ref = np.delete(idx_ref, np.flatnonzero(le[:jg]))
46
+ idx_p = np.delete(idx_p, i) # i reste à la même position
47
+ else:
48
+ idx_ref = np.delete(idx_ref, np.flatnonzero(le))
49
+ i += 1
50
+ return idx_p, idx_ref
51
+
52
+
53
+ def nd_update(c, population, pop1, pop1_phi, tab_ind11, tab_ind11_phi):
54
+
55
+ # non-dominance interne de pop1_phi puis de pop1
56
+ pop1_phi, tab_ind11_phi, obj_val_phi = non_dominance(c, pop1_phi, tab_ind11_phi)
57
+ pop1, tab_ind11, obj_val1 = non_dominance(c, pop1, tab_ind11)
58
+
59
+ obj_val_p = np.dot(c, population)
60
+ idx_p = np.arange(population.shape[1])
61
+
62
+ # population contre pop1
63
+ idx_p, idx1 = _filtrer_contre(obj_val_p, idx_p, obj_val1,
64
+ np.arange(pop1.shape[1]))
65
+
66
+ # population contre pop1_phi
67
+ # NB : comportement d'origine conservé. Le balayage de pop1_phi est borné par la
68
+ # taille de la population (size_popkD), pas par celle de pop1_phi : si pop1_phi
69
+ # est plus grande, ses derniers éléments ne sont pas comparés.
70
+ D = len(idx_p)
71
+ idx_p, idx_phi = _filtrer_contre(obj_val_p, idx_p, obj_val_phi,
72
+ np.arange(pop1_phi.shape[1]), limite_fixe=D)
73
+
74
+ pop2 = np.concatenate((population[:, idx_p], pop1_phi[:, idx_phi], pop1[:, idx1]),
75
+ axis=1)
76
+ return (pop2,
77
+ [tab_ind11_phi[k] for k in idx_phi],
78
+ [tab_ind11[k] for k in idx1])
@@ -0,0 +1,64 @@
1
+ import numpy as np
2
+ from . import BuildpopGA, GenPop, upload_cofGA
3
+ from tqdm import tqdm
4
+
5
+
6
+ def NewPop(population1, n_population, explor, p_cof1, index_p, p_cofphi1, index_phi,
7
+ phi, alpha, a, b, c, T, n, verbose=True):
8
+
9
+ n_pop = len(population1.T)
10
+ n_pop_phi = int(n_pop / alpha)
11
+
12
+ min_phi = []
13
+
14
+ barre = tqdm(
15
+ range(T),
16
+ desc="DEGA-2",
17
+ unit="it",
18
+ colour="green",
19
+ disable=not verbose,
20
+ bar_format="{desc} {percentage:3.0f}%|{bar:35}| {n_fmt}/{total_fmt} "
21
+ "[{elapsed}<{remaining}, {rate_fmt}] {postfix}",
22
+ )
23
+
24
+ for _ in barre:
25
+ [pop2, tab_ind1, tab_ind11, tab_ind1_phi, tab_ind11_phi] = BuildpopGA.Build_PT(
26
+ population1, n_population, explor, p_cof1, index_p, p_cofphi1, index_phi,
27
+ phi, alpha, a, b, c, n_pop, n_pop_phi, n)
28
+
29
+ s = pop2.shape[1]
30
+
31
+ if s > n_population:
32
+ # sélection des n_pop meilleurs individus (tri croissant de phi)
33
+ xphi1 = np.dot(phi, pop2)
34
+ ind_phi1 = np.argsort(xphi1, axis=1)
35
+ pop3 = pop2[:, ind_phi1[0, :n_pop]].astype(int)
36
+ elif s < n_population:
37
+ pop3 = GenPop.Gen(a, b, c, n, n_population - s)
38
+ pop3 = np.concatenate((pop2, pop3), axis=1)
39
+ else:
40
+ pop3 = pop2
41
+
42
+ population1 = pop3
43
+ xphi1 = np.dot(phi, pop3)
44
+
45
+ xphi2 = xphi1.min()
46
+ min_phi.append(xphi2)
47
+
48
+ ##################### Candidats ####################################
49
+ condidat_phi = list(index_phi[0, :explor])
50
+ condidat = list(index_p[0, :explor])
51
+
52
+ ##################### Mise à jour des coefficients #################
53
+ [p_cof1, p_cofphi1, index_p, index_phi] = upload_cofGA.upload(
54
+ p_cof1, index_p, p_cofphi1, index_phi,
55
+ tab_ind1, tab_ind1_phi, tab_ind11, tab_ind11_phi,
56
+ explor, condidat_phi, condidat, n_pop, n_pop_phi)
57
+
58
+ barre.set_postfix_str(f"min_phi={xphi2:.4e}", refresh=False)
59
+
60
+ # Correction : l'indice vient de pop3 (= population1), pas de pop2
61
+ min_index = xphi1.argmin()
62
+ xopt = population1[:, min_index]
63
+
64
+ return pop2, xphi2, min_phi, xopt
@@ -0,0 +1,32 @@
1
+ import numpy as np
2
+ from . import ConsChek, DomChek
3
+
4
+ # Nombre maximal de tirages consécutifs sans progression avant d'abandonner.
5
+ _ESSAIS_MAX = 5000
6
+
7
+
8
+ def Gen(a,b,c,n,n_population):
9
+ population=np.random.randint(0,3,(n,n_population),dtype=int);
10
+ pop2=ConsChek.chek(population, a, b)
11
+ pop3=DomChek.non_dominance(c, pop2)
12
+ np1=n_population-len(pop3.T)
13
+ sans_progres=0
14
+ while np1!=0:
15
+ population=np.random.randint(0,3,(n,np1),dtype=int);
16
+ pop2=ConsChek.chek(population, a, b)
17
+ pop3=np.concatenate((pop3,pop2),axis=1);
18
+ pop3=DomChek.non_dominance(c, pop3)
19
+ np1_nouveau=n_population-len(pop3.T)
20
+ # Garde-fou : sans lui, un problème où il n'existe pas assez de solutions
21
+ # réalisables et deux à deux non dominées (peu d'objectifs, peu de variables,
22
+ # contraintes très serrées...) faisait tourner la boucle indéfiniment.
23
+ sans_progres = 0 if np1_nouveau < np1 else sans_progres + 1
24
+ if sans_progres > _ESSAIS_MAX:
25
+ raise RuntimeError(
26
+ "Impossible de construire une population de %d solutions réalisables "
27
+ "et non dominées entre elles (%d trouvées). Réduis la taille de la "
28
+ "population, ajoute des objectifs (lignes de c) ou relâche les "
29
+ "contraintes." % (n_population, n_population - np1_nouveau))
30
+ np1=np1_nouveau
31
+
32
+ return(pop3)
@@ -0,0 +1,9 @@
1
+ """DEGA-2 : algorithme génétique multi-objectifs à variables entières."""
2
+
3
+ __version__ = "0.1.0"
4
+
5
+ from .solver import Result, solve
6
+ from .entree import charger_probleme, ecrire_exemple
7
+ from .example import demo
8
+
9
+ __all__ = ["solve", "charger_probleme", "ecrire_exemple", "demo", "Result", "__version__"]
@@ -0,0 +1,4 @@
1
+ from .cli import main
2
+
3
+ if __name__ == "__main__":
4
+ raise SystemExit(main())