<jupyter_start><jupyter_text>Probando PuLP Reproducción del Paper: SIMUS UN MÉTODO DE PROGRAMACIÓN MULTIOBJETIVO> <NAME>., <NAME>., & <NAME>. UN MÉTODO DE PROGRAMACIÓN MULTIOBJETIVO. Revista de la Escuela de Perfeccionamiento en Investigación Operativa, 24(39).  EnunciadoA fin de mostrar una aplicación del método, se utiliza un ejemplo48SECCION APLICACIONESINVESTIGACION OPERATIVA - AÑO XXIV - No 39 - PAGINAS 44 a 54 - MAYO 2016sobre planificación urbana, propuesto en Lliso (2014) 2 .Desde hace algunas décadas y debido a los cambios en la industriadel transporte ferroviario y marítimo en casi todas las ciudades hay espaciosvacíos, por lo general céntricos, los cuales eran ocupados por las estacionesde ferrocarril, patios de ferrocarril y muelles. Estas parcelas abandonadas sonel blanco de los municipios para ser usadas en la construcción de parques,edificios de viviendas, oficinas gubernamentales, centros comerciales, etc.Suelen ser grandes parcelas que pueden ser adecuadas para varios usosdiferentes al mismo tiempo, razón por la cual el gobierno municipal seencuentra ante un dilema ya que es deseable seleccionar la alternativa de usoque mejor sirva a la ciudad. CASO: REHABILITACIÓN DE TIERRASUna importante ciudad portuaria se ha visto afectada por el cambio enla modalidad de transporte marítimo, cuando comenzó el transporte decontenedores a mediados del siglo 20. La ciudad se quedó con 39 hectáreasde muelles vacíos, así como los almacenes y una terminal ferroviaria.El municipio tiene que decidir qué hacer con esta tierra y desarrolló unPlan Maestro basado en tres proyectos diferentes:- Proyecto 1: Torres Corporativas - Hoteles - Marina - Pequeño Parque.- Proyecto 2: Torres de Viviendas - Zona Comercial en la antigua  estación de ferrocarril.- Proyecto 3: Centro de Convenciones - Gran Parque y área recreativa.Los criterios que considera para el análisis de las propuestas serefieren a:- Criterio 1: Generación de Trabajo- Criterio 2: Espacio Verde Recuperado- Criterio 3: Factibilidad Financiera- Criterio 4: Impacto AmbientalPara el criterio 2 se especifica un límite máximo, mientras que losrestantes criterios no tienen restricción definida para el lado derecho.El Decisor considera a los cuatro criterios como objetivos, por lo quese deberán resolver cuatro programas lineales con tres restricciones cadauno.Los datos se detallan en la tabla siguiente. |               |Proyecto 1 | Proyecto 2 | Proyecto 3 | VLD | Acción    || ------------- |-----------|------------|------------|-----|-----------|| Criterio 1    | 250       |  130       | 350        | -   | Maximizar || Criterio 2    | 120       |  200       | 340        | 500 | Maximizar || Criterio 3    | 20        |  40        | 15         | -   | Minimizar || Criterio 4    | 800       |  1000      | 600        | -   | Maximizar |<jupyter_code>import pulp

import numpy as np

from skcriteria import norm<jupyter_output><empty_output><jupyter_text>Stage 1<jupyter_code>stage1 = pulp.LpProblem("Stage 1", pulp.LpMaximize)

# variables
x1 = pulp.LpVariable('x1', lowBound=0, cat='Continuous')
x2 = pulp.LpVariable('x2', lowBound=0, cat='Continuous')
x3 = pulp.LpVariable('x3', lowBound=0, cat='Continuous')

# Objective
stage1 += 250 * x1 + 130 * x2 + 350 * x3, "Z"

# Constraints
stage1 += 120 * x1 + 200 * x2 + 340 * x3 <= 500
stage1 += 20 * x1 + 40 * x2 + 15 * x3 >= 15
stage1 += 800 * x1 + 1000 * x2 + 600 * x3 <= 1000

stage1<jupyter_output><empty_output><jupyter_text>Stage 2<jupyter_code>stage2 = pulp.LpProblem("Stage 2", pulp.LpMaximize)

# variables
x1 = pulp.LpVariable('x1', lowBound=0, cat='Continuous')
x2 = pulp.LpVariable('x2', lowBound=0, cat='Continuous')
x3 = pulp.LpVariable('x3', lowBound=0, cat='Continuous')

# Objective
stage2 += 120 * x1 + 200 * x2 + 340 * x3, "Z"

# Constraints
stage2 += 250 * x1 + 130 * x2 + 350 * x3 <= 350
stage2 += 20 * x1 + 40 * x2 + 15 * x3 >= 15
stage2 += 800 * x1 + 1000 * x2 + 600 * x3 <= 1000

stage2<jupyter_output><empty_output><jupyter_text>Stage 3<jupyter_code>stage3 = pulp.LpProblem("Stage 3", pulp.LpMinimize)

# variables
x1 = pulp.LpVariable('x1', lowBound=0, cat='Continuous')
x2 = pulp.LpVariable('x2', lowBound=0, cat='Continuous')
x3 = pulp.LpVariable('x3', lowBound=0, cat='Continuous')

# Objective
stage3 += 20 * x1 + 40 * x2 + 15 * x3, "Z"

# Constraints
stage3 += 250 * x1 + 130 * x2 + 350 * x3 <= 350
stage3 += 120 * x1 + 200 * x2 + 340 * x3 <= 500
stage3 += 800 * x1 + 1000 * x2 + 600 * x3 <= 1000

stage3<jupyter_output><empty_output><jupyter_text>Stage 4<jupyter_code>stage4 = pulp.LpProblem("Stage 4", pulp.LpMaximize)

# variables
x1 = pulp.LpVariable('x1', lowBound=0, cat='Continuous')
x2 = pulp.LpVariable('x2', lowBound=0, cat='Continuous')
x3 = pulp.LpVariable('x3', lowBound=0, cat='Continuous')

# Objective
stage4 += 800 * x1 + 1000 * x2 + 600 * x3, "Z"

# Constraints
stage4 += 250 * x1 + 130 * x2 + 350 * x3 <= 350
stage4 += 120 * x1 + 200 * x2 + 340 * x3 <= 500
stage4 += 20 * x1 + 40 * x2 + 15 * x3 >= 15

stage4<jupyter_output><empty_output><jupyter_text>Solutions<jupyter_code>stages = [stage1, stage2, stage3, stage4]
for stage in stages:
    stage.solve()
    status = pulp.LpStatus[stage.status]
    print(f"{stage.name}: {status}")
results = []
for stage in stages:
    row = [v.varValue for v in stage.variables()]
    results.append(row)


results = np.asarray(results)<jupyter_output><empty_output><jupyter_text>Normalization<jupyter_code>renorm = norm.sum(results, axis=1)
renorm[np.isnan(renorm)] = 0
renorm<jupyter_output>/home/juan/proyectos/skcriteria/src/skcriteria/norm.py:173: RuntimeWarning: invalid value encountered in true_divide
  return arr / sumval<jupyter_text>1er Procedimiento de Ordenamiento Valor Suma del Proyecto<jupyter_code>sp = np.sum(renorm, axis=0)
sp<jupyter_output><empty_output><jupyter_text>Cálculo del número de veces que $v_{ij} > 0$ ($q$)<jupyter_code>q = np.sum(renorm > 0, axis=0)
q<jupyter_output><empty_output><jupyter_text>Cálculo Factor de participación ( $ fp = \frac{q}{len(stages)}$ )<jupyter_code>fp = q / len(stages)
fp<jupyter_output><empty_output><jupyter_text>Ranking 1er. Procedimiento<jupyter_code>vp = sp * fp
for idx, prj_idx in enumerate(np.argsort(-vp)):
    points = vp[prj_idx]
    print(f"#{idx+1}: Proyecto {prj_idx + 1} - Puntaje: {points}")<jupyter_output>#1: Proyecto 3 - Puntaje: 0.7430555561851853
#2: Proyecto 2 - Puntaje: 0.6660353524170876
#3: Proyecto 1 - Puntaje: 0.09090909139772729<jupyter_text>2do Procedimiento de Ordenamiento Matriz de Proyectos dominantes según cada criterio<jupyter_code>doms = None
for crit_idx, crit in enumerate(renorm):
    crit_B = np.tile(crit, (3, 1))
    crit_A = crit_B.T
    dom = crit_A - crit_B
    dom[dom < 0] = 0
    print(f"Matriz de Proyectos dominantes según el criterio {crit_idx+1}")
    print(dom)
    print("-" * 30)
    doms = dom if doms is None else doms + dom
print("Matriz de proyectos dominantes")
doms
tita_j_p = np.sum(doms, axis=1)
print("Dominación:", tita_j_p)
tita_j_d = np.sum(doms, axis=0)
print("Subordinación:", tita_j_d)
puntaje_2 = tita_j_p - tita_j_d
print("Puntaje 2do. Ordenamieno:", puntaje_2)<jupyter_output>Puntaje 2do. Ordenamieno: [-2.45454545  0.99621211  1.45833334]<jupyter_text>Ranking 2do. Procedimiento<jupyter_code>for idx, prj_idx in enumerate(np.argsort(-puntaje_2)):
    points = puntaje_2[prj_idx]
    print(f"#{idx+1}: Proyecto {prj_idx + 1} - Puntaje: {points}")<jupyter_output>#1: Proyecto 3 - Puntaje: 1.4583333371111111
#2: Proyecto 2 - Puntaje: 0.9962121145025249
#3: Proyecto 1 - Puntaje: -2.4545454516136362
{'fraction_non_alphanumeric': 0.11813731975128985, 'fraction_numerical': 0.07183489879613705, 'mean_word_length': 4.388453314326443, 'pattern_counts': {'":': 0, '<': 62, '<?xml version=': 0, '>': 58, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '13', 'dir': 'jupyter-structured-clean-dedup', 'id': '426323', 'license': 'BSD-3-Clause', 'n_tokens_mistral': 3245, 'n_tokens_neox': 2862, 'n_words': 789, 'path': '01_simus_manual.ipynb', 'repo_name': 'quatrope/simus', 'size': '7572'}