Le solveur d'optimisation mathématique (version 1-thread COIN-CBC), qui est inclus dans PuLP et est utilisé par défaut, ne prend pas en charge le multi-threading (au moins pour Windows), il faut donc du temps pour résoudre les problèmes d'optimisation d'entiers. Peut prendre. Il y avait un article qui a écrit comment installer la version multithread de COIN-CBC, donc je publierai le lien. Bien entendu, il est disponible gratuitement pour un usage commercial.
--Windows: rendre le moteur de calcul du package d'optimisation mathématique Python PuLP plus rapide (version Windows édition facile) et spécifier le temps de calcul --Mac: Utilisez votre propre solveur CBC avec PuLP
Un autre solveur gratuit appelé "MIPCL" semble résoudre le problème plus rapidement que PuLP (la version à un thread de COIN-CBC qui l'accompagne).
(Entrée de référence) Enfin un solveur d'optimisation mathématique gratuit qui peut être utilisé? MIPCL
Cependant, MIPCL semble avoir une petite particularité dans l'installation et la grammaire, donc pour le moment, je pense que vous pouvez utiliser MIPCL si vous voulez de la vitesse et PuLP si vous voulez de la facilité. Si cela prend du temps à écrire et à résoudre avec PuLP, c'est une façon de le réécrire dans MIPCL ~ ~, et compte tenu du temps et des efforts, c'est aussi un moyen d'introduire MIPCL depuis le début et de s'y habituer ~ ~ Je pense.
Un tel problème mathématique appelé optimisation mathématique ou planification mathématique
\begin{alignat}{2}
&\mbox{Maximiser}
&\qquad x + y & \\
&\mbox{Contrainte}
& 2x + y &\leq 2 \\
&
& x + 2y &\leq 2 \\
&
& x &\geq 0 \\
&
& y &\geq 0 \\
\end{alignat}
Et un tel problème mathématique
\begin{alignat}{3}
&\mbox{Minimize}
&\qquad \sum_{i \in I} \sum_{j \in J} c_{ij} x_{ij} &
&\qquad & \\
&\mbox{subject to}
& \sum_{j \in J} x_{ij} &\leq 1
& &\forall i \in I \\
&
&\sum_{i \in I} x_{ij} &= 1
& &\forall j \in J \\
&
& x_{ij} &\in \{0,1\}
& &\forall i \in I, \quad \forall j \in J
\end{alignat}
Présentation du package PuLP de Python qui résout.
C'est une cible, mais on suppose que la fonction objectif et l'expression de contrainte peuvent être décrites sous forme linéaire (expression linéaire), et la variable peut être décrite comme une valeur continue ou une valeur discrète ou un mélange de celles-ci.
En passant, le problème (2) est parfois appelé problème d'optimisation linéaire en entier (problème de planification linéaire en entier). En outre, les problèmes avec un mélange de variables continues et discrètes sont appelés problèmes d'optimisation d'entiers mixtes (problèmes de planification d'entiers mixtes, problèmes d'optimisation linéaire d'entiers mixtes, problèmes de planification linéaire d'entiers mixtes).
Vous devriez considérer PuLP lui-même comme une ** API de modélisation **, un ** langage de modélisation ** qui facilite le codage de problèmes d'optimisation mathématique sur Python. Il est différent du ** solveur ** qui résout réellement la formule, mais comme il est livré avec un solveur appelé COIN, vous pouvez résoudre le problème simplement en installant PuLP. PuLP lui-même prend en charge plusieurs solveurs autres que COIN, donc si ces solveurs sont installés séparément, vous pouvez (facilement) basculer le solveur pour qu'il appelle depuis PuLP.
C'est juste une ** opinion personnelle **, mais ...
Gurobi Optimizer, IBM ILOG CPLEX Optimization Studio, FICO Xpress Optimization Suite, Numerical Optimizer sont chers ... ** → PuLP est gratuit! Le même solveur COIN est également gratuit! !! ** **
GLPK et lp_solve sont lents ... Microsoft Excel est lent et peut gérer un petit nombre de variables et d'expressions de contraintes ... ** → Le COIN inclus dans PuLP n'est pas mal pour un solveur gratuit! Vous pouvez appeler un solveur commercial simplement en changeant le code! !! ** **
Il dit que si vous souhaitez utiliser SCIP à des fins commerciales, veuillez m'envoyer un e-mail ... ** → PuLP & COIN est OK pour un usage commercial! Il n'y a aucune obligation de publier le code source du produit incorporé! !! ** **
Le langage de modélisation AMPL que M. K de K & R, qui est célèbre pour le langage C, a été impliqué dans le développement, et le langage de modélisation original qui se trouve également dans IBM ILOG CPLEX Optimization Studio, FICO Xpress Optimization Suite, Numerical Optimizer, etc. C'est facile à comprendre car vous pouvez le décrire. Mais il ne peut être utilisé nulle part ailleurs, et si vous voulez faire quelque chose de compliqué, vous devez regarder le manuel, et même si vous google, il y a peu d'informations ... ** → PuLP peut aussi écrire un modèle comme une formule mathématique! Puisqu'il s'agit de Python, il est facile de se lier à d'autres algorithmes, et si vous ne le comprenez pas, vous pouvez obtenir beaucoup d'informations par google! !! Étant donné que la description de la partie modèle peut être modifiée telle quelle et que seul le solveur à appeler peut être modifié, PuLP peut en fait devenir un langage commun! !! !! ** **
L'environnement de développement intégré fourni avec IBM ILOG CPLEX Optimization Studio et FICO Xpress Optimization Suite, diverses informations peuvent être affichées, et il est pratique de pouvoir cliquer avec la souris. Mais je ne peux pas l'utiliser ailleurs ... ** → Puisqu'il s'agit de Python, il peut être utilisé sur Visual Studio Code, Visual Studio (même pour l'édition Community gratuite et l'édition Express), Jupyter Notebook et Spyder! Fonctionne sur diverses machines et environnements! !! Tout le monde peut co-développer et tester n'importe où! !! !! ** **
Les chercheurs et les étudiants peuvent obtenir des solveurs commerciaux à bas prix ou gratuitement à des fins de recherche et d'apprentissage.
Si le contenu de la recherche semble être destiné à un usage commercial à l'avenir, les chercheurs devraient envisager d'utiliser Python + PuLP à partir de maintenant, compte tenu du coût impliqué. Je l'ai écrit plusieurs fois, mais il est facile de changer de solveurs pour appeler depuis PuLP, donc si vous n'avez pas besoin de toucher aux profondeurs des solveurs commerciaux (tels que les paramètres de réglage pour l'optimisation des entiers), PuLP est une bonne API de modélisation. pense. De plus, la quantité de codage requise pour le portage et la compatibilité des solveurs commerciaux qui ont des API pour Python n'est pas si grande.
Les étudiants devraient envisager d'utiliser Python + PuLP (COIN) à partir de maintenant, en tenant compte de l'utilisation de l'optimisation mathématique dans leur emploi à temps partiel actuel, leur emploi futur et leurs clients. Bien sûr, cela dépend de l'ampleur du projet, mais il est assez difficile d'expliquer la rentabilité de l'augmentation du coût d'achat et de maintenance d'un solveur commercial. Il en va de même même si vous effectuez une recherche sous contrat ou une recherche conjointe avec une entreprise. Pensez aux options que les gens d'affaires peuvent utiliser.
C'était mon opinion personnelle.
Dans ce qui suit, j'écrirai en supposant le cas de ** Anaconda ** qui prend en charge ** Python 3.7 ** sur ** Windows ** (pris en charge). Remplacez-le de manière appropriée sur Mac ou Linux.
Si vous avez installé Gurobi Optimizer ou un logiciel de simulation dans le passé en plus du Python que vous avez installé vous-même, il est possible que le système de traitement Python soit bloqué. Dans ce cas, démarrez l'invite de commande (bouton Démarrer de Windows → Outils système Windows → invite de commande) et tapez where python
ou where pip
pour vérifier quel système de traitement est prioritaire. ..
Si le dossier ʻAnaconda3` est affiché en premier, comme indiqué ci-dessous, cela signifie qu'Anaconda a la priorité, comme prévu dans cet article.
C:\Users\(Nom d'utilisateur)>where python
C:\Users\(Nom d'utilisateur)\Anaconda3\python.exe
C:\Users\(Nom d'utilisateur)\AppData\Local\Microsoft\WindowsApps\python.exe
C:\Users\(Nom d'utilisateur)>where pip
C:\Users\(Nom d'utilisateur)\Anaconda3\Scripts\pip.exe
C:\Users\(Nom d'utilisateur)>
Si quelque chose qui n'est pas le dossier ʻAnaconda3` est affiché en premier, cela signifie que le système de traitement qui n'est pas Anaconda est prioritaire. Veuillez décider par vous-même si vous pouvez le conserver tel quel, et si nécessaire, modifiez l'ordre des éléments répertoriés dans "Chemin" de "Variables d'environnement".
Si ce qui suit est affiché, ou si d'autres systèmes de traitement sont affichés mais le dossier ʻAnaconda3` n'est pas affiché,
C:\Users\(Nom d'utilisateur)>where python
information:Le fichier avec le modèle donné est introuvable.
C:\Users\(Nom d'utilisateur)>
C'est le soi-disant état «passe ne passe pas» d'Anaconda. Probablement parce que je n'ai pas coché "Ajouter Anaconda à ma variable d'environnement PATH" lorsque j'ai installé Anaconda. (Référence) https://weblabo.oscasierra.net/python-anaconda-install-windows/ Dans ce cas, passez le chemin (soit par vous-même ou en désinstallant et réinstallant Anaconda), soit effectuez le travail suivant avec Anaconda Prompt (bouton Démarrer de Windows → Anaconda3 (64 bits) → Anaconda Prompt) au lieu de l'invite de commande. S'il te plait donne moi.
Juste au cas où (car c'est nécessaire lors de la réorganisation des variables d'environnement), fermez l'invite de commande et rouvrez-la. Si Python est installé dans un dossier qui nécessite une écriture avec des privilèges d'administrateur (par exemple, si vous sélectionnez «Tous les utilisateurs (requiert des privilèges d'administrateur)» dans l'installation d'Anaconda), sélectionnez «Exécuter en tant qu'administrateur». Commencez.
Si vous essayez d'installer à partir de ** à l'intérieur de l'entreprise ** et de gêner ** proxy **, vous pouvez temporairement définir le proxy à l'invite de commande comme suit (adresse IP et numéro de port). Veuillez remplacer par la valeur de votre environnement).
set HTTP_PROXY=111.222.111.222:3333
set HTTPS_PROXY=111.222.111.222:3333
Référence: http://d.hatena.ne.jp/showhey810/20140905/1409892787
Tapez «pip install pulp» pour télécharger et installer la pulpe. Si le ** logiciel de sécurité ** demande l'autorisation de communication, veuillez le faire. Si tout se passe bien, vous devriez voir quelque chose comme ceci:
C:\Users\(Nom d'utilisateur)>pip install pulp
Collecting pulp
Downloading PuLP-2.1-py3-none-any.whl (40.6 MB)
|■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■| 40.6 MB 6.4 MB/s
Requirement already satisfied: pyparsing>=2.0.1 in c:\users\(Nom d'utilisateur)\anaconda3\lib\site-packages (from pulp) (2.4.6)
Installing collected packages: pulp
Successfully installed pulp-2.1
C:\Users\(Nom d'utilisateur)>
S'il est déjà installé, vous devriez voir quelque chose comme ceci: Il est déjà installé, donc il n'y a pas de problème.
C:\Users\(Nom d'utilisateur)>pip install pulp
Requirement already satisfied: pulp in c:\users\(Nom d'utilisateur)\anaconda3\lib\site-packages (2.1)
Requirement already satisfied: pyparsing>=2.0.1 in c:\users\(Nom d'utilisateur)\anaconda3\lib\site-packages (from pulp) (2.4.6)
C:\Users\(Nom d'utilisateur)>
(Note)
python -m pip install pulp
.pip install -U pulp
ou python -m pip install -U pulp
.Résolvez le problème d'ouverture (1).
\begin{alignat}{2}
&\mbox{Maximiser}
&\qquad x + y & \\
&\mbox{Contrainte}
& 2x + y &\leq 2 \\
&
& x + 2y &\leq 2 \\
&
& x &\geq 0 \\
&
& y &\geq 0. \\
\end{alignat}
pulp_problem_1.py
# coding: UTF-8
#linéaire/Importez PuLP pour résoudre des problèmes d'optimisation linéaire d'entiers
import pulp
# sys.Importez pour obtenir la valeur maximale d'entier (int) qui peut être gérée par python avec maxsize
import sys
#Déclaration d'un problème d'optimisation mathématique (maximisation)
problem = pulp.LpProblem("Problem-1", pulp.LpMaximize)
#Déclarer des variables (continu)
# *Objet variable lui-même (x,y) et
#Une représentation sous forme de chaîne d'une variable ("xx", "yy") Distinguer
#J'ose utiliser l'expression de chaîne de caractères"xx", "yy"Est écrit
x = pulp.LpVariable("xx", 0, sys.maxsize, pulp.LpContinuous)
y = pulp.LpVariable("yy", 0, sys.maxsize, pulp.LpContinuous)
#Déclarer la fonction objectif
# *Aucune parenthèse requise, mais répertoriée pour plus de clarté
problem += ( x + y, "Objective" )
#Déclarer les contraintes
problem += ( 2 * x + y <= 2 , "Constraint_1" )
problem += ( x + 2 * y <= 2 , "Constraint_2" )
#Afficher toutes les expressions de problème
# *La représentation sous forme de chaîne de la variable est utilisée lorsque le problème est imprimé dans une instruction d'impression
print("La formule en question")
print("-" * 8)
print(problem)
print("-" * 8)
#Calcul
result_status = problem.solve()
#Afficher la valeur et la solution de la fonction objectif (si la solution est disponible)
print("")
print("Résultat du calcul")
print("*" * 8)
print(f"Optimalité= {pulp.LpStatus[result_status]}")
print(f"Valeur de la fonction objective= {pulp.value(problem.objective)}")
print(f"Solution x= {pulp.value(x)}")
print(f" y = {pulp.value(y)}")
print("*" * 8)
La formule en question
--------
Problem-1:
MAXIMIZE
1*xx + 1*yy + 0
SUBJECT TO
Constraint_1: 2 xx + yy <= 2
Constraint_2: xx + 2 yy <= 2
VARIABLES
xx <= 9.22337203685e+18 Continuous
yy <= 9.22337203685e+18 Continuous
--------
Résultat du calcul
********
Optimalité= Optimal
Valeur de la fonction objective= 1.33333334
Solution x= 0.66666667
y = 0.66666667
********
Les langages qui peuvent utiliser la surcharge d'opérateurs peuvent facilement écrire des expressions d'optimisation mathématique. Les autres langages sont ... Java ...
Résolvez le problème d'ouverture (2).
\begin{alignat}{3}
&\mbox{Minimize}
&\qquad \sum_{i \in I} \sum_{j \in J} c_{ij} x_{ij} &
&\qquad & \\
&\mbox{subject to}
& \sum_{j \in J} x_{ij} &\leq 1
& &\forall i \in I \\
&
&\sum_{i \in I} x_{ij} &= 1
& &\forall j \in J \\
&
& x_{ij} &\in \{0,1\}
& &\forall i \in I, \quad \forall j \in J.
\end{alignat}
Vous utilisez souvent $ \ sum $ dans les formules d'optimisation mathématique, n'est-ce pas? Les langages de modélisation d'optimisation mathématique sont basés sur la façon dont vous pouvez écrire $ \ sum $. À cet égard, PuLP est sûr. D'ailleurs, dans le texte d'introduction à l'optimisation mathématique, l'ensemble $ I $ et $ J $ dans ce problème est $ I: = \ {1, \ ldots, m \} $ et $ J: = \ Numérotation à partir de 1 par force, comme {1, \ ldots, n \} $, par exemple, conditions de contrainte
\sum_{j = 1}^{n} x_{ij} \leq 1 \quad \mbox{for} \;\; i = 1, \ldots, m
Il y a quelque chose qui dit, mais je ne sais pas ce que représentent les éléments de $ I $ et $ J $, et quel élément du nombre $ 2 $ est $ I $ ou $ J $. Il est recommandé de ne pas remplacer l'ensemble par une colonne d'entiers positifs et d'utiliser les noms des éléments de l'ensemble tels quels. PuLP vous permet de modéliser naturellement en utilisant des spécifications de langage telles que des dictionnaires et des taples Python.
De plus, comme la formule écrite par la commande $ \ LaTeX $ dans ce problème, il serait bien d'aligner la hauteur de chaque formule pour la rendre plus facile à voir.
Après cela, ce problème est atténué de 0-1 variable $ x_ {ij} \ in \ {0,1 \} $ à variable continue $ 0 \ leq x_ {ij} \ leq 1 $ (changé en condition plus lâche) Il est bien connu que même si vous résolvez le problème, il existe une solution optimale pour les entiers en raison de l'unimodularité totale du problème, et vous pouvez l'obtenir. Cependant, lorsque vous le modélisez réellement au travail, les contraintes augmentent régulièrement et, dans la plupart des cas, toute unimodularité ne tient pas.
pulp_problem_2.py
# coding: UTF-8
#linéaire/Importez PuLP pour résoudre des problèmes d'optimisation linéaire d'entiers
import pulp
#Importer le temps pour mesurer le temps de calcul
import time
#Groupe de travailleurs (utilisez une liste pour plus de commodité)
I = ["Monsieur A", "Monsieur B", "Monsieur C"]
print(f"Assemblée des travailleurs I= {I}")
#Ensemble de tâches (utilisez une liste pour plus de commodité)
J = ["Travail je", "Travail b", "Travail c"]
print(f"Ensemble de tâches J= {J}")
#Ensemble de coûts (liste temporaire) lorsque le travailleur i est affecté à la tâche j
cc = [
[ 1, 2, 3],
[ 4, 6, 8],
[10, 13, 16],
]
#Parce que cc est une liste et que l'indice est un nombre
#Définir le dictionnaire c, par exemple cc[0][0]Est c["Monsieur A","Travail je"]Rendez-le accessible avec
c = {} #Dictionnaire vide
for i in I:
for j in J:
c[i,j] = cc[I.index(i)][J.index(j)]
print("Coût c[i,j]: ")
for i in I:
for j in J:
print(f"c[{i},{j}] = {c[i,j]:2d}, ", end = "")
print("")
print("")
#Déclarer un problème d'optimisation mathématique (minimisation)
problem = pulp.LpProblem("Problem-2", pulp.LpMinimize)
# pulp.LpMinimize :Minimiser
# pulp.LpMaximize :Maximiser
#Dictionnaire représentant un ensemble de variables
x = {} #Dictionnaire vide
# x[i,j]Ou x[(i,j)]alors,(i,j)Lire et écrire des valeurs en utilisant le taple comme clé
# 0-Déclarer 1 variable
for i in I:
for j in J:
x[i,j] = pulp.LpVariable(f"x({i},{j})", 0, 1, pulp.LpInteger)
#Sur l'étiquette de la variable'['Ou']'Ou'-'Pour certaines raisons'_'Ça change en ...?
# lowBound,Si vous ne spécifiez pas upBound, chaque-Infini, +Infini になる
#La notation inclusive peut également être utilisée
# x_suffixes = [(i,j) for i in I for j in J]
# x = pulp.LpVariable.dicts("x", x_suffixes, cat = pulp.LpBinary)
# pulp.LpContinuous :Variable continue
# pulp.LpInteger :Variable entière
# pulp.LpBinary : 0-1 variable
#Déclarer la fonction objectif
problem += pulp.lpSum(c[i,j] * x[i,j] for i in I for j in J), "TotalCost"
# problem += sum(c[i,j] * x[i,j] for i in I for j in J)
#D'accord
#Déclarer les contraintes
#Pour chaque travailleur i, pas plus d'une tâche ne peut être attribuée
for i in I:
problem += sum(x[i,j] for j in J) <= 1, f"Constraint_leq_{i}"
#Sur l'étiquette de contrainte'['Ou']'Ou'-'Pour certaines raisons'_'Ça change en ...?
#Un seul travailleur est affecté à chaque tâche j
for j in J:
problem += sum(x[i,j] for i in I) == 1, f"Constraint_eq_{j}"
#Afficher toutes les expressions de problème
print("La formule en question")
print(f"-" * 8)
print(problem)
print(f"-" * 8)
print("")
#Calcul
#Désignation du solveur
solver = pulp.PULP_CBC_CMD()
# pulp.PULP_CBC_CMD() :Pièce attachée à PuLP-CBC
# pulp.GUROBI_CMD() :Lancez Gurobi depuis la ligne de commande(.Générer temporairement un fichier lp)
# pulp.GUROBI() :Lancez Gurobi depuis la bibliothèque(Emplacement de la bibliothèque requis)
#Prend en charge plusieurs autres solveurs
# (Exemple d'utilisation)
# if pulp.GUROBI_CMD().available():
# solver = pulp.GUROBI_CMD()
#Mesure de l'heure de début
time_start = time.perf_counter()
result_status = problem.solve(solver)
# solve()de()Vous pouvez spécifier le solveur dans
#Pâte si rien n'est spécifié.PULP_CBC_CMD()
#Mesure du temps terminée
time_stop = time.perf_counter()
#Afficher la valeur et la solution de la fonction objectif (si la solution est disponible)
print("Résultat du calcul")
print(f"*" * 8)
print(f"Optimalité= {pulp.LpStatus[result_status]}, ", end="")
print(f"Valeur de la fonction objective= {pulp.value(problem.objective)}, ", end="")
print(f"Temps de calcul= {time_stop - time_start:.3f} (Secondes)")
print("Solution x[i,j]: ")
for i in I:
for j in J:
print(f"{x[i,j].name} = {x[i,j].value()}, ", end="")
print("")
print(f"*" * 8)
Assemblée des travailleurs I= ['Monsieur A', 'Monsieur B', 'Monsieur C']
Ensemble de tâches J= ['Travail je', 'Travail b', 'Travail c']
Coût c[i,j]:
c[Monsieur A,Travail je] = 1, c[Monsieur A,Travail b] = 2, c[Monsieur A,Travail c] = 3,
c[Monsieur B,Travail je] = 4, c[Monsieur B,Travail b] = 6, c[Monsieur B,Travail c] = 8,
c[Monsieur C,Travail je] = 10, c[Monsieur C,Travail b] = 13, c[Monsieur C,Travail c] = 16,
La formule en question
--------
Problem-2:
MINIMIZE
1*x(Monsieur A,Travail je) + 3*x(Monsieur A,Travail c) + 2*x(Monsieur A,Travail b) + 4*x(Monsieur B,Travail je) + 8*x(Monsieur B,Travail c) + 6*x(Monsieur B,Travail b) + 10*x(Monsieur C,Travail je) + 16*x(Monsieur C,Travail c) + 13*x(Monsieur C,Travail b) + 0
SUBJECT TO
Constraint_leq_Monsieur A: x(Monsieur A,Travail je) + x(Monsieur A,Travail c) + x(Monsieur A,Travail b) <= 1
Constraint_leq_Monsieur B: x(Monsieur B,Travail je) + x(Monsieur B,Travail c) + x(Monsieur B,Travail b) <= 1
Constraint_leq_Monsieur C: x(Monsieur C,Travail je) + x(Monsieur C,Travail c) + x(Monsieur C,Travail b) <= 1
Constraint_eq_Travail je: x(Monsieur A,Travail je) + x(Monsieur B,Travail je) + x(Monsieur C,Travail je) = 1
Constraint_eq_Travail b: x(Monsieur A,Travail b) + x(Monsieur B,Travail b) + x(Monsieur C,Travail b) = 1
Constraint_eq_Travail c: x(Monsieur A,Travail c) + x(Monsieur B,Travail c) + x(Monsieur C,Travail c) = 1
VARIABLES
0 <= x(Monsieur A,Travail je) <= 1 Integer
0 <= x(Monsieur A,Travail c) <= 1 Integer
0 <= x(Monsieur A,Travail b) <= 1 Integer
0 <= x(Monsieur B,Travail c) <= 1 Integer
0 <= x(Monsieur B,Travail b) <= 1 Integer
0 <= x(Monsieur C,Travail je) <= 1 Integer
0 <= x(Monsieur C,Travail c) <= 1 Integer
0 <= x(Monsieur C,Travail b) <= 1 Integer
--------
Résultat du calcul
********
Optimalité= Optimal,Valeur de la fonction objective= 19.0,Temps de calcul= 0.040 (Secondes)
Solution x[i,j]:
x(Monsieur A,Travail je) = 0.0, x(Monsieur A,Travail b) = 0.0, x(Monsieur A,Travail c) = 1.0,
x(Monsieur B,Travail je) = 0.0, x(Monsieur B,Travail b) = 1.0, x(Monsieur B,Travail c) = 0.0,
x(Monsieur C,Travail je) = 1.0, x(Monsieur C,Travail b) = 0.0, x(Monsieur C,Travail c) = 0.0,
********
Je pense que c'est plus facile que la classe de peinture de Bob, alors essayez Python + PuLP. Si le problème que vous souhaitez résoudre ** prend beaucoup de temps à calculer, consultez l'article sur le solveur multithread ** avec le lien en haut et essayez-le.
Recommended Posts