cejsp 0.4.1__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.
- cejsp-0.4.1/LICENSE +21 -0
- cejsp-0.4.1/MANIFEST.in +12 -0
- cejsp-0.4.1/PKG-INFO +134 -0
- cejsp-0.4.1/README.md +100 -0
- cejsp-0.4.1/VALIDAR_WINDOWS.ps1 +47 -0
- cejsp-0.4.1/docs/FIVE_CLASSES.md +90 -0
- cejsp-0.4.1/docs/PUBLICAR_PYPI.md +46 -0
- cejsp-0.4.1/docs/RESEARCH_MODES.md +44 -0
- cejsp-0.4.1/docs/RESULTADOS.md +53 -0
- cejsp-0.4.1/examples/quickstart.py +9 -0
- cejsp-0.4.1/examples/test_igjsp_classifier.py +43 -0
- cejsp-0.4.1/examples/training_manifest.template.json +11 -0
- cejsp-0.4.1/pyproject.toml +31 -0
- cejsp-0.4.1/setup.cfg +4 -0
- cejsp-0.4.1/src/cejsp/__init__.py +19 -0
- cejsp-0.4.1/src/cejsp/__main__.py +3 -0
- cejsp-0.4.1/src/cejsp/batch.py +3 -0
- cejsp-0.4.1/src/cejsp/classifier.py +4 -0
- cejsp-0.4.1/src/cejsp/cli.py +3 -0
- cejsp-0.4.1/src/cejsp/estimator.py +3 -0
- cejsp-0.4.1/src/cejsp/graphs.py +3 -0
- cejsp-0.4.1/src/cejsp/instances.py +3 -0
- cejsp-0.4.1/src/cejsp/io.py +3 -0
- cejsp-0.4.1/src/cejsp/labels.py +3 -0
- cejsp-0.4.1/src/cejsp.egg-info/PKG-INFO +134 -0
- cejsp-0.4.1/src/cejsp.egg-info/SOURCES.txt +68 -0
- cejsp-0.4.1/src/cejsp.egg-info/dependency_links.txt +1 -0
- cejsp-0.4.1/src/cejsp.egg-info/entry_points.txt +3 -0
- cejsp-0.4.1/src/cejsp.egg-info/requires.txt +24 -0
- cejsp-0.4.1/src/cejsp.egg-info/top_level.txt +2 -0
- cejsp-0.4.1/src/xai_complex/__init__.py +16 -0
- cejsp-0.4.1/src/xai_complex/_graph_builder.py +293 -0
- cejsp-0.4.1/src/xai_complex/_graph_features.py +573 -0
- cejsp-0.4.1/src/xai_complex/batch.py +37 -0
- cejsp-0.4.1/src/xai_complex/bottleneck.py +61 -0
- cejsp-0.4.1/src/xai_complex/calibration.py +69 -0
- cejsp-0.4.1/src/xai_complex/categories.py +11 -0
- cejsp-0.4.1/src/xai_complex/classifier.py +244 -0
- cejsp-0.4.1/src/xai_complex/cli.py +60 -0
- cejsp-0.4.1/src/xai_complex/cumulative.py +70 -0
- cejsp-0.4.1/src/xai_complex/estimator.py +199 -0
- cejsp-0.4.1/src/xai_complex/feature_selector.py +27 -0
- cejsp-0.4.1/src/xai_complex/graphs.py +49 -0
- cejsp-0.4.1/src/xai_complex/instances.py +170 -0
- cejsp-0.4.1/src/xai_complex/io.py +158 -0
- cejsp-0.4.1/src/xai_complex/labels.py +102 -0
- cejsp-0.4.1/src/xai_complex/landscape.py +77 -0
- cejsp-0.4.1/src/xai_complex/proof_features.py +98 -0
- cejsp-0.4.1/src/xai_complex/research.py +507 -0
- cejsp-0.4.1/src/xai_complex/search_features.py +118 -0
- cejsp-0.4.1/src/xai_complex/specialists.py +66 -0
- cejsp-0.4.1/src/xai_complex/structural.py +64 -0
- cejsp-0.4.1/src/xai_complex/subset_voting.py +60 -0
- cejsp-0.4.1/src/xai_complex/supervised.py +39 -0
- cejsp-0.4.1/tests/test_cejsp.py +13 -0
- cejsp-0.4.1/tests/test_contracts.py +116 -0
- cejsp-0.4.1/tests/test_estimator.py +49 -0
- cejsp-0.4.1/tests/test_five_classes.py +64 -0
- cejsp-0.4.1/tests/test_graphs.py +32 -0
- cejsp-0.4.1/tests/test_instance_files.py +59 -0
- cejsp-0.4.1/tests/test_pipeline_validation.py +34 -0
- cejsp-0.4.1/tests/test_proof_signals.py +140 -0
- cejsp-0.4.1/tests/test_review_regressions.py +56 -0
- cejsp-0.4.1/tests/test_search_features.py +99 -0
- cejsp-0.4.1/tests/test_source_regressions.py +41 -0
- cejsp-0.4.1/tests/test_structural.py +59 -0
- cejsp-0.4.1/validate_instance_formats.py +41 -0
- cejsp-0.4.1/validate_pipeline.py +73 -0
- cejsp-0.4.1/validate_real_inputs.py +26 -0
- cejsp-0.4.1/verify_release.py +11 -0
cejsp-0.4.1/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Planning and Scheduling Research Group
|
|
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.
|
cejsp-0.4.1/MANIFEST.in
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
include LICENSE README.md
|
|
2
|
+
recursive-include tests *.py
|
|
3
|
+
recursive-include docs *.md
|
|
4
|
+
include examples/quickstart.py
|
|
5
|
+
include examples/training_manifest.template.json
|
|
6
|
+
include verify_release.py
|
|
7
|
+
include VALIDAR_WINDOWS.ps1
|
|
8
|
+
include validate_real_inputs.py
|
|
9
|
+
include validate_pipeline.py
|
|
10
|
+
include validate_instance_formats.py
|
|
11
|
+
|
|
12
|
+
include examples/test_igjsp_classifier.py
|
cejsp-0.4.1/PKG-INFO
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cejsp
|
|
3
|
+
Version: 0.4.1
|
|
4
|
+
Summary: CEJSP: JSP Complexity Estimator for job shop scheduling instances
|
|
5
|
+
Author: Planning and Scheduling Research Group
|
|
6
|
+
License-Expression: MIT
|
|
7
|
+
Classifier: Programming Language :: Python :: 3
|
|
8
|
+
Classifier: Operating System :: OS Independent
|
|
9
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
10
|
+
Requires-Python: >=3.10
|
|
11
|
+
Description-Content-Type: text/markdown
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Requires-Dist: numpy<3,>=1.26
|
|
14
|
+
Requires-Dist: pandas<3,>=2.1
|
|
15
|
+
Requires-Dist: scikit-learn<2,>=1.4
|
|
16
|
+
Requires-Dist: scipy<2,>=1.11
|
|
17
|
+
Requires-Dist: joblib<2,>=1.3
|
|
18
|
+
Provides-Extra: integration
|
|
19
|
+
Requires-Dist: IGJSP==2.0.1; extra == "integration"
|
|
20
|
+
Requires-Dist: ortools<10,>=9.15; extra == "integration"
|
|
21
|
+
Provides-Extra: graphs
|
|
22
|
+
Requires-Dist: torch>=2.2; extra == "graphs"
|
|
23
|
+
Requires-Dist: torch-geometric>=2.5; extra == "graphs"
|
|
24
|
+
Requires-Dist: networkx>=3; extra == "graphs"
|
|
25
|
+
Requires-Dist: tqdm>=4; extra == "graphs"
|
|
26
|
+
Provides-Extra: research
|
|
27
|
+
Requires-Dist: ortools<10,>=9.15; extra == "research"
|
|
28
|
+
Requires-Dist: catboost<2,>=1.2.10; extra == "research"
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: pytest>=8; extra == "dev"
|
|
31
|
+
Requires-Dist: build>=1.2; extra == "dev"
|
|
32
|
+
Requires-Dist: twine>=6; extra == "dev"
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# CEJSP: JSP Complexity Estimator
|
|
36
|
+
|
|
37
|
+
La API 0.2 añade entrada directa JSON/DZN/Taillard y un clasificador supervisado reentrenable de cinco clases: **toy, easy, medium, hard, open**. Consultar [el flujo de cinco clases](docs/FIVE_CLASSES.md) para entrenar, clasificar y versionar referencias. Requiere un protocolo explícito y ejemplos etiquetados; no se incluye todavía una referencia real de cinco clases validada.
|
|
38
|
+
|
|
39
|
+
Estimación empírica de dificultad de instancias de scheduling ya generadas. Este paquete no genera instancias ni modifica IGJSP.
|
|
40
|
+
|
|
41
|
+
El código procede del proyecto XAI-COMPLEX. Conserva el extractor de características de grafos y ofrece la metodología por lotes del estimador ponderado, además de una API explícita para ajustar una referencia y predecir nuevas instancias sin recalibrar cada lote.
|
|
42
|
+
|
|
43
|
+
## Instalación
|
|
44
|
+
|
|
45
|
+
```powershell
|
|
46
|
+
python -m pip install .
|
|
47
|
+
python -m pip install ".[graphs,dev]"
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
El extra `graphs` instala las dependencias del extractor original. No se necesita IGJSP para instalar ni utilizar XAI-COMPLEX con instancias guardadas o características extraídas.
|
|
51
|
+
|
|
52
|
+
## Usar instancias que ya tienes
|
|
53
|
+
|
|
54
|
+
```python
|
|
55
|
+
import json
|
|
56
|
+
from pathlib import Path
|
|
57
|
+
from cejsp.graphs import extract_instance_features
|
|
58
|
+
from cejsp import ComplexityEstimator
|
|
59
|
+
|
|
60
|
+
instances = [json.loads(p.read_text(encoding="utf-8"))
|
|
61
|
+
for p in Path("instancias_existentes").glob("*.json")]
|
|
62
|
+
features = [extract_instance_features(inst) for inst in instances]
|
|
63
|
+
model = ComplexityEstimator().fit(features)
|
|
64
|
+
resultados = model.predict(features[:1])
|
|
65
|
+
model.save("referencia.joblib")
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
Se necesitan al menos tres instancias de referencia con variación; para una calibración útil se requiere un conjunto representativo y una evaluación independiente. No se distribuye un modelo preentrenado ni se afirma precisión predictiva sin evaluación.
|
|
69
|
+
|
|
70
|
+
Para evaluar una instancia nueva se carga la referencia ya ajustada:
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
model = ComplexityEstimator.load("referencia.joblib", trusted=True)
|
|
74
|
+
resultado = model.predict([extract_instance_features(instancia_nueva)])
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Solo se deben cargar modelos de confianza. Se verifican esquema y versiones de dependencias del artefacto.
|
|
78
|
+
|
|
79
|
+
## Mantener el análisis por lotes del proyecto
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
import pandas as pd
|
|
83
|
+
from cejsp import estimate_features
|
|
84
|
+
|
|
85
|
+
features = pd.read_csv("graphs/features.csv").set_index("file")
|
|
86
|
+
scores = estimate_features(features)
|
|
87
|
+
scores.to_csv("complexity_scores.csv")
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Esta ruta conserva Isolation Forest, LOF, MinCovDet, vecinos y prior del estimador ponderado. Sus normalizaciones y categorías son relativas al lote. La API `ComplexityEstimator` congela la referencia; usa los mismos cuatro tipos de señal sin prior y, opcionalmente, mezcla regresión supervisada. Es una variante inductiva explícita, no una reproducción numérica idéntica del análisis por lotes.
|
|
91
|
+
|
|
92
|
+
La extracción usa el grafo JSP original. Las instancias con varias velocidades requieren `speed_index` explícito. El adaptador de entrada conserva todas las velocidades, fechas y disponibilidad; el extractor original rechaza FJSP porque su grafo de rutas fijas no modela la elección de máquina. No se declara compatibilidad científica con FJSP sin validar esa representación.
|
|
93
|
+
|
|
94
|
+
`summarize_instance` ofrece estadísticas descriptivas; no sustituye las características de grafos del estimador original.
|
|
95
|
+
|
|
96
|
+
## Etiquetas y evaluación
|
|
97
|
+
|
|
98
|
+
`SolverTargetCalibrator` calibra señales de solver en el entrenamiento y mantiene fijos esos parámetros. `evaluate_supervised` ajusta objetivo y preprocesamiento dentro de cada pliegue. Usa `base_instance_id` o grupos equivalentes para que variantes de una misma instancia no aparezcan en entrenamiento y validación. Las etiquetas miden dificultad empírica respecto al solver, hardware y límites de tiempo; no una clase de complejidad computacional.
|
|
99
|
+
|
|
100
|
+
Las correcciones de etiquetas cambian los resultados anteriores: se rechazan objetivos sin señales, se validan pesos, se renormalizan componentes disponibles y se conserva el significado absoluto del estado del solver.
|
|
101
|
+
|
|
102
|
+
## Comandos
|
|
103
|
+
|
|
104
|
+
```powershell
|
|
105
|
+
cejsp fit reference_features.json referencia.joblib
|
|
106
|
+
cejsp predict query_features.json referencia.joblib --trust-model
|
|
107
|
+
python -m unittest discover -s tests -v
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
Los JSON de la CLI contienen listas de diccionarios de características numéricas, sin identificadores de texto. Los identificadores se mantienen por separado o en el índice del DataFrame para la API por lotes.
|
|
111
|
+
|
|
112
|
+
Consulta `docs/PUBLICAR_PYPI.md` para construir, verificar y publicar.
|
|
113
|
+
|
|
114
|
+
## Estado de esta candidata
|
|
115
|
+
|
|
116
|
+
La ejecución `validacion-20261022-175907` del 22/10/2026 completó la validación: 32 pruebas sin omisiones en el entorno inicial y en instalaciones separadas de wheel y sdist, `pip check` correcto, 162 JSON válidos y flujo completo con 20 benchmarks en los tres entornos. Ambos artefactos superan `twine check --strict`. La invariancia individual/lotes se comprueba con tolerancia absoluta `1e-9` e igualdad de categorías y señales; la persistencia no cambia las puntuaciones. Esto valida funcionamiento y distribución, no precisión científica ni mejoras de rendimiento. No se ha publicado. Consultar `RESULTADOS.md` en la raíz del repositorio para el historial.
|
|
117
|
+
|
|
118
|
+
Las etiquetas necesitan el mismo identificador completo que las características. No se infieren correspondencias a partir del tamaño, configuración o semilla, ni se promedian registros repetidos automáticamente. Por ejemplo, `10_10-0-1-cp-sat` no se convierte silenciosamente en `10-10-0.pt`: la configuración y el protocolo del solver deben resolverse antes mediante una correspondencia explícita y verificada. Para variantes, incluir `base_instance_id` en todas las etiquetas o pasar `groups` a `evaluate_supervised`; el resultado incluye los índices de cada pliegue para auditar su separación.
|
|
119
|
+
|
|
120
|
+
`fit_instances(..., speed_index=...)` y `predict_instances(..., speed_index=...)` permiten la proyección explícita de velocidad. La invariancia por lote pertenece a la API inductiva; no se exige al análisis relativo por lotes.
|
|
121
|
+
|
|
122
|
+
## Nombre e interoperabilidad
|
|
123
|
+
|
|
124
|
+
La distribución se llama cejsp y el comando principal es cejsp. Los imports xai_complex y el comando anterior se conservan por compatibilidad. Las clases mantienen su identidad y los esquemas de persistencia anteriores para permitir cargar referencias guardadas; no se duplica el estimador. La disponibilidad del nombre en PyPI no está verificada. La validación completa anterior corresponde a la distribución xai-complex; CEJSP requiere repetir la validación tras el cambio de nombre.
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
## Mejora supervisada CEJSP 0.3.0
|
|
128
|
+
|
|
129
|
+
Referencia recomendada: `models/jsplib-8a6e36ef3126-v2/reference.joblib`, características estructurales y Extra Trees. Se conservan las referencias anteriores. Resultados, limitaciones y experimentos IGJSP: `evaluation/MEJORA_CLASIFICADOR.md`. El aumento con pseudoetiquetas no se incorpora por empeorar el resultado controlado. No hay validación externa de dificultad IGJSP.
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
## Estudio easy y referencias 0.4.0
|
|
133
|
+
|
|
134
|
+
Se completaron cinco rondas de nuevas variables, parámetros y selección dentro de los pliegues. No se alcanzó el 95% fuera del entrenamiento. El perfil de acierto global obtiene 84,19% exploratorio; el orientado a easy reconoce 7/15 casos con 79,41% global y precisión easy de 21,21%. Son perfiles experimentales con distintos compromisos; los modelos anteriores se conservan. Informe y comandos: `evaluation/RESULTADOS_EASY.md`; perfiles: `models/PROFILES.json`. Las sondas añaden resolución limitada durante inferencia.
|
cejsp-0.4.1/README.md
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
# CEJSP: JSP Complexity Estimator
|
|
2
|
+
|
|
3
|
+
La API 0.2 añade entrada directa JSON/DZN/Taillard y un clasificador supervisado reentrenable de cinco clases: **toy, easy, medium, hard, open**. Consultar [el flujo de cinco clases](docs/FIVE_CLASSES.md) para entrenar, clasificar y versionar referencias. Requiere un protocolo explícito y ejemplos etiquetados; no se incluye todavía una referencia real de cinco clases validada.
|
|
4
|
+
|
|
5
|
+
Estimación empírica de dificultad de instancias de scheduling ya generadas. Este paquete no genera instancias ni modifica IGJSP.
|
|
6
|
+
|
|
7
|
+
El código procede del proyecto XAI-COMPLEX. Conserva el extractor de características de grafos y ofrece la metodología por lotes del estimador ponderado, además de una API explícita para ajustar una referencia y predecir nuevas instancias sin recalibrar cada lote.
|
|
8
|
+
|
|
9
|
+
## Instalación
|
|
10
|
+
|
|
11
|
+
```powershell
|
|
12
|
+
python -m pip install .
|
|
13
|
+
python -m pip install ".[graphs,dev]"
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
El extra `graphs` instala las dependencias del extractor original. No se necesita IGJSP para instalar ni utilizar XAI-COMPLEX con instancias guardadas o características extraídas.
|
|
17
|
+
|
|
18
|
+
## Usar instancias que ya tienes
|
|
19
|
+
|
|
20
|
+
```python
|
|
21
|
+
import json
|
|
22
|
+
from pathlib import Path
|
|
23
|
+
from cejsp.graphs import extract_instance_features
|
|
24
|
+
from cejsp import ComplexityEstimator
|
|
25
|
+
|
|
26
|
+
instances = [json.loads(p.read_text(encoding="utf-8"))
|
|
27
|
+
for p in Path("instancias_existentes").glob("*.json")]
|
|
28
|
+
features = [extract_instance_features(inst) for inst in instances]
|
|
29
|
+
model = ComplexityEstimator().fit(features)
|
|
30
|
+
resultados = model.predict(features[:1])
|
|
31
|
+
model.save("referencia.joblib")
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Se necesitan al menos tres instancias de referencia con variación; para una calibración útil se requiere un conjunto representativo y una evaluación independiente. No se distribuye un modelo preentrenado ni se afirma precisión predictiva sin evaluación.
|
|
35
|
+
|
|
36
|
+
Para evaluar una instancia nueva se carga la referencia ya ajustada:
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
model = ComplexityEstimator.load("referencia.joblib", trusted=True)
|
|
40
|
+
resultado = model.predict([extract_instance_features(instancia_nueva)])
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Solo se deben cargar modelos de confianza. Se verifican esquema y versiones de dependencias del artefacto.
|
|
44
|
+
|
|
45
|
+
## Mantener el análisis por lotes del proyecto
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
import pandas as pd
|
|
49
|
+
from cejsp import estimate_features
|
|
50
|
+
|
|
51
|
+
features = pd.read_csv("graphs/features.csv").set_index("file")
|
|
52
|
+
scores = estimate_features(features)
|
|
53
|
+
scores.to_csv("complexity_scores.csv")
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Esta ruta conserva Isolation Forest, LOF, MinCovDet, vecinos y prior del estimador ponderado. Sus normalizaciones y categorías son relativas al lote. La API `ComplexityEstimator` congela la referencia; usa los mismos cuatro tipos de señal sin prior y, opcionalmente, mezcla regresión supervisada. Es una variante inductiva explícita, no una reproducción numérica idéntica del análisis por lotes.
|
|
57
|
+
|
|
58
|
+
La extracción usa el grafo JSP original. Las instancias con varias velocidades requieren `speed_index` explícito. El adaptador de entrada conserva todas las velocidades, fechas y disponibilidad; el extractor original rechaza FJSP porque su grafo de rutas fijas no modela la elección de máquina. No se declara compatibilidad científica con FJSP sin validar esa representación.
|
|
59
|
+
|
|
60
|
+
`summarize_instance` ofrece estadísticas descriptivas; no sustituye las características de grafos del estimador original.
|
|
61
|
+
|
|
62
|
+
## Etiquetas y evaluación
|
|
63
|
+
|
|
64
|
+
`SolverTargetCalibrator` calibra señales de solver en el entrenamiento y mantiene fijos esos parámetros. `evaluate_supervised` ajusta objetivo y preprocesamiento dentro de cada pliegue. Usa `base_instance_id` o grupos equivalentes para que variantes de una misma instancia no aparezcan en entrenamiento y validación. Las etiquetas miden dificultad empírica respecto al solver, hardware y límites de tiempo; no una clase de complejidad computacional.
|
|
65
|
+
|
|
66
|
+
Las correcciones de etiquetas cambian los resultados anteriores: se rechazan objetivos sin señales, se validan pesos, se renormalizan componentes disponibles y se conserva el significado absoluto del estado del solver.
|
|
67
|
+
|
|
68
|
+
## Comandos
|
|
69
|
+
|
|
70
|
+
```powershell
|
|
71
|
+
cejsp fit reference_features.json referencia.joblib
|
|
72
|
+
cejsp predict query_features.json referencia.joblib --trust-model
|
|
73
|
+
python -m unittest discover -s tests -v
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
Los JSON de la CLI contienen listas de diccionarios de características numéricas, sin identificadores de texto. Los identificadores se mantienen por separado o en el índice del DataFrame para la API por lotes.
|
|
77
|
+
|
|
78
|
+
Consulta `docs/PUBLICAR_PYPI.md` para construir, verificar y publicar.
|
|
79
|
+
|
|
80
|
+
## Estado de esta candidata
|
|
81
|
+
|
|
82
|
+
La ejecución `validacion-20261022-175907` del 22/10/2026 completó la validación: 32 pruebas sin omisiones en el entorno inicial y en instalaciones separadas de wheel y sdist, `pip check` correcto, 162 JSON válidos y flujo completo con 20 benchmarks en los tres entornos. Ambos artefactos superan `twine check --strict`. La invariancia individual/lotes se comprueba con tolerancia absoluta `1e-9` e igualdad de categorías y señales; la persistencia no cambia las puntuaciones. Esto valida funcionamiento y distribución, no precisión científica ni mejoras de rendimiento. No se ha publicado. Consultar `RESULTADOS.md` en la raíz del repositorio para el historial.
|
|
83
|
+
|
|
84
|
+
Las etiquetas necesitan el mismo identificador completo que las características. No se infieren correspondencias a partir del tamaño, configuración o semilla, ni se promedian registros repetidos automáticamente. Por ejemplo, `10_10-0-1-cp-sat` no se convierte silenciosamente en `10-10-0.pt`: la configuración y el protocolo del solver deben resolverse antes mediante una correspondencia explícita y verificada. Para variantes, incluir `base_instance_id` en todas las etiquetas o pasar `groups` a `evaluate_supervised`; el resultado incluye los índices de cada pliegue para auditar su separación.
|
|
85
|
+
|
|
86
|
+
`fit_instances(..., speed_index=...)` y `predict_instances(..., speed_index=...)` permiten la proyección explícita de velocidad. La invariancia por lote pertenece a la API inductiva; no se exige al análisis relativo por lotes.
|
|
87
|
+
|
|
88
|
+
## Nombre e interoperabilidad
|
|
89
|
+
|
|
90
|
+
La distribución se llama cejsp y el comando principal es cejsp. Los imports xai_complex y el comando anterior se conservan por compatibilidad. Las clases mantienen su identidad y los esquemas de persistencia anteriores para permitir cargar referencias guardadas; no se duplica el estimador. La disponibilidad del nombre en PyPI no está verificada. La validación completa anterior corresponde a la distribución xai-complex; CEJSP requiere repetir la validación tras el cambio de nombre.
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
## Mejora supervisada CEJSP 0.3.0
|
|
94
|
+
|
|
95
|
+
Referencia recomendada: `models/jsplib-8a6e36ef3126-v2/reference.joblib`, características estructurales y Extra Trees. Se conservan las referencias anteriores. Resultados, limitaciones y experimentos IGJSP: `evaluation/MEJORA_CLASIFICADOR.md`. El aumento con pseudoetiquetas no se incorpora por empeorar el resultado controlado. No hay validación externa de dificultad IGJSP.
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
## Estudio easy y referencias 0.4.0
|
|
99
|
+
|
|
100
|
+
Se completaron cinco rondas de nuevas variables, parámetros y selección dentro de los pliegues. No se alcanzó el 95% fuera del entrenamiento. El perfil de acierto global obtiene 84,19% exploratorio; el orientado a easy reconoce 7/15 casos con 79,41% global y precisión easy de 21,21%. Son perfiles experimentales con distintos compromisos; los modelos anteriores se conservan. Informe y comandos: `evaluation/RESULTADOS_EASY.md`; perfiles: `models/PROFILES.json`. Las sondas añaden resolución limitada durante inferencia.
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
param([string]$Python = 'python', [string]$Instancias = (Join-Path $PSScriptRoot '..\TaillardInstancesJSON'))
|
|
2
|
+
$ErrorActionPreference = 'Stop'
|
|
3
|
+
$raiz = $PSScriptRoot
|
|
4
|
+
$ejecucion = Join-Path $raiz ('validacion-' + (Get-Date -Format 'yyyyMMdd-HHmmss'))
|
|
5
|
+
New-Item -ItemType Directory -Path $ejecucion | Out-Null
|
|
6
|
+
$env:TEMP = $ejecucion
|
|
7
|
+
$env:TMP = $ejecucion
|
|
8
|
+
Start-Transcript -Path (Join-Path $ejecucion 'validacion.log')
|
|
9
|
+
function Ejecutar {
|
|
10
|
+
param([string]$Programa, [string[]]$Argumentos)
|
|
11
|
+
& $Programa @Argumentos
|
|
12
|
+
if ($LASTEXITCODE -ne 0) { throw "Error $LASTEXITCODE al ejecutar $Programa $Argumentos" }
|
|
13
|
+
}
|
|
14
|
+
try {
|
|
15
|
+
$entorno = Join-Path $ejecucion 'entorno'
|
|
16
|
+
Ejecutar $Python @('-m', 'venv', $entorno)
|
|
17
|
+
$interprete = Join-Path $entorno 'Scripts\python.exe'
|
|
18
|
+
Ejecutar $interprete @('-m', 'pip', 'install', '--upgrade', 'pip')
|
|
19
|
+
Ejecutar $interprete @('-m', 'pip', 'install', "$raiz[graphs,dev,research]")
|
|
20
|
+
Ejecutar $interprete @('-m', 'pip', 'check')
|
|
21
|
+
Ejecutar $interprete @('-I', (Join-Path $raiz 'verify_release.py'))
|
|
22
|
+
Ejecutar $interprete @('-I', (Join-Path $raiz 'validate_instance_formats.py'), (Join-Path $raiz '..'), '--output', (Join-Path $ejecucion 'instance-formats.json'))
|
|
23
|
+
Ejecutar $interprete @('-I', (Join-Path $raiz 'validate_real_inputs.py'), $Instancias, '--output', (Join-Path $ejecucion 'real-inputs.json'))
|
|
24
|
+
Ejecutar $interprete @('-I', (Join-Path $raiz 'validate_pipeline.py'), $Instancias, '--output', (Join-Path $ejecucion 'pipeline.json'))
|
|
25
|
+
$dist = Join-Path $ejecucion 'dist'
|
|
26
|
+
Ejecutar $interprete @('-m', 'build', $raiz, '--outdir', $dist)
|
|
27
|
+
$archivos = @(Get-ChildItem -LiteralPath $dist -File | ForEach-Object FullName)
|
|
28
|
+
Ejecutar $interprete (@('-m', 'twine', 'check', '--strict') + $archivos)
|
|
29
|
+
foreach ($tipo in @('wheel', 'sdist')) {
|
|
30
|
+
$smoke = Join-Path $ejecucion $tipo
|
|
31
|
+
Ejecutar $Python @('-m', 'venv', $smoke)
|
|
32
|
+
$smokePython = Join-Path $smoke 'Scripts\python.exe'
|
|
33
|
+
if ($tipo -eq 'wheel') {
|
|
34
|
+
$archivo = (Get-ChildItem -LiteralPath $dist -Filter '*.whl' | Select-Object -First 1).FullName
|
|
35
|
+
} else {
|
|
36
|
+
$archivo = (Get-ChildItem -LiteralPath $dist -Filter '*.tar.gz' | Select-Object -First 1).FullName
|
|
37
|
+
}
|
|
38
|
+
Ejecutar $smokePython @('-m', 'pip', 'install', "$archivo[graphs,research]")
|
|
39
|
+
Ejecutar $smokePython @('-m', 'pip', 'check')
|
|
40
|
+
Ejecutar $smokePython @('-I', (Join-Path $raiz 'verify_release.py'))
|
|
41
|
+
Ejecutar $smokePython @('-I', (Join-Path $raiz 'validate_pipeline.py'), $Instancias, '--output', (Join-Path $ejecucion "$tipo-pipeline.json"))
|
|
42
|
+
}
|
|
43
|
+
Ejecutar $interprete @('-m', 'pip', 'freeze')
|
|
44
|
+
Write-Output "VALIDACION COMPLETA SIN OMISIONES. Resultados: $ejecucion"
|
|
45
|
+
} finally {
|
|
46
|
+
Stop-Transcript
|
|
47
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Una instancia, cinco clases y referencias reentrenables
|
|
2
|
+
|
|
3
|
+
El flujo público de CEJSP 0.2.1 es `archivo existente → lector → características → modelo guardado → toy/easy/medium/hard/open`. La versión anterior de `ComplexityEstimator` se conserva con sus tres categorías; la nueva API es `JobShopComplexityClassifier` y necesita etiquetas supervisadas reales.
|
|
4
|
+
|
|
5
|
+
## Significado de las clases
|
|
6
|
+
|
|
7
|
+
Las cinco clases son dificultad empírica **según un protocolo declarado**, no clases de complejidad computacional. El protocolo debe definir solver, versión, hardware o entorno de referencia, criterio de éxito, límites y significado de cada etiqueta. `open` predicho no certifica que un problema sea históricamente abierto ni que no exista una solución óptima conocida. SATISFIED o alcanzar un timeout tampoco bastan para declarar un problema abierto científicamente.
|
|
8
|
+
|
|
9
|
+
No se convierten los quintiles de una puntuación de anomalía en estas cinco etiquetas. El piloto anterior mostró que la mezcla inductiva no supera al control de tamaño. Por ello se añade un clasificador supervisado directo, Random Forest balanceado, como candidato explícito, sin sustituir ni atribuir una mejora demostrada al método anterior. Sus votos no son probabilidades calibradas y así se indica en cada salida.
|
|
10
|
+
|
|
11
|
+
## Archivos admitidos
|
|
12
|
+
|
|
13
|
+
- JSON de IGJSP, JSON nativo de JSPLIB, objetos de instancia y estructura normalizada CEJSP. Los nombres y las etiquetas de JSPLIB no se usan como características.
|
|
14
|
+
- DZN con JOBS, MACHINES, SPEED, time, energy y precedence en arrays literales. La precedencia es rango por máquina, como en el modelo MiniZinc existente; el lector ordena las operaciones por esos rangos y conserva todas las velocidades. Rechaza restricciones o campos adicionales que no entiende, incluidas variantes de fechas aún no implementadas en el lector DZN, para no descartarlas silenciosamente.
|
|
15
|
+
- Taillard/JSPLIB con cabecera jobs/máquinas y pares máquina/duración, como los benchmarks existentes, con o sin extensión. También bloques Times/Machines con matrices por trabajo. Admite IDs de máquina desde cero o uno y duraciones cero. El formato no aporta energía: se marca como ausente y las características de energía/coste energético no entran en el nuevo clasificador.
|
|
16
|
+
|
|
17
|
+
Los JSON con fechas conservan el tratamiento ya existente. El extractor de grafos sigue requiriendo una velocidad explícita si hay varias y rechaza FJSP. No se declara compatibilidad con todas las variantes posibles de DZN o Taillard.
|
|
18
|
+
|
|
19
|
+
## Entrenar una referencia
|
|
20
|
+
|
|
21
|
+
Partir de `examples/training_manifest.template.json`. La plantilla tiene campos vacíos deliberadamente y no se puede entrenar sin completar el protocolo y las etiquetas. Cada ejemplo contiene un path relativo al manifiesto, una etiqueta y un identificador de instancia base para agrupar variantes en una evaluación posterior.
|
|
22
|
+
|
|
23
|
+
El manifiesto necesita `schema: cejsp.training.v1`, `model_version`, `feature_backend` (graph por defecto, graph_approx con intermediación muestreada reproducible, o summary como variante descriptiva explícita), `protocol.id`, las cinco definiciones en `protocol.class_definitions`, y `examples`. Cada ejemplo es `{ "path": "instancias/ejemplo.json", "label": "easy", "base_instance_id": "ejemplo-base" }`.
|
|
24
|
+
|
|
25
|
+
```powershell
|
|
26
|
+
cejsp train dataset/manifest.json models/reference-v1.joblib
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Se requieren ejemplos de las cinco clases y al menos dos por clase para permitir el ajuste; ese mínimo técnico no basta para validar un clasificador útil. No se entrena con labels inventadas. El artefacto guarda esquema, columnas, clases, protocolo, versión, fingerprint de entrenamiento, identificadores base, versiones de dependencias y backend de características.
|
|
30
|
+
|
|
31
|
+
## Clasificar
|
|
32
|
+
|
|
33
|
+
```powershell
|
|
34
|
+
cejsp classify instancia.json models/reference-v1.joblib --trust-model
|
|
35
|
+
cejsp classify instancia.dzn models/reference-v1.joblib --trust-model
|
|
36
|
+
cejsp classify instancia_taillard models/reference-v1.joblib --trust-model
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
La salida incluye `category`, los votos de las cinco clases, `model_version`, `label_protocol`, identificador de instancia y señal de aplicabilidad. Estar dentro de los rangos de entrenamiento no garantiza generalización. Una instancia fuera de rango se marca expresamente; no se convierte automáticamente en `open`.
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
from cejsp import JobShopComplexityClassifier
|
|
43
|
+
model = JobShopComplexityClassifier.load("models/reference-v1.joblib", trusted=True)
|
|
44
|
+
result = model.classify("instancia.dzn")
|
|
45
|
+
print(result["category"])
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Para comprobar solo lectura y normalización, sin modelo ni dependencias científicas:
|
|
49
|
+
|
|
50
|
+
```powershell
|
|
51
|
+
cejsp inspect instancia.dzn
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Reentrenar
|
|
55
|
+
|
|
56
|
+
```powershell
|
|
57
|
+
cejsp retrain dataset/manifest-v2.json models/reference-v2.joblib --previous models/reference-v1.joblib --trust-model
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Es reentrenamiento completo con el conjunto incluido en el nuevo manifiesto, no aprendizaje incremental ni acumulación automática de los ejemplos antiguos. Hay que incluir explícitamente los ejemplos anteriores que se quieran conservar. Se exige otra versión y un archivo nuevo; se conserva el modelo previo y se registra su versión. Los artefactos joblib solo deben cargarse si son de confianza.
|
|
61
|
+
|
|
62
|
+
## Referencia JSPLIB
|
|
63
|
+
|
|
64
|
+
Se ha fijado la instantánea `8a6e36ef31263d36975e56fb481e0ba04e188d6f` de ScheduleOpt/benchmarks y sus etiquetas originales. La preparación, el entrenamiento y la evaluación están en `evaluation/train_jsplib.py`. La procedencia y licencia de datos están en `data/jsplib/README.md`.
|
|
65
|
+
|
|
66
|
+
La referencia usa `graph_approx`: conserva el grafo original y sus características, con intermediación estimada sobre 100 nodos, semilla 42. Es una variante explícita, no una equivalencia numérica con la intermediación exacta. El artefacto conserva el backend y el número de muestras para usarlos también en inferencia. No se afirma una mejora de rendimiento sin una comparación controlada.
|
|
67
|
+
|
|
68
|
+
El informe y el modelo quedan en `models/jsplib-8a6e36ef3126-v1/`. El test estratificado del 20% se reserva antes del ajuste; el diagnóstico adicional deja fuera familias completas. Se eliminan duplicados de contenido y se comprueba la separación de identificadores base. La referencia final se reajusta con los 272 casos elegibles después de evaluar; las métricas de test corresponden al modelo de evaluación independiente.
|
|
69
|
+
|
|
70
|
+
```powershell
|
|
71
|
+
.\.venv\Scripts\python.exe -m cejsp classify instancia.json models\jsplib-8a6e36ef3126-v1\reference.joblib --trust-model
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
El protocolo de origen utiliza pruebas de optimalidad y tiempos de motores de referencia: toy hasta un minuto, easy hasta diez minutos, medium hasta una hora, hard más de una hora y open sin prueba de optimalidad publicada en esa instantánea. Se usan las etiquetas de la tabla literalmente; las condiciones históricas no se reinterpretan como tiempos actuales del ordenador del usuario.
|
|
75
|
+
|
|
76
|
+
Todavía se requiere evaluación externa con instancias IGJSP etiquetadas de forma independiente. Los votos del bosque no están calibrados y las clases minoritarias tienen pocos ejemplos. El informe registra las exclusiones y las métricas por clase, además de los controles de tamaño y clase mayoritaria.
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
## Actualización 0.3.0
|
|
80
|
+
|
|
81
|
+
La referencia recomendada es `models/jsplib-8a6e36ef3126-v2/reference.joblib`, backend `structural`, estimador `extra_trees`. El grafo y el estimador originales siguen disponibles. El nuevo manifiesto acepta `estimator_kind` y `n_estimators`. Véase `evaluation/MEJORA_CLASIFICADOR.md` para las comparaciones, incluidas selección anidada, familias y experimentos negativos de aumento de datos. Las métricas de la variante fija no equivalen a una evaluación externa del procedimiento de selección.
|
|
82
|
+
|
|
83
|
+
`structural` y `hybrid` añaden señales de duración, carga y rutas. El backend estructural requiere JSP de permutación y rechaza fechas y alternativas de máquina no representadas. Las semillas, los identificadores y las etiquetas no forman parte de sus características. Los modelos con estos backends usan el esquema de persistencia v3 y requieren CEJSP 0.3.0.
|
|
84
|
+
|
|
85
|
+
Se generaron 816 instancias con IGJSP 2.0.1. Su similitud no transfiere automáticamente la etiqueta del benchmark. El experimento con pseudoetiquetas empeoró los resultados y no se incorpora a la referencia recomendada. No se declara una mejora de easy ni de transferencia equilibrada entre familias.
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
## Modos de investigación 0.4.0
|
|
89
|
+
|
|
90
|
+
Ver `RESEARCH_MODES.md` para cotas, reglas constructivas, geometría, bloques críticos, sondas CP-SAT y alternativas especializadas. La persistencia nueva usa esquema v4 y conserva parámetros, pesos de decisión y presupuesto. El objetivo del 95% se evalúa fuera del entrenamiento y no está garantizado por aumentar características o workers.
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Publicación posterior
|
|
2
|
+
|
|
3
|
+
No se ha publicado. No publicar esta candidata mientras haya pruebas omitidas o comprobaciones bloqueadas. El nombre `cejsp` y la versión `0.4.1` son propuestas; su disponibilidad no está comprobada.
|
|
4
|
+
|
|
5
|
+
Desde PowerShell, ejecutar con un Python ejecutable y acceso a las dependencias:
|
|
6
|
+
|
|
7
|
+
```powershell
|
|
8
|
+
Set-Location 'D:\CODE\XAI-COMPLEX'
|
|
9
|
+
& .\pypi\VALIDAR_WINDOWS.ps1 -Python python
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
El script instala `.[graphs,dev,research]`, exige pruebas sin omisiones, comprueba los JSON existentes y el flujo completo con 20 benchmarks, construye wheel y sdist, ejecuta `twine check --strict` y prueba las dos distribuciones en entornos separados con Python aislado (`-I`). Se detiene ante cualquier error. Los resultados quedan en `pypi/validacion-FECHA/`. Si los benchmarks están en otra ubicación, usar `-Instancias 'RUTA'`.
|
|
13
|
+
|
|
14
|
+
Tras una ejecución satisfactoria, y solo cuando se autorice la publicación, seleccionar la carpeta exacta de esa ejecución:
|
|
15
|
+
|
|
16
|
+
```powershell
|
|
17
|
+
$release = Get-ChildItem .\pypi -Directory -Filter 'validacion-*' | Sort-Object Name | Select-Object -Last 1
|
|
18
|
+
$pythonRelease = Join-Path $release.FullName 'entorno\Scripts\python.exe'
|
|
19
|
+
$artifacts = @(Get-ChildItem (Join-Path $release.FullName 'dist') -File | ForEach-Object FullName)
|
|
20
|
+
& $pythonRelease -m twine check --strict @artifacts
|
|
21
|
+
& $pythonRelease -m twine upload --repository testpypi @artifacts
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
Comprobar que esa ejecución terminó con `VALIDACION COMPLETA SIN OMISIONES`. No elegir una ejecución fallida por ser la más reciente. Twine solicita las credenciales: usuario `__token__` y token específico del servicio. No guardar credenciales en el repositorio.
|
|
25
|
+
|
|
26
|
+
Comprobar TestPyPI en otro entorno, descargando el paquete sin mezclar índices:
|
|
27
|
+
|
|
28
|
+
```powershell
|
|
29
|
+
python -m venv .testpypi-check
|
|
30
|
+
& .\.testpypi-check\Scripts\python.exe -m pip download --index-url https://test.pypi.org/simple/ --no-deps cejsp==0.4.1 --dest .testpypi-download
|
|
31
|
+
& .\.testpypi-check\Scripts\python.exe -m pip install '.\.testpypi-download\cejsp-0.4.1-py3-none-any.whl[graphs,research]'
|
|
32
|
+
& .\.testpypi-check\Scripts\python.exe -I .\pypi\verify_release.py
|
|
33
|
+
& .\.testpypi-check\Scripts\python.exe -I .\pypi\validate_pipeline.py .\TaillardInstancesJSON
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Después de comprobar TestPyPI y recibir autorización para PyPI:
|
|
37
|
+
|
|
38
|
+
```powershell
|
|
39
|
+
& $pythonRelease -m twine upload @artifacts
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
Si el nombre está ocupado, cambiar `project.name` y reconstruir. Para una versión publicada, incrementar la versión en `pyproject.toml` y `src/xai_complex/__init__.py`, sincronizar la copia auxiliar de la raíz y volver a validar. Una versión publicada no se sustituye.
|
|
43
|
+
|
|
44
|
+
Documentación oficial: https://packaging.python.org/en/latest/tutorials/packaging-projects/ y https://twine.readthedocs.io/en/stable/.
|
|
45
|
+
|
|
46
|
+
El flujo de cinco clases requiere una nueva ejecución completa de VALIDAR_WINDOWS.ps1. Publicar únicamente artefactos cejsp-0.4.1* de esa ejecución, nunca los de validaciones anteriores.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# Modos de investigación CEJSP 0.4.0
|
|
2
|
+
|
|
3
|
+
La versión mantiene los estimadores anteriores. Añade variables y alternativas supervisadas explícitas; no las presenta como equivalentes numéricos del estimador científico original.
|
|
4
|
+
|
|
5
|
+
| Backend | Entrada adicional calculada | Requisito |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| structural | Distribución de tiempos, cargas y rutas | JSP de permutación, sin fechas |
|
|
8
|
+
| search | structural, cotas preemptivas y cuatro reglas constructivas | Mismo contrato; admite tiempos reales |
|
|
9
|
+
| probe | search y sonda CP-SAT | OR-Tools y tiempos enteros |
|
|
10
|
+
| landscape | search, geometría de orden y bloques críticos de un schedule constructivo | Mismo contrato estructural |
|
|
11
|
+
| trajectory | landscape, sonda corta de 0,2 unidades deterministas y otra de probe_budget | OR-Tools, tiempos enteros; mayor coste de inferencia |
|
|
12
|
+
|
|
13
|
+
Los presupuestos deterministas no son segundos de pared. Las sondas usan un worker y semilla fija; la extracción se puede paralelizar entre instancias. Una prueba temprana de optimalidad evita repetir una búsqueda más larga innecesariamente. Ni una prueba local de optimalidad ni un timeout sustituyen la etiqueta histórica del protocolo JSPLIB.
|
|
14
|
+
|
|
15
|
+
Los estimadores configurables son random_forest, extra_trees, hist_gradient, rbf_svm, ensemble, catboost, ordinal_forest, easy_specialist y selected_easy. La alternativa ordinal presupone un orden empírico de etiquetas: es una hipótesis de modelado, no una demostración de que open tenga siempre mayor dificultad intrínseca. El especialista combina un modelo multiclase con un clasificador easy frente al resto. selected_easy ordena variables mediante información mutua multiclase y easy frente al resto; la selección se ajusta exclusivamente dentro del entrenamiento de cada pliegue.
|
|
16
|
+
|
|
17
|
+
Instalación para estos estudios:
|
|
18
|
+
|
|
19
|
+
```powershell
|
|
20
|
+
python -m pip install './pypi[graphs,dev,research]'
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Los manifiestos de entrenamiento admiten n_jobs, estimator_params, class_decision_weights y probe_budget. Los pesos de decisión deben ser positivos y contener las cinco clases. Sus salidas son votos ajustados, sin calibración de probabilidad. Las configuraciones nuevas se guardan con esquema v4; requieren CEJSP 0.4.0. Los artefactos anteriores siguen siendo compatibles si coinciden sus dependencias.
|
|
24
|
+
|
|
25
|
+
Para repetir las rondas completas desde la raíz, usando carpetas de salida nuevas o conservando las anteriores:
|
|
26
|
+
|
|
27
|
+
```powershell
|
|
28
|
+
.\.venv\Scripts\python.exe evaluation\study_easy.py --workers 8 --out models\nuevo-estudio
|
|
29
|
+
.\.venv\Scripts\python.exe evaluation\analyze_easy_variables.py
|
|
30
|
+
.\.venv\Scripts\python.exe evaluation\study_specialists.py --workers 4 --out models\nuevo-especialista
|
|
31
|
+
.\.venv\Scripts\python.exe evaluation\study_trajectory.py --workers 12 --out models\nueva-trayectoria
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Los scripts de especialistas y trayectoria usan sus carpetas de resultados declaradas y no sustituyen una referencia existente. Sus rutas de cohortes son locales al repositorio. Los manifiestos finales permiten reentrenar mediante el comando público, con otra versión y salida:
|
|
35
|
+
|
|
36
|
+
```powershell
|
|
37
|
+
cejsp retrain dataset/manifest-v2.json models/reference-v2.joblib --previous models/reference-v1.joblib --trust-model
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
La selección de características, modelos y multiplicadores debe repetirse dentro de cada pliegue. El comando train o retrain solo ajusta el manifiesto: no ejecuta automáticamente la validación anidada. Ningún porcentaje del ajuste a todos los datos certifica el objetivo del 95%.
|
|
41
|
+
|
|
42
|
+
Las referencias, predicciones fuera del ajuste, planes, variables y limitaciones se conservan en models/jsplib-easy-v5, models/jsplib-easy-v6-specialists y models/jsplib-easy-v7-trajectory. El estudio está en evaluation/VARIABLES_EASY.md. Estos resultados son internos sobre una cohorte ya explorada; falta un conjunto externo etiquetado de IGJSP.
|
|
43
|
+
|
|
44
|
+
La quinta ronda se repite con `python evaluation/study_selected_easy.py --workers 8 --out models/nueva-seleccion`. El resultado conjunto está en evaluation/RESULTADOS_EASY.md. No se alcanzó el 95% fuera del entrenamiento. Para ejecutar los scripts contra la fuente actual, fijar PYTHONPATH a pypi/src y reinstalar la versión final al validar el wheel.
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# Estado de la entrega
|
|
2
|
+
|
|
3
|
+
Fecha: 22 de octubre de 2026.
|
|
4
|
+
|
|
5
|
+
## Alcance
|
|
6
|
+
|
|
7
|
+
Correcciones de XAI-COMPLEX y carpeta de distribución independiente. IGJSP no se modifica, no se incluye como dependencia y no se genera ninguna instancia. El paquete recibe instancias existentes o sus características.
|
|
8
|
+
|
|
9
|
+
Las modificaciones están preparadas en una copia: el entorno no permite escribir en D:\CODE\XAI-COMPLEX. APLICAR_CAMBIOS.ps1 comprueba hashes y prepara copias de seguridad antes de trasladarlas al repositorio original; no se ha ejecutado sobre ese directorio.
|
|
10
|
+
|
|
11
|
+
## Cambios
|
|
12
|
+
|
|
13
|
+
- Estado INFEASIBLE separado de FEASIBLE.
|
|
14
|
+
- Límites de vecinos según el número de muestras y error explícito para referencias insuficientes.
|
|
15
|
+
- Preprocesamiento y calibración del objetivo ajustados dentro de cada pliegue en los estimadores ponderados.
|
|
16
|
+
- Evaluación supervisada compartida; cada modelo de validación se entrena una vez y se reutiliza para obtener sus predicciones.
|
|
17
|
+
- Rechazo de etiquetas sin señales, pesos inválidos, identificadores ambiguos y objetivos constantes.
|
|
18
|
+
- Renormalización de pesos por señales disponibles; el estado del solver conserva su escala absoluta.
|
|
19
|
+
- Exportación de características sin eliminar la última fila ni forzar semilla cero.
|
|
20
|
+
- Retirada de la supresión global de avisos.
|
|
21
|
+
- Fechas por trabajo expandidas a sus operaciones y selección explícita de velocidad antes de construir el grafo original.
|
|
22
|
+
- Rechazo explícito de FJSP en el grafo de rutas fijas; no se convierte silenciosamente en JSP.
|
|
23
|
+
- Semilla fija en centralidad aproximada y propagación de errores de generación de grafos.
|
|
24
|
+
- Limpieza de comentarios decorativos y comprobación de que esa pasada conserva el AST.
|
|
25
|
+
- API de análisis por lotes basada en el estimador ponderado original, más variante inductiva explícita con referencia persistente.
|
|
26
|
+
|
|
27
|
+
El estimador básico estimate_complexity.py conserva su carácter experimental: se corrigen incompatibilidades dimensionales y tamaños fijos, y los identificadores arbitrarios de KMeans se sustituyen por distancia al centroide. Esta corrección cambia sus puntuaciones. Para el paquete se usa como referencia el estimador ponderado, no esa variante experimental.
|
|
28
|
+
|
|
29
|
+
## Validación
|
|
30
|
+
|
|
31
|
+
- Pruebas de contratos de entrada, fechas, velocidades, disponibilidad, etiquetas y regresiones de código ejecutadas con Python 3.12.14.
|
|
32
|
+
- 23 pruebas descubiertas: 16 pasan y 7 se omiten por dependencias ausentes.
|
|
33
|
+
- Las 7 omitidas cubren el estimador, persistencia, invariancia por lote, evaluación agrupada e integración de grafos. No se consideran aprobadas.
|
|
34
|
+
- Los contratos utilizan fixtures sintéticos. Además se comprobaron normalización y estadísticas descriptivas de los 162 JSON reales de TaillardInstancesJSON: 162 pasan tras corregir el rechazo de una operación de duración cero en orb07, presente también en el archivo original. Esta comprobación no ejecuta grafos ni el estimador, y no demuestra compatibilidad con todos los objetos de IGJSP.
|
|
35
|
+
- Compilación sintáctica de los módulos del paquete y de la copia de scripts.
|
|
36
|
+
- Construcción de wheel y sdist con setuptools. Instalación del wheel en un entorno aislado usando --no-deps; esto solo valida distribución e importaciones ligeras.
|
|
37
|
+
- No se ha podido ejecutar twine check ni instalar las dependencias ausentes: las descargas fallan con error de resolución DNS. No se ha publicado en TestPyPI ni PyPI.
|
|
38
|
+
- No hay mediciones de rendimiento ni resultados científicos nuevos. No se afirma equivalencia numérica con resultados anteriores tras corregir etiquetas y validación.
|
|
39
|
+
|
|
40
|
+
## Pendiente antes de publicar
|
|
41
|
+
|
|
42
|
+
Se ha repetido la instalación de las dependencias en un entorno separado, tanto con la configuración disponible como indicando PyPI explícitamente: falla. La consulta directa a PyPI devuelve error de resolución DNS. La caché contiene binarios para Python 3.11, pero ese intérprete devuelve acceso denegado al ejecutarlo en esta sesión; el intérprete ejecutable disponible es Python 3.12.14. No se ha eludido esa restricción ni se han sustituido las bibliotecas por simulaciones.
|
|
43
|
+
|
|
44
|
+
VALIDAR_WINDOWS.ps1 realiza la validación completa desde un PowerShell con acceso a las dependencias. Su sintaxis ha sido comprobada. No está ejecutado con éxito aquí.
|
|
45
|
+
|
|
46
|
+
Instalar .[graphs,dev], ejecutar verify_release.py sin omisiones, verificar las rutas ponderadas con los CSV reales del proyecto y probar extracción con JSON/objetos reales guardados. Ejecutar twine check, instalar el sdist y validar TestPyPI según PUBLICAR_PYPI.md. Hasta entonces esta entrega es una candidata de trabajo, no una versión completamente validada.
|
|
47
|
+
|
|
48
|
+
## Revisión antislop posterior
|
|
49
|
+
|
|
50
|
+
PASS, R-31: comentarios decorativos retirados; la pasada de comentarios verifica igualdad de AST.
|
|
51
|
+
PASS, R-36: el informe distingue resultados ejecutados y pruebas bloqueadas; no se inventan métricas.
|
|
52
|
+
Las reglas de UI, navegación, tipografía y accesibilidad no aplican a esta biblioteca Python.
|
|
53
|
+
La validación funcional de publicación permanece pendiente; no se declara un PASS global.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import json
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from cejsp import ComplexityEstimator
|
|
4
|
+
|
|
5
|
+
reference = json.loads(Path("reference_features.json").read_text(encoding="utf-8"))
|
|
6
|
+
model = ComplexityEstimator().fit(reference)
|
|
7
|
+
model.save("reference.joblib")
|
|
8
|
+
query = json.loads(Path("query_features.json").read_text(encoding="utf-8"))
|
|
9
|
+
print(model.predict(query))
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"""Real integration smoke test: IGJSP -> native JSON -> CEJSP classification."""
|
|
2
|
+
import argparse,json,time,sys
|
|
3
|
+
from importlib.util import find_spec
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from hashlib import sha256
|
|
6
|
+
from importlib.metadata import version
|
|
7
|
+
# Direct execution from a checkout does not put pypi/src on sys.path.
|
|
8
|
+
# Keep installed distributions preferred so artifact checks still test them.
|
|
9
|
+
if find_spec('cejsp') is None:
|
|
10
|
+
source = Path(__file__).resolve().parents[1] / 'src'
|
|
11
|
+
if not (source / 'cejsp' / '__init__.py').is_file():
|
|
12
|
+
raise SystemExit('CEJSP is not installed and local sources are unavailable. Install cejsp[integration] in this Python environment.')
|
|
13
|
+
sys.path.insert(0, str(source))
|
|
14
|
+
|
|
15
|
+
from IGJSP.generador import Generator
|
|
16
|
+
from cejsp import JobShopComplexityClassifier,CATEGORIES
|
|
17
|
+
from cejsp.io import load_instance
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def main():
|
|
21
|
+
p=argparse.ArgumentParser(description=__doc__)
|
|
22
|
+
p.add_argument('--model',type=Path,required=True,help='Trusted CEJSP model')
|
|
23
|
+
p.add_argument('--output',type=Path,required=True,help='Empty output directory')
|
|
24
|
+
p.add_argument('--jobs',type=int,default=6);p.add_argument('--machines',type=int,default=6);p.add_argument('--seed',type=int,default=42)
|
|
25
|
+
a=p.parse_args()
|
|
26
|
+
if min(a.jobs,a.machines)<1:p.error('Dimensions must be positive')
|
|
27
|
+
a.output.mkdir(parents=True,exist_ok=True)
|
|
28
|
+
if any(a.output.iterdir()):p.error('Use an empty output directory')
|
|
29
|
+
started=time.perf_counter()
|
|
30
|
+
obj=Generator(json=False,dzn=False,taillard=False).generate_new_instance(jobs=a.jobs,machines=a.machines,speed=1,ReleaseDateDueDate=0,distribution='uniform',seed=a.seed,instance_type='JSP')
|
|
31
|
+
path=a.output/'instance.json';obj.saveJsonFile(str(path))
|
|
32
|
+
instance=load_instance(path)
|
|
33
|
+
if len(instance['jobs'])!=a.jobs or instance['n_machines']!=a.machines:raise AssertionError('Generator dimensions differ')
|
|
34
|
+
model=JobShopComplexityClassifier.load(a.model,trusted=True)
|
|
35
|
+
prediction=model.classify(path)
|
|
36
|
+
if prediction['category'] not in CATEGORIES:raise AssertionError('Unexpected class')
|
|
37
|
+
loaded=model.load(a.model,trusted=True)
|
|
38
|
+
if loaded.classify(path)!=prediction:raise AssertionError('Reload changed prediction')
|
|
39
|
+
result={'passed':True,'generator':'IGJSP','generator_version':version('IGJSP'),'seed':a.seed,'jobs':a.jobs,'machines':a.machines,'model_sha256':sha256(a.model.read_bytes()).hexdigest(),'classification':prediction,'ground_truth_available':False,'seconds':time.perf_counter()-started}
|
|
40
|
+
(a.output/'result.json').write_text(json.dumps(result,indent=2),encoding='utf-8')
|
|
41
|
+
print(json.dumps(result,indent=2))
|
|
42
|
+
|
|
43
|
+
if __name__=='__main__':main()
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "cejsp.training.v1",
|
|
3
|
+
"model_version": "reference-v1",
|
|
4
|
+
"feature_backend": "graph",
|
|
5
|
+
"speed_index": null,
|
|
6
|
+
"protocol": {
|
|
7
|
+
"id": "",
|
|
8
|
+
"class_definitions": {"toy": "", "easy": "", "medium": "", "hard": "", "open": ""}
|
|
9
|
+
},
|
|
10
|
+
"examples": [{"path": "REPLACE_WITH_INSTANCE_PATH", "label": null, "base_instance_id": ""}]
|
|
11
|
+
}
|