IGJSP 1.1.1__py3-none-any.whl → 1.1.3__py3-none-any.whl

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.
IGJSP/generador.py CHANGED
@@ -15,6 +15,15 @@ from pprint import pprint
15
15
 
16
16
  from scipy.stats import expon, norm, uniform
17
17
 
18
+ from importlib.resources import files, as_file
19
+
20
+ def _read_text_resource(rel_path: str, encoding: str = "utf-8") -> str:
21
+ p = files("IGJSP").joinpath(rel_path)
22
+ if not p.is_file():
23
+ raise FileNotFoundError(
24
+ f"Template Minizinc no encontrado en el paquete: {rel_path}"
25
+ )
26
+ return p.read_text(encoding=encoding)
18
27
 
19
28
  def f(x):
20
29
  return int(np.exp(-int(x)/100)*100)
@@ -28,27 +37,51 @@ def t(c):
28
37
 
29
38
  # ------- Helpers internos para el DZN -------
30
39
 
31
- def _parse_int_var(text, name, default=None):
40
+
41
+ def _parse_set_size(text, name):
42
+ """
43
+ Obtiene el tamaño de un conjunto tipo:
44
+ JOBS = 1..50;
45
+ Devuelve 50.
32
46
  """
33
- Busca una variable escalar tipo: name = 10;
47
+ m = re.search(rf'\b{name}\b\s*=\s*1\.\.(\d+)\s*;', text)
48
+ if not m:
49
+ raise ValueError(f"No se pudo encontrar el conjunto {name} = 1..N; en el fichero DZN.")
50
+ return int(m.group(1))
51
+
52
+
53
+ def _parse_speed(text):
34
54
  """
35
- m = re.search(rf'\b{name}\b\s*=\s*([0-9]+)', text)
55
+ SPEED puede ir como:
56
+ SPEED = 1;
57
+ o (por si acaso) como 1..SPEED; (aunque en tu ejemplo es un escalar).
58
+ """
59
+ m = re.search(r'\bSPEED\b\s*=\s*(\d+)\s*;', text)
60
+ if m:
61
+ return int(m.group(1))
62
+
63
+ m = re.search(r'\bSPEED\b\s*=\s*1\.\.(\d+)\s*;', text)
36
64
  if m:
37
65
  return int(m.group(1))
38
- if default is not None:
39
- return default
40
- raise ValueError(f"No se encontró la variable entera '{name}' en el fichero DZN.")
66
+
67
+ # Si no aparece, asumimos 1 (como en muchos templates tuyos)
68
+ return 1
41
69
 
42
70
 
43
- def _parse_array_var(text, name):
71
+ def _parse_array_from_arrayXd(text, name):
44
72
  """
45
- Busca una variable array tipo:
46
- name = [1, 2, 3];
47
- o
48
- name = [1 2 3];
49
- Devuelve un np.array de ints o None si no está.
73
+ Extrae la parte entre corchetes de cosas tipo:
74
+ name = array3d(...,[1,2,3,...]);
75
+ name = array2d(...,[1,2,3,...]);
76
+ name = array1d(...,[1,2,3,...]);
77
+
78
+ Devuelve np.array de ints o None si no se encuentra.
50
79
  """
51
- m = re.search(rf'\b{name}\b\s*=.*?\[(.*?)\];', text, re.DOTALL)
80
+ m = re.search(
81
+ rf'\b{name}\b\s*=\s*array[123]d\([^[]*\[\s*(.*?)\s*\]\s*\)\s*;',
82
+ text,
83
+ re.DOTALL
84
+ )
52
85
  if not m:
53
86
  return None
54
87
 
@@ -62,6 +95,41 @@ def _parse_array_var(text, name):
62
95
 
63
96
  return np.array([int(t) for t in tokens], dtype=int)
64
97
 
98
+
99
+ def _parse_array_fallback_plain(text, name):
100
+ """
101
+ Fallback para cosas tipo:
102
+ name = [1,2,3,...];
103
+ por si en algún template no se usa arrayXd.
104
+ """
105
+ m = re.search(
106
+ rf'\b{name}\b\s*=\s*\[\s*(.*?)\s*\]\s*;',
107
+ text,
108
+ re.DOTALL
109
+ )
110
+ if not m:
111
+ return None
112
+
113
+ inner = m.group(1).strip()
114
+ if not inner:
115
+ return np.array([], dtype=int)
116
+
117
+ tokens = re.split(r'[\s,]+', inner)
118
+ tokens = [t for t in tokens if t != '']
119
+
120
+ return np.array([int(t) for t in tokens], dtype=int)
121
+
122
+
123
+ def _parse_array_generic(text, name):
124
+ """
125
+ Intenta primero arrayXd(...,[...]); y si no lo encuentra,
126
+ prueba el formato plano name = [ ... ];
127
+ """
128
+ arr = _parse_array_from_arrayXd(text, name)
129
+ if arr is not None:
130
+ return arr
131
+ return _parse_array_fallback_plain(text, name)
132
+
65
133
  #################################################################################
66
134
  # #
67
135
  # JSP #
@@ -183,24 +251,46 @@ class JSP:
183
251
 
184
252
  def loadDznFile(path):
185
253
  """
186
- Carga un .dzn generado por saveDznFile y devuelve un JSP.
187
- Soporta rddd = 0, 1, 2 (sin fechas, fechas por job, fechas por operación).
254
+ Carga un .dzn generado a partir de tus templates, del estilo:
255
+
256
+ JOBS = 1..J;
257
+ MACHINES = 1..M;
258
+ SPEED = S;
259
+
260
+ time = array3d(JOBS,MACHINES,1..SPEED,[...]);
261
+ energy = array3d(JOBS,MACHINES,1..SPEED,[...]);
262
+ precedence = array2d(JOBS,MACHINES,[...]);
263
+
264
+ Opcionalmente puede contener:
265
+ releaseDate = array1d(JOBS,[...]) (rddd = 1)
266
+ dueDate = array1d(JOBS,[...])
267
+
268
+ o
269
+
270
+ releaseDate = array2d(JOBS,MACHINES,[...]) (rddd = 2)
271
+ dueDate = array2d(JOBS,MACHINES,[...])
272
+
273
+ Devuelve un objeto JSP(**sol) consistente con loadJsonFile.
188
274
  """
189
275
  with open(path, 'r', encoding='utf-8') as f:
190
276
  text = f.read()
191
277
 
192
- numJobs = _parse_int_var(text, 'jobs')
193
- numMchs = _parse_int_var(text, 'machines')
194
- speed = _parse_int_var(text, 'Speed', default=1)
278
+ # Eliminar comentarios de Minizinc (% hasta final de línea)
279
+ text = re.sub(r'%.*', '', text)
280
+
281
+ # Leer tamaños de conjuntos
282
+ numJobs = _parse_set_size(text, "JOBS")
283
+ numMchs = _parse_set_size(text, "MACHINES")
284
+ speed = _parse_speed(text)
195
285
 
196
- time_flat = _parse_array_var(text, 'time')
197
- energy_flat = _parse_array_var(text, 'energy')
198
- prec_flat = _parse_array_var(text, 'precedence')
286
+ # Leer arrays principales
287
+ time_flat = _parse_array_generic(text, "time")
288
+ energy_flat = _parse_array_generic(text, "energy")
289
+ prec_flat = _parse_array_generic(text, "precedence")
199
290
 
200
291
  if time_flat is None or energy_flat is None or prec_flat is None:
201
- raise ValueError("Faltan variables obligatorias (time, energy o precedence) en el fichero DZN.")
292
+ raise ValueError("No se pudieron leer 'time', 'energy' o 'precedence' del fichero DZN.")
202
293
 
203
- # Comprobar tamaños
204
294
  expected_te = numJobs * numMchs * speed
205
295
  if time_flat.size != expected_te or energy_flat.size != expected_te:
206
296
  raise ValueError(
@@ -218,29 +308,27 @@ class JSP:
218
308
  EnergyConsumption = energy_flat.reshape((numJobs, numMchs, speed))
219
309
  precedence = prec_flat.reshape((numJobs, numMchs))
220
310
 
221
- # Reconstruir Orden a partir de la precedencia (cada fila es posiciones 0..numMchs-1 por máquina)
311
+ # Reconstruir Orden a partir de precedence (igual que en saveDznFile)
312
+ # precedence[j, m] = posición de la máquina m en la secuencia 0..M-1
222
313
  Orden = np.zeros((numJobs, numMchs), dtype=int)
223
314
  for j in range(numJobs):
224
- # precedence[j, m] = posición de la máquina m en la secuencia
225
- # argsort da el índice de la máquina por orden de prioridad
226
315
  Orden[j, :] = np.argsort(precedence[j, :])
227
316
 
228
- # Release / Due dates (pueden no existir)
229
- release_flat = _parse_array_var(text, 'releaseDate')
230
- due_flat = _parse_array_var(text, 'dueDate')
317
+ # --- Release / Due dates (si existen) ---
318
+ release_flat = _parse_array_generic(text, "releaseDate")
319
+ due_flat = _parse_array_generic(text, "dueDate")
231
320
 
232
321
  if release_flat is None or due_flat is None:
233
- # rddd = 0
322
+ # rddd = 0 (no fechas)
234
323
  ReleaseDueDate = np.array([])
235
324
  else:
236
- # O bien vector por job, o matriz jobs x machines
237
325
  if release_flat.size == numJobs and due_flat.size == numJobs:
238
- # rddd = 1 → (numJobs, 2)
326
+ # rddd = 1: job-level
239
327
  ReleaseDueDate = np.zeros((numJobs, 2), dtype=int)
240
328
  ReleaseDueDate[:, 0] = release_flat
241
329
  ReleaseDueDate[:, 1] = due_flat
242
330
  elif release_flat.size == numJobs * numMchs and due_flat.size == numJobs * numMchs:
243
- # rddd = 2 → (numJobs, numMchs, 2)
331
+ # rddd = 2: operation-level
244
332
  ReleaseDueDate = np.zeros((numJobs, numMchs, 2), dtype=int)
245
333
  ReleaseDueDate[:, :, 0] = release_flat.reshape((numJobs, numMchs))
246
334
  ReleaseDueDate[:, :, 1] = due_flat.reshape((numJobs, numMchs))
@@ -257,6 +345,7 @@ class JSP:
257
345
  'ReleaseDateDueDate': ReleaseDueDate,
258
346
  'Orden': Orden
259
347
  }
348
+
260
349
  return JSP(**sol)
261
350
 
262
351
  def loadTaillardFile(path):
@@ -548,7 +637,7 @@ class JSP:
548
637
  with open(path, 'wb') as f:
549
638
  pickle.dump(self, f)
550
639
 
551
- def saveDznFile(self, InputDir, OutputDir):
640
+ def saveDznFile(self, InputDir, OutputDir,index):
552
641
  indexProblema = OutputDir.split("/")[-2]
553
642
  OutputDir = "/".join(OutputDir.split("/")[:-2])
554
643
  # indexProblema = os.path.basename(os.path.normpath(OutputDir))
@@ -557,40 +646,41 @@ class JSP:
557
646
  # print(self.speed)
558
647
  # for t in [0, 1, 2]:
559
648
  t = data.rddd
560
- for s in range(1,self.speed+1):
561
- s0, sf, sp = [0,s,1]
562
- time = data.ProcessingTime[:, :, s0:sf:sp]
563
- energy = data.EnergyConsumption[:, :, s0:sf:sp]
564
- precedence = np.full((data.numJobs, data.numMchs), 0)
565
-
566
- replace_data = {
567
- "machines": data.numMchs,
568
- "jobs": data.numJobs,
569
- "Speed": s,
570
- "time": str(time.flatten()).replace(" ", ", "),
571
- "energy": str(energy.flatten()).replace(" ", ", ")
572
- }
573
-
574
- if t == 1:
575
- replace_data["releaseDate"] = str([int(data.ReleaseDueDate[job, 0]) for job in range(data.numJobs)]).replace(", ", " ")
576
- replace_data["dueDate"] = str([int(data.ReleaseDueDate[job, 1]) for job in range(data.numJobs)]).replace(", ", " ")
577
- elif t == 2:
578
- replace_data["releaseDate"] = str(data.ReleaseDueDate[:, :, 0].flatten()).replace(", ", " ")
579
- replace_data["dueDate"] = str(data.ReleaseDueDate[:, :, 1].flatten()).replace(", ", " ")
580
-
581
- for job in range(data.numJobs):
582
- for i, prioridad in enumerate(range(data.numMchs)):
583
- precedence[job, data.Orden[job, prioridad]] = i
584
-
585
- replace_data["precedence"] = str(precedence.flatten()).replace(" ", ",")
586
-
587
- with open(f"./Minizinc/Types/RD/JSP/type{t}.dzn", "r", encoding="utf-8") as file:
588
- filedata = file.read()
589
- for k, v in replace_data.items():
590
- filedata = filedata.replace("{" + k + "}", str(v))
591
- os.makedirs(f"{OutputDir}/", exist_ok=True)
592
- with open(f"{OutputDir}/{indexProblema}-{t}-{s}.dzn", "w+", encoding="utf-8") as new:
593
- new.write(filedata)
649
+ # for s in range(1,self.speed+1):
650
+ s = self.speed
651
+ s0, sf, sp = [0,s,1]
652
+ time = data.ProcessingTime[:, :, s0:sf:sp]
653
+ energy = data.EnergyConsumption[:, :, s0:sf:sp]
654
+ precedence = np.full((data.numJobs, data.numMchs), 0)
655
+
656
+ replace_data = {
657
+ "machines": data.numMchs,
658
+ "jobs": data.numJobs,
659
+ "Speed": s,
660
+ "time": str(time.flatten()).replace(" ", ", "),
661
+ "energy": str(energy.flatten()).replace(" ", ", ")
662
+ }
663
+
664
+ if t == 1:
665
+ replace_data["releaseDate"] = str([int(data.ReleaseDueDate[job, 0]) for job in range(data.numJobs)]).replace(", ", " ")
666
+ replace_data["dueDate"] = str([int(data.ReleaseDueDate[job, 1]) for job in range(data.numJobs)]).replace(", ", " ")
667
+ elif t == 2:
668
+ replace_data["releaseDate"] = str(data.ReleaseDueDate[:, :, 0].flatten()).replace(", ", " ")
669
+ replace_data["dueDate"] = str(data.ReleaseDueDate[:, :, 1].flatten()).replace(", ", " ")
670
+
671
+ for job in range(data.numJobs):
672
+ for i, prioridad in enumerate(range(data.numMchs)):
673
+ precedence[job, data.Orden[job, prioridad]] = i
674
+
675
+ replace_data["precedence"] = str(precedence.flatten()).replace(" ", ",")
676
+ filedata = _read_text_resource(f"Minizinc/Types/RD/JSP/type{t}.dzn")
677
+ # with open(f"./Minizinc/Types/RD/JSP/type{t}.dzn", "r", encoding="utf-8") as file:
678
+ # filedata = file.read()
679
+ for k, v in replace_data.items():
680
+ filedata = filedata.replace("{" + k + "}", str(v))
681
+ os.makedirs(f"{OutputDir}/", exist_ok=True)
682
+ with open(f"{OutputDir}/{indexProblema}-{t}-{s}_{index}.dzn", "w+", encoding="utf-8") as new:
683
+ new.write(filedata)
594
684
 
595
685
  def saveTaillardStandardFile(self, path):
596
686
  os.makedirs("/".join(path.split("/")[:-1]),exist_ok=True)
@@ -917,7 +1007,7 @@ class FJSP(JSP):
917
1007
 
918
1008
  f.write(json_str)
919
1009
 
920
- def saveDznFile(self, InputDir, OutputDir):
1010
+ def saveDznFile(self, InputDir, OutputDir,index):
921
1011
  indexProblema = OutputDir.split("/")[-2]
922
1012
  OutputDir = "/".join(OutputDir.split("/")[:-2])
923
1013
  # indexProblema = os.path.basename(os.path.normpath(OutputDir))
@@ -926,45 +1016,44 @@ class FJSP(JSP):
926
1016
  # print(self.speed)
927
1017
  # for t in [0, 1, 2]:
928
1018
  t = data.rddd
929
- for s in range(1,self.speed+1):
930
- s0, sf, sp = [0,s,1]
931
- time = data.ProcessingTime[:, :, s0:sf:sp]
932
- energy = data.EnergyConsumption[:, :, s0:sf:sp]
933
- precedence = np.full((data.numJobs, data.numMchs), 0)
934
-
935
- replace_data = {
936
- "machines": data.numMchs,
937
- "jobs": data.numJobs,
938
- "Speed": s,
939
- "time": str(time.flatten()).replace(" ", ", "),
940
- "energy": str(energy.flatten()).replace(" ", ", ")
941
- }
942
- if t == 1:
943
- replace_data["releaseDate"] = str([int(data.ReleaseDueDate[job, 0]) for job in range(data.numJobs)]).replace(" ", ",")
944
- replace_data["dueDate"] = str([int(data.ReleaseDueDate[job, 1]) for job in range(data.numJobs)]).replace(" ", ",")
945
- elif t == 2:
946
- replace_data["releaseDate"] = str(data.ReleaseDueDate[:, :, 0].flatten()).replace(" ", ",")
947
- replace_data["dueDate"] = str(data.ReleaseDueDate[:, :, 1].flatten()).replace(" ", ",")
948
-
949
- for job in range(data.numJobs):
950
- for i, prioridad in enumerate(range(data.numMchs)):
951
- precedence[job, data.Orden[job, prioridad]] = i
952
- replace_data["precedence"] = str(precedence.flatten()).replace(" ", ",")
953
-
954
- replace_data["available_machines"] = str(data.available_machines.flatten()).replace(" ", ", ")
955
-
956
- with open(f"./Minizinc/Types/RD/FJSP/type{t}.dzn", "r", encoding="utf-8") as file:
957
- filedata = file.read()
958
- for kk, v in replace_data.items():
959
- filedata = filedata.replace("{" + kk + "}", str(v))
960
-
961
- os.makedirs(f"{OutputDir}/", exist_ok=True)
962
-
963
- with open(f"{OutputDir}/{indexProblema}-{t}-{s}.dzn", "w+", encoding="utf-8") as new:
964
- new.write(filedata)
965
- # print(f"{OutputDir}/{indexProblema}")
966
- # with open(f"{OutputDir}/{indexProblema}", "wb") as new:
967
- # pickle.dump(new_object, new)
1019
+ # for s in range(1,self.speed+1):
1020
+ s= self.speed
1021
+ s0, sf, sp = [0,s,1]
1022
+ time = data.ProcessingTime[:, :, s0:sf:sp]
1023
+ energy = data.EnergyConsumption[:, :, s0:sf:sp]
1024
+ precedence = np.full((data.numJobs, data.numMchs), 0)
1025
+
1026
+ replace_data = {
1027
+ "machines": data.numMchs,
1028
+ "jobs": data.numJobs,
1029
+ "Speed": s,
1030
+ "time": str(time.flatten()).replace(" ", ", "),
1031
+ "energy": str(energy.flatten()).replace(" ", ", ")
1032
+ }
1033
+ if t == 1:
1034
+ replace_data["releaseDate"] = str([int(data.ReleaseDueDate[job, 0]) for job in range(data.numJobs)]).replace(" ", ",")
1035
+ replace_data["dueDate"] = str([int(data.ReleaseDueDate[job, 1]) for job in range(data.numJobs)]).replace(" ", ",")
1036
+ elif t == 2:
1037
+ replace_data["releaseDate"] = str(data.ReleaseDueDate[:, :, 0].flatten()).replace(" ", ",")
1038
+ replace_data["dueDate"] = str(data.ReleaseDueDate[:, :, 1].flatten()).replace(" ", ",")
1039
+
1040
+ for job in range(data.numJobs):
1041
+ for i, prioridad in enumerate(range(data.numMchs)):
1042
+ precedence[job, data.Orden[job, prioridad]] = i
1043
+ replace_data["precedence"] = str(precedence.flatten()).replace(" ", ",")
1044
+
1045
+ replace_data["available_machines"] = str(data.available_machines.flatten()).replace(" ", ", ")
1046
+
1047
+ # with open(f"./Minizinc/Types/RD/FJSP/type{t}.dzn", "r", encoding="utf-8") as file:
1048
+ # filedata = file.read()
1049
+ filedata = _read_text_resource(f"Minizinc/Types/RD/FJSP/type{t}.dzn")
1050
+ for kk, v in replace_data.items():
1051
+ filedata = filedata.replace("{" + kk + "}", str(v))
1052
+
1053
+ os.makedirs(f"{OutputDir}/", exist_ok=True)
1054
+
1055
+ with open(f"{OutputDir}/{indexProblema}-{t}-{s}_{index}.dzn", "w+", encoding="utf-8") as new:
1056
+ new.write(filedata)
968
1057
 
969
1058
  def saveTaillardStandardFile(self, path):
970
1059
  os.makedirs("/".join(path.split("/")[:-1]),exist_ok=True)
@@ -1036,14 +1125,12 @@ class Generator:
1036
1125
  jsp_instance = JSP(jobs = jobs, machines = machines)
1037
1126
  case "FJSP":
1038
1127
  jsp_instance = FJSP(jobs = jobs, machines = machines)
1039
-
1128
+
1040
1129
  for index in range(1, size + 1):
1041
-
1042
1130
  jsp_instance.fill_random_values(speed = speed, rddd = ReleaseDateDueDate, distribution = distribution, seed = seed,tpm = tpm)
1043
1131
 
1044
1132
  # Determinar el nombre de salida basado en `outputName` y los parámetros actuales
1045
- problem_path = self.savepath.format(size = size, jobs =jobs, machines = machines, release_due_date = ReleaseDateDueDate,
1046
- speed_scaling = speed, distribution = distribution, seed=seed)
1133
+ problem_path = self.savepath.format(size = size, jobs =jobs, machines = machines, release_due_date = ReleaseDateDueDate, speed_scaling = speed, distribution = distribution, seed=seed)
1047
1134
 
1048
1135
  if not (self.json or self.dzn or self.taillard): return jsp_instance
1049
1136
 
@@ -1059,7 +1146,7 @@ class Generator:
1059
1146
  if self.dzn:
1060
1147
  pkl_path = f"{problem_path}/" + jm_path.split("/")[0] + f"_{j}x{m}_{i}.pkl"
1061
1148
  jsp_instance.savePythonFile(pkl_path)
1062
- jsp_instance.saveDznFile(pkl_path, problem_path + jm_path)#f"{j}x{m}_{i}")
1149
+ jsp_instance.saveDznFile(pkl_path, problem_path + jm_path,index)#f"{j}x{m}_{i}")
1063
1150
  os.remove(pkl_path)
1064
1151
  if self.taillard:
1065
1152
  jsp_instance.saveTaillardStandardFile(problem_path + jm_path.split("/")[0] + f"_{j}x{m}_{i}.txt")
@@ -1069,7 +1156,7 @@ class Generator:
1069
1156
  if self.dzn:
1070
1157
  pkl_path = f"{problem_path}/" + jm_path.split("/")[0] + f"_{j}x{m}_{i}.pkl"
1071
1158
  jsp_instance.savePythonFile(pkl_path)
1072
- jsp_instance.saveDznFile(pkl_path,f"{problem_path}/DZN/" + jm_path)#f"{j}x{m}_{i}")
1159
+ jsp_instance.saveDznFile(pkl_path,f"{problem_path}/DZN/" + jm_path,index)#f"{j}x{m}_{i}")
1073
1160
  os.remove(pkl_path)
1074
1161
  if self.taillard:
1075
1162
  jsp_instance.saveTaillardStandardFile(f"{problem_path}/TAILLARD/" + jm_path.split("/")[0] + f"_{j}x{m}_{i}.txt")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: IGJSP
3
- Version: 1.1.1
3
+ Version: 1.1.3
4
4
  Summary: Instance generator for JSP
5
5
  Project-URL: Homepage, https://gps.blogs.upv.es/
6
6
  Author-email: GPS-UPV <gps@dsic.upv.es>
@@ -1,4 +1,4 @@
1
- IGJSP/generador.py,sha256=vpopW1e8zwZ5H69uvCSY28KJuP-XGNM6VQPKCTawiAs,48598
1
+ IGJSP/generador.py,sha256=TJiEBaZkUSzLDn0tZJ7oMhbz2QJq51611F-v8X22oLk,50728
2
2
  IGJSP/main.py,sha256=Sia5Ss8O3HWBdshvPLJKUMaZIoQPHy6x8yzvojojPFo,2838
3
3
  IGJSP/Minizinc/Models/RD/JSP0.mzn,sha256=cfN_E3RQ6nBulGfaOOYTd-zAgA5SI6E2saDlYtKCflg,2282
4
4
  IGJSP/Minizinc/Models/RD/JSP1.mzn,sha256=5B8cyw2WyKR8yEL1fFd0TaCAVhjPoxEJRJDPPEjJGEk,2840
@@ -12,7 +12,7 @@ IGJSP/Minizinc/Types/RD/FJSP/type2.dzn,sha256=Wz1MnkSL5GUPsbh1eq0leoaQRImkNqQqkX
12
12
  IGJSP/Minizinc/Types/RD/JSP/type0.dzn,sha256=wNuPQkXBXPSpPaPz2WFhp4pGDgfSimtg4I93UfwC01Q,263
13
13
  IGJSP/Minizinc/Types/RD/JSP/type1.dzn,sha256=Xbt9StzCgEqqh_HS9tWGrTVtu-OEnf5Yq5Ty91AkzoM,333
14
14
  IGJSP/Minizinc/Types/RD/JSP/type2.dzn,sha256=L2nc7bPJEhyuaEwgw0ZCpC52CpVJILQU_WQdKn8GUZs,379
15
- igjsp-1.1.1.dist-info/METADATA,sha256=JtfzaTnLrHW2GMG__daue2UjaEjh9_0UwgDMFDjVCRI,10609
16
- igjsp-1.1.1.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
17
- igjsp-1.1.1.dist-info/licenses/LICENSE,sha256=f7RDRO-z_nMoooAya7NAb8sXtrHR6WnttYtyUc9fB-c,1116
18
- igjsp-1.1.1.dist-info/RECORD,,
15
+ igjsp-1.1.3.dist-info/METADATA,sha256=qWUwuqSmPDChTMxgy_VbRSbUyclj5oibJCKDp6B3YXQ,10609
16
+ igjsp-1.1.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
17
+ igjsp-1.1.3.dist-info/licenses/LICENSE,sha256=f7RDRO-z_nMoooAya7NAb8sXtrHR6WnttYtyUc9fB-c,1116
18
+ igjsp-1.1.3.dist-info/RECORD,,
File without changes