this repo has no description
at develop 29 kB view raw
1.. _sec-modelling: 2 3Modelamiento básico en MiniZinc 4=============================== 5 6.. highlight:: minizinc 7 :linenothreshold: 5 8 9En esta sección se presenta la estructura básica de un modelo MiniZinc utilizando dos ejemplos simples. 10 11Nuestro primer ejemplo 12---------------------- 13 14.. _fig-aust: 15 16.. figure:: figures/aust.* 17 18 Estados de Australia 19 20Como nuestro primer ejemplo, imagine que se desea colorear el mapa de Australia, tal como se ve en la figura :numref:`fig-aust`. 21 22Esta figura se compone de siete estados diferentes, cada uno de los estados debe de tener un color y cada región adyacentes tiene que poseer diferentes colores. 23 24.. literalinclude:: examples/aust_es.mzn 25 :language: minizinc 26 :caption: Un modelo de MiniZinc :download:`aust_es.mzn <examples/aust_es.mzn>` para colorear los estados y territorios en Australia 27 :name: ex-aust 28 29Este problema se puede modelar muy fácil en MiniZinc. El modelo se muestra en :numref:`ex-aust`. 30 31La primera línea del modelo corresponde a un comentario. Un comentario comienza con un ``%``, que indica que el resto de la línea es un comentario. 32 33MiniZinc también tiene comentarios de bloque similares al estilo del lenguaje de programación C. Este tipo de comentario comienzan con ``/*`` y finalizan con un ``*/``. 34 35La siguiente parte del modelo declara las variables en el modelo. 36 37La línea 38 39:: 40 41 int: nc = 3; 42 43especifica un :index:`parámetro` en el problema, el cual es el número de colores a ser utilizados. 44 45Los parámetros son similares a las variables (constantes) de la mayoría de los lenguajes de programación. 46 47Estos deben de ser declarados y se debe de especificar un :index:`tipo` de dato. 48En este caso, el tipo de dato es :mzn:`int`. 49 50Además se le debe de dar un valor al parámetro mediante una :index:`asignación`. 51 52MiniZinc permite incluir la asignación como parte de la declaración (como en la línea anterior) o ser una sentencia de asignación separada. 53Así, la siguiente asignación de dos líneas, es equivalente a la asignación de una línea. 54 55:: 56 57 int: nc; 58 nc = 3; 59 60A diferencia de las variables, en muchos lenguajes de programación a un parámetro sólo se le puede asignar un solo valor. En ese sentido, son denominadas constantes. Es un error que un parámetro posea más de una asignación. 61 62 63Lo tipos de parámetros básicos son: :index:`enteros <integer>` (:mzn:`int`), 64números de punto flotante (:mzn:`float`), 65:index:`boleanos <Boolean>` (:mzn:`bool`) y 66:index:`cadenas <string>` (:mzn:`string`). 67Arreglos y conjuntos también son soportados. 68 69.. index:: 70 see: decision variable; variable 71 72 73Los modelos MiniZinc también pueden contener otro tipo de variable llamadas *variables de decisión*. 74Las :index:`variables de decisión <variable>` son variables en el sentido de las matemáticas o variables lógicas. 75A diferencia de parámetros y variables en un lenguaje de programación estándar, el modelador no necesita darles un valor. 76 77Más bien, el valor de una variable de decisión es desconocido. En consecuencia, es solamente cuando se ejecuta el modelo en MiniZinc, que el sistema de resolución determina si la variable de decisión se puede asignar un valor que satisface las restricciones en el modelo. 78 79En nuestro modelo de ejemplo, nosotros asociamos una *variable de decisión* a cada estado: 80``wa``, ``nt``, ``sa``, ``q``, ``nsw``, ``v`` y ``t`` que representa el color (desconocido) que se utilizará para llenar la región. 81 82.. index:: 83 single: domain 84 85Para cada variable de decisión se necesita dar el conjunto de los posibles valores que la variable puede tomar. 86Esto se llama *dominio* de la variable. Esto se puede dar como parte de la :index:`declaración de la variable <variable; declaration>` y el :index:`tipo` de la variable de decisión se infiere a partir del tipo de los valores en el dominio. 87 88En MiniZinc, las variables de decisión pueden ser booleanas, enteras, números de punto flotante o conjuntos. 89También se admiten las matrices cuyos elementos son variables de decisión. En nuestro modelo MiniZinc usamos números enteros para modelar los diferentes colores. 90Por lo tanto, cada una de las variables de decisión declarada posee el dominio :mzn:`1..nc`. 91Este dominio declarado es una expresión de un intervalo de tipo entero indicado por el conjunto :math:`\{ 1, 2, \dots, nc \}` usado en la declaración :mzn:`var`. El tipo de los valores es entero, por lo que todas las variables del modelo son variables de decisión enteras. 92 93 94.. defblock:: Identificadores 95 96 Los identificadores, son utilizados para nombrar parámetros y variables, 97 son secuencias de caracteres alfabéticos de minúsculas y mayúsculas, dígitos y el carácter ``_`` de subrayado . 98 Además, deben de comenzar con un carácter alfabético. Así, ``myName_2`` es un identificador válido. 99 100 Las *palabras clave* en MiniZinc no se pueden utilizar como nombres de identificador. Estas, se encuentran listadas en: ref:`spec-identifiers`. 101 102 Tampoco se permite que los *operadores* de MiniZinc se utilicen como identificadores; el listado aparece en :ref:`spec-Operators`. 103 104 105MiniZinc distingue cuidadosamente entre los dos tipos de variables del modelo: los parámetros y las variables de decisión. Los tipos de expresiones que se pueden construir usando variables de decisión son más restringidos que los que se pueden construir a partir de parámetros. Sin embargo, en cualquier lugar en que se pueda utilizar una variable de decisión, también se puede tener un parámetro del mismo tipo. 106 107 108.. defblock:: Declaraciones de variables enteras 109 110 Una :index:`variable de parámetro entero <variable; declaration; integer>` se declara como: 111 112 .. code-block:: minizincdef 113 114 int : <var-name> 115 <l> .. <u> : <var-name> 116 117 en donde :mzndef:`<l>` y :mzndef:`<u>` son expresiones enteras fijas. 118 119 Una variable de decisión entera se declara como: 120 121 .. code-block:: minizincdef 122 123 var int : <var-name> 124 var <l>..<u> : <var-name> 125 126 en donde :mzndef:`<l>` y :mzndef:`<u>` son expresiones enteras fijas. 127 128 129Formalmente la distinción entre parámetros y variables de decisión se denomina *instanciación* de la variable. La combinación de la instanciación variable y el tipo se llama tipo-instanciación (:index:`type-inst`). 130A medida de que usted empiece a usar MiniZinc, sin duda verá ejemplos de errores de tipo-instanciación (:index:`type-inst`). 131 132.. index:: 133 single: constraint 134 135El siguiente componente del modelo son las *restricciones*. Estas especifican las expresiones booleanas que las variables de decisión deben satisfacer para ser una solución válida para el modelo. En este ejemplo, existe un número de restricciones no iguales entre las variables de decisión, las cuales hacen cumplir que si dos estados son adyacentes, entonces deben tener colores diferentes. 136 137.. defblock:: Operadores relacionales 138 139 MiniZinc proporciona los :index:`operadores relacionales <operator; relational>`: 140 141 .. index:: 142 single: = 143 single: == 144 single: != 145 single: < 146 single: <= 147 single: > 148 single: >= 149 150 igual (``=`` or ``==``), no igual 151 (``!=``), 152 estrictamente menor que (``<``), 153 estrictamente mayor que (``>``), 154 menor o igual a (``<=``), y 155 mayor o igual que (``>=``). 156 157 158La siguiente línea del modelo: 159 160:: 161 162 solve satisfy; 163 164 165indica que el tipo de problema que es. En este caso, es un problema de :index:`satisfacción`: es decir, se debe de encontrar un valor para las variables de decisión que satisface las restricciones pero no nos importa cuál. 166 167.. index:: 168 single: output 169 170La parte final del modelo es la declaración de *salida*. Esto le indica a MiniZinc lo que debe de imprimir cuando se ejecute el modelo y encuentre una :index:`solución`. 171 172.. defblock:: Salida y cadenas 173 174 .. index:: 175 single: output 176 single: string 177 single: show 178 179 Una instrucción de salida es seguida por una *lista* de cadenas. Estos son típicamente :index:`string literales <string; literal>` 180 que se escriben entre comillas dobles y utilizan una notación C para caracteres especiales, 181 o una expresión de la forma :mzn:`show(e)` 182 en donde :mzn:`e` es una espresión de MiniZinc. 183 En el ejemplo ``\n`` representa el carácter de nueva línea y ``\t`` un tabulador. 184 185 También hay variedades de formato :mzn:`show` para números: 186 :mzn:`show_int(n,X)` 187 salidas de valores enteros 188 ``X`` en al menos :math:`|n|` carácteres, justificados a la derecha 189 si :math:`n > 0` y de otro modo, justificado a la izquierda; 190 :mzn:`show_float(n,d,X)` 191 salidas de los valores de punto flotante (mzn:`float`) ``X`` en al menos :math:`|n|` carácteres, justificados a la derecha 192 si :math:`n > 0` y de otro modo, justificado a la izquierda, con :math`d` carácteres después del punto decimal. 193 194 Los :index:`Literales de cadenas <string; literal>` deben encajar en una sola línea. Los literales de cadena más largos se pueden dividir en varias líneas utilizando el operador de concatenación de cadenas ``++``. 195 Por ejemplo, el literal 196 197 :: 198 199 "Archivo de datos no válido: La cantidad de harina no es negativa" 200 201 es equivalente a la expresión literal de cadena 202 203 :: 204 205 "Archivo de datos no válido: " ++ 206 "La cantidad de harina no es negativa" 207 208 MiniZinc soporta 209 :index:`cadenas interpoladas <string; literal; interpolated>`. 210 Las expresiones pueden ser incorporados directamente en las cadenas literales, 211 donde una subcadena del forma :mzn:`"\(e)"` 212 es reemplazada por el resultado :mzn:`show(e)`. 213 Por ejemplo, :mzn:`"t=\(t)\n"` produce la misma cadena como :mzn:`"t=" ++ show(t) ++ "\n"`. 214 215 Un modelo puede contener varias declaraciones de salida. En ese caso, todas las salidas se concatenan en el orden en que aparecen en el modelo. 216 217Podemos evaluar nuestro modelo escribiendo 218 219.. code-block:: bash 220 221 $ mzn-gecode aust_es.mzn 222 223en donde :download:`aust_es.mzn <examples/aust_es.mzn>` es el nombre del archivo que contiene nuestro modelo MiniZinc. 224Se debe de utilizar la extensión de archivo ``.mzn`` para indicar un modelo MiniZinc. 225El comando ``mzn-gecode`` utiliza el *solver* de dominios finitos Gecode para evaluar nuestro modelo. 226 227Cuando ejecutamos esto obtenemos el resultado: 228 229.. code-block:: none 230 231 wa=2 nt=3 sa=1 232 q=2 nsw=3 v=2 233 t=1 234 ---------- 235 236 237.. index:: 238 single: solution; separator ---------- 239 240La línea de 10 guiones ``----------`` es automáticamente agregada por la salida de MiniZinc, la cual indica que se ha encontrado una solución. 241 242 243Un ejemplo de optimización aritmética 244------------------------------------- 245 246El segundo ejemplo está motivado por la necesidad de hornear pasteles para una fiesta en nuestra escuela local. Sabemos cómo hacer dos tipos de tortas. \footnote{Advertencia: por favor no utilice estas recetas en casa} 247Un pastel de plátano que toma 250g de harina, 2 plátanos para puré de plátano, 75g de azúcar y 100g de mantequilla. Para un pastel de chocolate se necesita 200g de harina, 75g de cacao, 150g de azúcar y 150g de mantequilla. 248 249Podemos vender un pastel de chocolate por $4.50 y un pastel de plátano por $4.00. Además, tenemos 4kg de harina, 6 plátanos, 2kg de azúcar, 500g de mantequilla y 500g de cacao. 250 251La pregunta es, ¿cuántos de cada tipo de pastel debemos hornear para la fiesta para maximizar el beneficio?. 252 253A continuación se muestra el posible modelo de MiniZinc en :numref:`ex-cakes`. 254 255.. literalinclude:: examples/cakes_es.mzn 256 :language: minizinc 257 :caption: Modelo para determinar cuántos pasteles de banana y chocolate para hornear para la fiesta de la escuela (:download:`cakes_es.mzn <examples/cakes_es.mzn>`) 258 :name: ex-cakes 259 260.. index:: 261 single: expression; arithmetic 262 263La primera nueva característica es el uso de *expresiones aritméticas*. 264 265.. defblock:: Operadores Aritméticos Enteros 266 267 .. index:: 268 single: operator; integer 269 single: + 270 single: - 271 single: div 272 single: * 273 single: mod 274 275 MiniZinc proporciona los estándar operadores aritméticos enteros. 276 277 Adición (``+``), 278 subtracción (``-``), 279 multiplicación (``*``), 280 división entera (:mzn:`div`) 281 y 282 módulo entero (:mzn:`mod`). 283 También proporciona ``+`` y ``-`` 284 como operadores unarios. 285 286 El módulo entero se define para dar un resultado :math:`a` :mzn:`mod` :math:`b` 287 que tiene el mismo signo que el dividendo :math:`a`. La división entera se define de modo que 288 :math:`a = b ` ``*`` :math:`(a` :mzn:`div` :math:`b) + (a` :mzn:`mod` :math:`b)`. 289 290 MiniZinc proporciona funciones enteras estándar para el valor absoluto (:mzn:`abs`) y función de potencia (:mzn:`pow`). 291 Por ejemplo, :mzn:`abs(-4)` y :mzn:`pow(2,5)` es evaluado como ``4`` and ``32`` respectivamente. 292 293 La sintaxis para literales aritméticos es razonablemente estándar. Los literales enteros pueden ser decimales, hexadecimales u octales. Por ejemplo, ``0``, ``5``, ``123``, ``0x1b7``, ``0o777``. 294 295.. index:: 296 single: optimization 297 single: objective 298 single: maximize 299 single: minimize 300 301La segunda característica mostrada en el ejemplo es la optimización. La línea 302 303:: 304 305 solve maximize 400 * b + 450 * c; 306 307especifica que queremos encontrar una solución que maximice la expresión declarada, esto se denomina *objetivo*. 308 309El objetivo puede ser cualquier tipo de expresión aritmética. Se puede reemplazar la palabra clave 310:mzn:`maximize` 311por :mzn:`minimize` para especificar un problema de minimización. 312 313Cuando ejecutamos esto obtenemos el resultado: 314 315.. code-block:: none 316 317 Número de tortas de plátano = 2 318 Número de tortas de chocolate = 2 319 ---------- 320 ========== 321 322.. index:: 323 single: solution; end `==========` 324 325La línea ``==========`` 326se muestra automáticamente para problemas de optimización cuando el sistema ha demostrado que una solución es óptima. 327 328 329.. index:: 330 single: data file 331 332 333Archivos de datos y afirmaciones 334-------------------------------- 335 336Un inconveniente de este modelo es que si queremos resolver un problema similar, la próxima vez que necesitamos hornear pasteles para la escuela (que es a menudo) tenemos que modificar las restricciones en el modelo para reflejar los ingredientes que tenemos en la despensa. Si queremos reutilizar el modelo entonces es más conveniente dejar que la cantidad de cada ingrediente sea un parámetro del modelo y luego fijar sus valores en la parte superior del modelo. 337 338Incluso mejor sería establecer el valor de estos parámetros en un archivo de datos separado (*data file*). MiniZinc (como la mayoría de los otros lenguajes de modelado) permite el uso de archivos de datos para establecer el valor de los parámetros declarado en el modelo original. Esto permite que el mismo modelo se utilice fácilmente con diferentes datos ejecutándolo con diferentes archivos de datos. 339 340 341Los archivos de datos deben tener la extensión de archivo ``.dzn`` para indicar un archivo de datos MiniZinc y un modelo se puede ejecutar con cualquier número de archivos de datos (aunque una variable/parámetro sólo se puede asignar un valor en un archivo). 342 343.. literalinclude:: examples/cakes2_es.mzn 344 :language: minizinc 345 :caption: Modelo independiente de los datos para determinar cuántos pasteles de banana y chocolate para hornear para la fiesta de la escuela (:download:`cakes2_es.mzn <examples/cakes2_es.mzn>`) 346 :name: ex-cakes2 347 348Nuestro nuevo modelo se muestra en :numref:`ex-cakes2`. 349Podemos ejecutarlo usando el comando 350 351.. code-block: bash 352 353 $ mzn-gecode cakes2_es.mzn pantry.dzn 354 355donde el archivo de datos :download:`pantry_es.dzn <examples/pantry_es.dzn>` es definido en 356:numref:`fig-pantry1`. Esto da el mismo resultado que :download:`cakes_es.mzn <examples/cakes_es.mzn>`. 357El resultado de la ejecución del comando 358 359.. code-block:: bash 360 361 $ mzn-gecode cakes2_es.mzn pantry2_es.dzn 362 363con un conjunto de datos alternativo definido en 364:numref:`fig-pantry2` is 365 366.. code-block:: none 367 368 Número de tortas de plátano = 3 369 Número de tortas de chocolate = 8 370 ---------- 371 ========== 372 373Si eliminamos la instrucción de salida de :download:`cakes_es.mzn <examples/cakes_es.mzn>` entonces MiniZinc utilizará una salida predeterminada. En este caso, la salida resultante será 374 375.. code-block:: none 376 377 b = 3; 378 c = 8; 379 ---------- 380 ========== 381 382.. defblock:: Salida por defecto 383 384 A MiniZinc model with no output will output a line for each decision variable with its value, unless it is assigned an expression on its declaration. Note how the output is in the form of a correct datafile. 385 386.. literalinclude:: examples/pantry_es.dzn 387 :language: minizinc 388 :caption: Ejemplo de archivo de datos para :download:`cakes2_es.mzn <examples/cakes2_es.mzn>` (:download:`pantry_es.dzn <examples/pantry_es.dzn>`) 389 :name: fig-pantry1 390 391.. literalinclude:: examples/pantry2_es.dzn 392 :language: minizinc 393 :caption: Ejemplo de archivo de datos para :download:`cakes2_es.mzn <examples/cakes2_es.mzn>` (:download:`pantry2_es.dzn <examples/pantry2_es.dzn>`) 394 :name: fig-pantry2 395 396Se pueden introducir pequeños archivos de datos sin crear un archivo de datos ``.dzn``, usando una :index:`bandera en la línea de comandos <data file;command line>` 397``-D`` *cadena*, 398en donde *cadena* es el contenido del archivo de datos. Por ejemplo, el comando 399 400.. code-block:: bash 401 402 $ mzn-gecode cakes2_es.mzn -D \ 403 "flour=4000;banana=6;sugar=2000;butter=500;cocoa=500;" 404 405dará idénticos resultados que 406 407.. code-block:: bash 408 409 $ mzn-g12fd cakes2_es.mzn pantry_es.dzn 410 411Los archivos de datos sólo pueden contener instrucciones de asignación para variables de decisión y parámetros en el modelo o modelos a los que están destinados. 412 413.. index:: 414 single: assert 415 416La programación defensiva sugiere que debemos comprobar que los valores en el archivo de datos son razonables. Para nuestro ejemplo es razonable comprobar que la cantidad de todos los ingredientes no es negativa y generar un error en tiempo de ejecución si esto no es cierto. 417 418MiniZinc proporciona un operador (*built-in*) booleano incorporado para comprobar los valores de los parámetros. 419La forma es :mzn:`assert(B,S)`. La expresión booleana ``B`` es evaluada, y si la ejecución es falsa se aborta y la expresión de cadena ``S`` se evalúa e imprime como un mensaje de error. Para comprobar y generar un mensaje de error apropiado si la cantidad de harina es negativa podemos simplemente agregar la línea 420 421:: 422 423 constraint assert(flour >= 0,"La cantidad de harina no debe ser negativa"); 424 425a nuestro modelo. Observe que la espresión :mzn:`assert` es una expresión booleana y por lo tanto es considerado como un tipo de restricción. Podemos agregar líneas similares para comprobar que la cantidad de los otros ingredientes no es negativa. 426 427 428 429Resolviendo números reales 430-------------------------- 431 432Minizinc también soporta la resolución de restricciones con números reales usado en variables de punto flotante y restricciones. 433 434Considere un problema de tomar un préstamo a corto por un año, el cual será reembolsado en 4 cuotas trimestrales. 435 436Un modelo para esto se muestra en :numref:`ex-loan`. Utiliza un cálculo de interés simple para calcular el saldo después de cada trimestre. 437 438.. literalinclude:: examples/loan_es.mzn 439 :language: minizinc 440 :caption: Modelo para determinar las relaciones entre un préstamo de 1 año y lo reembolsado cada trimestre (:download:`loan_es.mzn <examples/loan_es.mzn>`) 441 :name: ex-loan 442 443Tenga en cuenta que declaramos una variable flotante ``f`` similar a una variable entera utilizando la palabra clave :mzn:`float` en lugar de :mzn:`int`. 444 445Podemos utilizar el mismo modelo para responder a una serie de preguntas diferentes. 446La primera pregunta es: Si tomo prestado $1000 al 4% y debo pagar $260 por trimestre, cuánto puedo terminar debiendo?. 447Esta pregunta está codificada por el archivo de datos :download:`loan1_es.dzn <examples/loan1_es.dzn>`. 448 449Puesto que deseamos utilizar variables de números reales y restricción, necesitamos usar un *solver* que soporte este tipo de problema. 450Un solver adecuado sería uno que soporta la programación lineal entera mixta. 451La distribución MiniZinc contiene un *solver*. 452La salida al ejecutar el comando ``mzn-cbc``: 453 454.. code-block:: bash 455 456 $ mzn-cbc loan_es.mzn loan1_es.dzn 457 458La salida es 459 460.. code-block:: none 461 462 Préstamo 1000.00 al 4.0% interés y reembolso 260.00 463 por trimestre para 1 año deja 65.78 debido 464 ---------- 465 466La segunda pregunta es: Si tomo prestado $1000 al 4% y no debo nada al final, ¿cuánto tengo que pagar?. 467Esta pregunta está codificada por el archivo de datos :download:`loan2_es.dzn <examples/loan2_es.dzn>`. 468La salida al ejecutar el comando 469 470.. code-block:: bash 471 472 $ mzn-cbc loan_es.mzn loan2_es.dzn 473 474La salida es 475 476.. code-block:: none 477 478 Préstamo 1000.00 al 4.0% interés y reembolso 275.49 479 por trimestre para 1 año deja 0.00 debido 480 ---------- 481 482La tercera pregunta, es si puedo pagar $250 por trimestre, ¿cuánto puedo pedir prestado al 4% para terminar por no pagar nada?. 483Esta pregunta está codificada por el archivo de datos :download:`loan3_es.dzn <examples/loan3_es.dzn>`. 484La salida al ejecutar el comando 485 486.. code-block:: bash 487 488 $ mzn-g12mip loan_es.mzn loan3_es.dzn 489 490La salida es: 491 492.. code-block:: none 493 494 Préstamo 907.47 at 4.0% interés y reembolso 250.00 495 por trimestre para 1 año deja 0.00 debido 496 ---------- 497 498.. literalinclude:: examples/loan1_es.dzn 499 :language: minizinc 500 :caption: Ejemplo de archivo de datos para :download:`loan_es.mzn <examples/loan_es.mzn>` (:download:`loan1_es.dzn <examples/loan1_es.dzn>`) 501 502.. literalinclude:: examples/loan2_es.dzn 503 :language: minizinc 504 :caption: Ejemplo de archivo de datos para :download:`loan_es.mzn <examples/loan_es.mzn>` (:download:`loan2.dzn <examples/loan2_es.dzn>`) 505 506.. literalinclude:: examples/loan3_es.dzn 507 :language: minizinc 508 :caption: Ejemplo de archivo de datos para :download:`loan_es.mzn <examples/loan_es.mzn>` (:download:`loan3_es.dzn <examples/loan3_es.dzn>`) 509 510 511.. defblock:: Operadores de Coma Flotante 512 513 .. index: 514 single: operator; float 515 single: + 516 single: - 517 single: * 518 single: / 519 single: abs 520 single: sqrt 521 single: ln 522 single: log2 523 single: log10 524 single: exp 525 single: sin 526 single: cos 527 single: tan 528 single: asin 529 single: acos 530 single: atan 531 single: sinh 532 single: cosh 533 single: tanh 534 single: asinh 535 single: acosh 536 single: atanh 537 single: pow 538 539 MiniZinc proporciona los siguiente operadores estándar aritméticos de punto flotante: 540 adición (``+``), 541 subtracción (``-``), 542 multiplicación (``*``) 543 and floating point division (``/``). 544 and floating point division ``+`` y ``-`` as unary operators. 545 546 MiniZinc puede coaccionar de forma automática números enteros a los números de punto flotante. Pero para hacer la coerción explícita, la función incorporada 547 :mzn:`int2float` puede ser usada. Obsérvese que una consecuencia de la coerción automática es que una expresión :mzn:`a / b` siempre se considera una división de punto flotante. Si necesita una división entera, asegúrese de usar el operador :mzn:`div`!. 548 549 MiniZinc proporciona además las siguientes funciones de coma flotante: 550 valor absoluto (``abs``), 551 raíz cuadrada (``sqrt``), 552 logaritmo natural (``ln``), 553 logaritmo en base 2 (``log2``), 554 logaritmo en base 10 (``log10``), 555 exponenciación de $e$ (``exp``), 556 seno (``sin``), 557 coseno (``cos``), 558 tangente (``tan``), 559 arcoseno (``asin``), 560 arco-coseno (``acos``), 561 arco-tangente (``atan``), 562 seno hiperbólico (``sinh``), 563 coseno hiperbólico(``cosh``), 564 tangente hiperbólico(``tanh``), 565 arcoseno hiperbólico(``asinh``), 566 arco-coseno hiperbólico(``acosh``), 567 arco-tangente hiperbólico(``atanh``), 568 y potencia (``pow``) que es la única función binaria, el resto son unarios. 569 570 La sintaxis para literales aritméticos es razonablemente estándar. Ejemplo literales flotantes son ``1.05``, ``1.3e-5`` and ``1.3E+5``. 571 572.. \pjs{Should do multiple solutions????} 573 574Estructura básica de un modelo 575------------------------------ 576 577Ahora estamos en condiciones de resumir la estructura básica de un modelo MiniZinc. La estructura esta compuesta por varios elementos (*items*), cada uno de los cuales tiene un punto y coma ``;``` al final. Los elementos pueden ocurrir en cualquier orden. 578 579Por ejemplo, los identificadores no necesitan ser declarados antes de ser utilizados. 580 581Hay 8 clases de :index:`elementos <item>`. 582 583- :index:`Include items <item; include>` permiten que el contenido de otro archivo se inserte en el modelo. 584 Estos tienen la forma: 585 586 .. code-block:: minizincdef 587 588 include <filename>; 589 590 en donde, :mzndef:`<filename>` es una cadena literal. 591 Permite que los modelos grandes se dividan en sub-modelos más pequeños y también la inclusión de restricciones definidas en los archivos de la biblioteca. 592 Veremos un ejemplo en :numref:`ex-smm`. 593 594- :index:`Variable declarations <item; variable declaration>` declaran nuevas variables. 595 Estas variables son variables globales y pueden ser referidos a desde cualquier parte del modelo. 596 Las variables pueden ser de dos tipos. 597 Parámetros a los que se asigna un valor fijo en el modelo o en un archivo de datos y variables de decisión cuyo valor se encuentra sólo cuando se resuelve el modelo. 598 Decimos que los parámetros son :index:`fixed` y variables de decisión :index:`unfixed`. 599 A la variable se le puede asignar opcionalmente un valor como parte de la declaración. 600 La forma es: 601 602 .. index: 603 single: expression; type-inst 604 single: par 605 single: var 606 607 .. code-block:: minizincdef 608 609 <type inst expr>: <variable> [ = ] <expression>; 610 611 El :mzndef:`<type-inst expr>` da la instanciación y el tipo de la variable. Estos son uno de los aspectos más complejos de MiniZinc. 612 Las instanciaciones se declaran utilizando :mzn:`par` para parámetros y 613 :mzn:`var` para variables de decisión. Si no hay una declaración de instanciación explícita entonces la variable es un parámetro. 614 El tipo puede ser un tipo base, como :index:`integer o float range <range>` o un arreglo o un conjunto. 615 Los tipos bases son :mzn:`float`, 616 :mzn:`int`, 617 :mzn:`string`, 618 :mzn:`bool`, 619 :mzn:`ann` 620 de los cuales solo 621 :mzn:`float`, :mzn:`int` and :mzn:`bool` puede usarse para variables de decisión. 622 El tipo de base :mzn:`ann` es una :index:`annotation` -- 623 Se analiza las anotaciones en :ref:`sec-search`. 624 :index:`Integer range expressions <range; integer>` puede ser utilizado en lugar del tipo :mzn:`int`. 625 Igualmente :index:`float range expressions <range; float>` puede utilizarse en lugar del tipo :mzn:`float`. 626 Éstos se usan típicamente para dar el dominio de una variable de la decisión pero se pueden también utilizar para restringir el rango de un parámetro. Otro uso de las declaraciones de variables es definir :index:`enumerated types`, los cuales se discuten en :ref:`sec-enum`. 627 628- :index:`Assignment items <item; assignment>` asignar un valor a una variable. Tienen la forma: 629 630 .. code-block:: minizincdef 631 632 <variable> = <expression>; 633 634 Los valores se pueden asignar a las variables de decisión, en cuyo caso la asignación es equivalente a la escritura :mzndef:`constraint <variable> = <expression>`. 635 636- :index:`Constraint items <item; constraint>` forman el corazón del modelo. Tienen la forma: 637 638 .. code-block:: minizincdef 639 640 constraint <Boolean expression>; 641 642 Ya hemos visto ejemplos de restricciones simples usando la comparación aritmética y el operador :mzn:`assert` incorporado. 643 En la siguiente sección veremos ejemplos de restricciones más complejas. 644 645- :index:`Solve items <item; solve>` especifique exactamente qué tipo de solución se busca. 646 Como hemos visto, tienen una de las siguientes tres formas: 647 648 .. code-block:: minizincdef 649 650 solve satisfy; 651 solve maximize <arithmetic expression>; 652 solve minimize <arithmetic expression>; 653 654 Se requiere un modelo para tener exactamente un elemento de resolución. 655 656- :index:`Output items <item; output>` son para presentar bien los resultados de la ejecución del modelo. 657 Estas tienen la forma: 658 659 .. code-block:: minizincdef 660 661 output [ <string expression>, ..., <string expression> ]; 662 663 Si no hay ningún elemento de salida, 664 por defecto MiniZinc imprimirá los valores de todas las variables de decisión. Estas variables no se les asignará opcionalmente un valor en el formato de los elementos de asignación. 665 666- :index:`Enumerated type declarations <item; enum>`. 667 Se discute eso en :ref:`sec-arrayset` y :ref:`sec-enum`. 668 669- :index:`Predicate, function and test items <item; predicate>` son para definir nuevas restricciones, funciones y pruebas booleanas. 670 Se discute eso en :ref:`sec-predicates`. 671 672- El :index:`annotation item <item; annotation>` se utiliza para definir una nueva anotación. Se discute eso en :ref:`sec-search`.