Appeler CPLEX depuis Python (DO cplex)

1.Tout d'abord

C'est le premier message de Qiita. Cet article a été enregistré sous forme de mémorandum et il peut y avoir des erreurs.

L'environnement de développement fourni par IBM ILOG en tant que solution d'optimisation est appelé IBM ILOG CPLEX Optimization Studio. Les langages de développement CPLEX incluent C / C ++ / Java / Python, et d'autres problèmes d'optimisation peuvent être décrits à l'aide du langage OPL à l'aide du plugin Eclipse. L'environnement de développement intégré (IDE) de CPLEX Studio vous permet de résoudre les problèmes d'optimisation de manière interactive avec le développement en utilisant le langage OPL, tout en résolvant des problèmes d'optimisation polyvalents et d'autres solutions différentes obtenues avec CPLEX. Il semble être un peu difficile à utiliser dans des situations telles que l'application au problème de. Par conséquent, cette fois, j'écrirai un article avec le sens d'enregistrer la construction de l'environnement de développement par l'API Python sous forme de mémorandum. Ici, il y a deux principales API CPLEX Python, DOCplex [1] et Python-API (Legacy) [2], mais il semble que la version héritée sera abolie dans un avenir pas trop lointain, donc ici nous utiliserons DOCplex. Nous allons construire l'environnement de développement utilisé.

2. Environnement d'exploitation

Contrôle de fonctionnement ・ Ubuntu 18.04 Bionic (64 bits, 8 Go, sur VMWare) ・ CPLEX Optimization Studio 12.9 ・ Python 3.7.3 Cela a été fait à.

3. Instructions d'installation de CPLEX Studio 12.9

Tout d'abord, DL CPLEX Studio. Téléchargez .bin depuis le site [3](en supposant que vous le placiez dans ~ / Downloads). Bien qu'il s'agisse d'une méthode de téléchargement, elle est omise ici car elle peut être facilement téléchargée en lisant [3].

Après le téléchargement, commençons l'installation. Allons à ~ / Téléchargements et travaillons dessus.


$cd ~/Downloads

Tout d'abord, donnez l'autorisation d'exécution au fichier .bin.

$chmod +x CPLEX_OPT_STUD_129_LNX_X86-64.bin

Exécutez ensuite le fichier .bin.

$sudo ./CPLEX_OPT_STUD_129_LNX_X86-64.bin

Dans certaines langues, l'installateur se lancera et vous posera quelques questions. Il est résumé ci-dessous. Si vous ne l'aimez pas, appuyez sur Quitter pour arrêter.

  1. Sélection locale: -> 1. Anglais ou 2. Japonais
  2. Il est recommandé de quitter tous les programmes avant l'installation: -> ENTER ou retour
  3. Spécifiez le chemin d'installation: / opt / ibm / ILOG / CPLEX_Studio129 est la valeur par défaut
  4. Appuyez sur ENTER pour installer: -> ENTER
  5. Vérifiez la capacité du disque (environ 2 Go): -> ENTER
  6. Installation réussie: -> ENTER

Vous devez emprunter certains chemins. CPLEX dispose de deux moteurs d'optimisation, la programmation mathématique (MP) et la programmation par contraintes (CP), chacun avec un chemin binaire différent. Ouvrez le fichier de configuration du shell (~ / .bashrc) et écrivez l'exportation suivante après la dernière ligne.

$echo "export LD_LIBRARY_PATH="/opt/ibm/ILOG/CPLEX_Studio129/opl/bin/x86-64_linux:$LD_LIBRARY_PATH"
$echo "export PATH="/opt/ibm/ILOG/CPLEX_Studio129/opl/bin/x86-64_linux:$PATH"
$echo "export PATH="/opt/ibm/ILOG/CPLEX_Studio129/cplex/bin/x86-64_linux:$PATH"
$echo "export PATH="/opt/ibm/ILOG/CPLEX_Studio129/cpoptimizer/bin/x86-64_linux:$PATH"

Si vous l'ajoutez, je le refléterai.


$source ~/.bashrc

Voyons maintenant si la commande fonctionne.

$cplex
Welcome to IBM(R) ILOG(R) CPLEX(R) Interactive Optimizer 12.9.0.0
with Simplex, Mixed Integer & Barrier Optimizers
5725-A06 5725-A29 5724-Y48 5724-Y49 5724-Y54 5724-Y55 5655-Y21
Copyright IBM Corp. 1988, 2019. All Rights Reserved.
Type 'help' for a list of available commands.
Type 'help' followed by a command name for more
information on commands.

Commençons également et vérifions le moteur d'optimisation de la programmation par contraintes.

$cpoptimizer
Welcome to IBM(R) ILOG(R) CP Interactive Optimizer 12.9.0.0
with Simplex, Mixed Integer & Barrier Optimizers
5724-Y48 5724-Y49 5724-Y54 5724-Y55 5724-A06 5724-A29
Copyright IBM Corp. 1990, 2019. All Rights Reserved.

Type 'help' for a list of available commands.
Type 'help' followed by a command name for more
information on commands.

En outre, si le chemin passe, la commande suivante doit également passer. Si le contenu de l'aide est affiché de manière bâclée, le chemin passe sans aucun problème.

$oplrun

[Si la commande introuvable s'affiche et qu'elle ne démarre pas correctement] Il semble que le paramètre LD_LIBRARY_PATH ne soit pas reflété (dépend-il du système d'exploitation? ..?). Cela peut être évité en enregistrant le chemin dans la bibliothèque partagée (je ne sais pas grand chose à ce sujet ...). Cela semble correct si vous créez un fichier appelé hogehoge.conf sous /etc/ld.so.conf.d et ajoutez LD_LIBRARY_PATH.


$sudo vim /etc/ld.so.conf.d/oplrun.conf

J'écrirai ce qui suit à l'intérieur.

/opt/ibm/ILOG/CPLEX_Studio129/opl/bin/x86-64_linux/
/opt/ibm/ILOG/CPLEX_Studio129/cplex/bin/x86-64_linux/
/opt/ibm/ILOG/CPLEX_Studio129/cpoptimizer/bin/x86-64_linux/

Enregistrez le fichier et reconstruisez le cache.

$sudo ldconfig

4. Configuration DOCplex

Dans cet article, j'ai installé CPLEX dans / opt / ibm / ILOG / CPLEX_Studio129 / ... Par la suite, / opt / ibm / ILOG / CPLEX_129 sera placé comme (CPLEX_DIR). Si vous définissez vous-même un chemin arbitraire, CPLEX_DIR doit être un autre chemin. Faites attention.

Allez dans (CPLEX_DIR) / python / docplex / et vous trouverez un fichier appelé setup.py, exécutez-le.

$cd (CPLEX_DIR)/python/docplex
$sudo python3 setup.py install

La configuration commencera et se terminera en quelques secondes. Ceci termine la construction de l'environnement DOCplex.

5. Résolvez l'exemple

À partir de là, je vais brièvement aborder la manière d'écrire à l'aide de l'échantillon de référence officiel [4]. Puisque je m'étudie moi-même, il y a des incertitudes, mais je vous serais reconnaissant de pouvoir contribuer de quelque manière que ce soit.

Ici, je prendrai le premier exemple de [4], The Transportation Problem.

example-qiita1.png

C'est un problème qui minimise le coût du transport de marchandises situées de deux endroits à trois endroits. La figure est un graphe non circulaire dirigé (DAG) avec pondération entière non négative. Le noeud Sortant sur la gauche montre les emplacements où les approvisionnements peuvent être effectués. De plus, le nombre inscrit en rouge correspond au poids de chaque nœud et indique la quantité totale de marchandises pouvant être transportées. Le nombre en vert à côté du nœud entrant sur la droite correspond à la quantité totale de fournitures requises par le site. L'arc entre les nœuds indique l'itinéraire transportable et le poids sur l'arc indique le coût de transport par matériau.

Il existe plusieurs combinaisons pour calculer les coûts de transport dans ce problème. Puisqu'il s'agit d'un exemple simple, la solution optimale peut être facilement trouvée comme suit.

Le nœud 3 ne peut recevoir que des fournitures du nœud 1 et nécessite 7 fournitures. Par conséquent, puisque seul le matériau 15 du nœud 1 est envoyé au nœud 3, la quantité restante du nœud 1 devient 8, et à ce moment, le matériau 7 est envoyé au nœud 3 au coût de transport 2, de sorte que le coût de transport de 2 × 7 = 14 est requis. Faire.

De même, comme le nœud 4 ne peut recevoir que des fournitures du nœud 2, la quantité de restes dans le nœud 2 est de 20-10 = 10, et le coût de transport à ce moment est de 10 x 5 = 50, donc la quantité de restes dans le nœud 1 est de 8. , Le nœud 2 a 10 restes et le nœud 5 a besoin de 15 fournitures. À ce stade, comme le coût de transport du nœud 2 au nœud 5 est faible, si nous décidons de transporter préférentiellement les fournitures du nœud 2, le nœud 2 transportera les 10 et le montant restant sera 0, tandis que les fournitures requises pour le nœud 5 seront 5. Je vais. Enfin, toutes les exigences peuvent être satisfaites en envoyant seulement 5 fournitures du nœud 1 au nœud 5. Dans le processus ici, le nœud 2 porte 10 au coût de transport 3, donc 10 × 3 = 30 coût de transport, et le nœud 1 en transporte seulement 5 au coût de transport 4, donc 5 × 4 = 20 coût de transport est nécessaire.

De ce qui précède, le coût de transport final de 14 + 50 + 30 + 20 = 114 est requis.

Pour ériger ce problème en problème d'optimisation, il est nécessaire d'organiser la fonction objectif et les conditions de contrainte et de définir les variables de décision.

Sur la base de ce qui précède, il semble bon de définir les variables de décision comme suit.

J'écrirai le programme ci-dessous.

sample.py


 #URL/Vous pouvez résoudre le problème dans le cloud en écrivant la clé.
 #Ici, il est supposé être exécuté localement, il est donc défini sur Aucun.
url=None
key=None

 #Preparation of data
 #Le nœud 1 est 15,Le nœud 2 n'a que 20 fournitures
capacities = {1:15, 2:20} 
 #Le nœud 3 est 7,Le nœud 4 est 10,Le nœud 5 a 15 requêtes
demands = {3:7, 4:10, 5:15}
 #À ce moment, le coût de l'arc est(1,3)=2, (1,5)=4, (2,4)=5, (2,5)=Parce que c'est 3
costs = {(1,3):2, (1,5):4, (2,4):5, (2,5):3}
source = range(1,3) #gamme en python(i,j)Est-ce que je...j-Jusqu'à 1
target  = range(3,6)

 #description of a problem
 #Importer docplex
from docplex.mp.model import Model
tm = Model(name='transportation')

 #decision (continuous) variable 
 #Variable x(i,j)Est défini dans le problème tm. x est une variable continue, i se réfère à la source et j se réfère à la cible. Cependant, cela existe dans les coûts(Ceux qui sont connectés à l'arc)Seulement dans les cas.
x = {(i,j): tm.continuous_var(name='x_{0}_{1}'.format(i,j)) for i in source for j in target if (i,j) in costs}
tm.print_information()

 #add constraints
 # (1,3), (1,5)Le montant total des fournitures transportant[1]  (=15)Ne dépasse pas
 # (2,4), (2,5)Le montant total des fournitures transportant[2]  (=20)Ne dépasse pas
for i in source:
    tm.add_constraint(tm.sum(x[i,j] for j in target if (i,j) in costs) <= capacities[i] )
for j in target:
    tm.add_constraint(tm.sum(x[i,j] for i in source if (i,j) in costs) >= demands[j] )

 #Objective function
 #La fonction objective est l'arc(i,j)Minimisez le montant total des frais de transport entre
tm.minimize(tm.sum(x[i,j]*costs[i,j] for i in source for j in target if (i,j) in costs))

 #Solve
 #Résoudre le problème
tms = tm.solve(url=url,key=key)

 #Display and exceptions
 #Afficher la solution
assert tms
tms.display()

Lors de l'exécution, vous obtenez:


Model: transportation
 - number of variables: 4
   - binary=0, integer=0, continuous=4
 - number of constraints: 0
   - linear=0
 - parameters: defaults
solution for: transportation
objective: 114.000
x_1_3 = 7.000
x_1_5 = 5.000
x_2_4 = 10.000
x_2_5 = 10.000

C'est la fin de l'introduction de DOCplex (Python-API).

Lien de référence

1: Référence officielle DOCplex 2: Python-API(Legacy) 3: Téléchargement CPLEX 4: Exemple de référence officiel DOCplex

Recommended Posts

Appeler CPLEX depuis Python (DO cplex)
Appelez Matlab depuis Python pour optimiser
Appeler C depuis Python avec DragonFFI
Appeler popcount depuis Ruby / Python / C #
Appelez python de nim avec Nimpy
Appeler C / C ++ depuis Python sur Mac
Appeler le langage C depuis Python (python.h)
sql à sql
MeCab de Python
Appeler des commandes depuis Python (édition Windows)
Appelez la bibliothèque Python pour la normalisation de texte depuis MATLAB
Appel de scripts Python à partir de Python intégré en C ++ / C ++
Appeler Polly à partir du kit SDK AWS pour Python
Un moyen simple d'appeler Java depuis Python
Utilisez Thingsspeak de Python
Touchez MySQL depuis Python 3
Exploitez Filemaker depuis Python
Utiliser fluentd de python
Accéder à bitcoind depuis python
Changements de Python 3.0 à Python 3.5
Changements de Python 2 à Python 3.0
Python depuis ou import
Utilisez MySQL depuis Python
Exécutez Python à partir d'Excel
Installer Python à partir de la source
Exécuter des commandes depuis Python
Faites fonctionner le neutron de Python!
Utiliser MySQL depuis Python
Faire fonctionner LXC depuis Python
Faites Houdini avec Python3! !! !!
Manipuler riak depuis python
Forcer Python depuis Fortran
Utilisez BigQuery depuis Python.
Exécuter la commande depuis Python
[Python] Lire depuis Stdin
Utilisez mecab-ipadic-neologd de Python
Appelez votre propre module python à partir du package ROS
[Python] Comment appeler une fonction de c depuis python (édition ctypes)
Appeler des fonctions du langage C depuis Python pour échanger des tableaux multidimensionnels
Deep Python appris de DEAP
Faites Django avec CodeStar (Python3.6.8, Django2.2.9)
Publier de Python vers Slack
Fonctionnalités de grammaire ajoutées à partir de Python3.6
Flirter de PHP à Python
Rendre MeCab disponible à partir de Python 3
Faites Django avec CodeStar (Python3.8, Django2.1.15)
Informations obtenues à partir de tweet_id (Python)
OCR à partir de PDF en Python
Exécutez le script illustrator à partir de python
Utiliser MySQL depuis Anaconda (python)
Anaconda mis à jour de 4.2.0 à 4.3.0 (python3.5 mis à jour vers python3.6)
Étude de Python Hour4: orientée objet ②
Interroger Athena depuis Lambda Python
Accéder à Oracle DB depuis Python
Étude de Python Hour3: Fonctions
Démarrer / arrêter GCE à partir de python
Arrêtez Omxplayer à partir du code Python
Passer de python2.7 à python3.6 (centos7)
Connectez-vous à sqlite depuis python
Installez pyenv depuis Homebrew, installez Python depuis pyenv