-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
102 lines (84 loc) · 4.01 KB
/
main.py
File metadata and controls
102 lines (84 loc) · 4.01 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import os, glob
from solver import *
from problem_instance import *
from solution import *
from utils import find_step
import gurobipy as gp
import time
if __name__ == '__main__':
#verobse
verbose = True
#total time available to gurobi
T_avail = 595
#NOTICE THAT INSIDE THE TWO SOLVER A 4 THREAD CONSTRAINT IS ACTIVE FOR COMPETITION REQUIREMENTS.
# Hidden/Public
inType = 'p' #'l' 'h' , 'p'
#check for gurobi version. if not 9.5.1 or .2, iterative model building too expensive.
# Get the Gurobi version
version = gp.gurobi.version()
# Check if version is 9.5.1. or .2. If not, the model building is so slow that the decomposition method makes no sense. I don't know why. we tried several machines and pre_solve options. it is always 10 times slower than 9.5.
if version[0] != 9 or version[1] != 5:
raise ValueError(f"Incompatible Gurobi version. Expected 9.5.1 or .2, but found {version[0]}.{version[1]}.{version[2]}")
else:
print("Gurobi version 9.5.2 confirmed. Proceeding...")
###########
## Selection of the dataset
###########
if inType == 'p':
foldername = 'ihtc2024_competition_instances'
filenames = [f'i{i:02}' for i in range(1, 31)] # i01 … i30
elif inType == 'h':
foldername = 'ihtc2024_final_instances'
filenames = [f'm{i:02}' for i in range(1, 31)] # m01 … m30
elif inType == 'l':
foldername = 'large_instances'
pattern = os.path.join('./datasets/', foldername, 'l*.json')
# strip extension → l35_1, l35_2, …
filenames = [os.path.splitext(os.path.basename(p))[0]
for p in glob.glob(pattern)]
filenames.sort()
else:
raise ValueError(f"Unknown inType '{inType}'")
########
## Iteration on the instances
########
#uncomment for specfic instances (check that the foldername fits)
# filenames = ['i16']
for filename in filenames:
print(f"\n|--- {filename} ---|")
t_start = time.time()
inst = InstanceGlobal(os.path.join('.', 'datasets', foldername, f'{filename}.json'))
sol_two = Solution(inst)
#step generation and actual solve
step, H = find_step(inst.N_PATIENTS,inst.N_DAYS)
#
if verbose:
print('inst: ',filename,'initial step: ', step, 'initial H: ', H)
#
# Initialize sub solvers
#NOTICE: CURRENTLY 4 THREADS CONSTRAINT IS HARDCODED INSIDE BOTH THE SOLVER.
#
sub_sSCPPAS_two = HPT_SCPPAS(**{'v': inst.N_DAYS, 'H': H, 'step': step, 'verbose': verbose})
sub_sNRA_two = NRA(**{'verbose': verbose})
# Initialized sub solvers manager
seq_solver_two = Seq_solver_two(sol_two, sub_sSCPPAS_two, sub_sNRA_two, percTimeNRA=0.1) #percTime is how much of the total time is given minimum to the NRA, here 10%
seq_solver_two.populate(inst) #populate the subsolvers with the specific instances. To be fair, when the solver is the same only a populate should be called within the loop. But the code is not do optimized rn, sorry.
#actual remaining time for the solver
remaining_time = int(T_avail - (time.time() - t_start))
###run the solver
try:
seq_solver_two.solve(res_time=remaining_time)
except ValueError as e:
print(f"Failed to solve: {str(e)}")
#########
##Solution visualization and json dump (notice that as worst case a empty solution is dumped even if unfeasible)
#########
# #This can be launched only if cpp precompiled on the validator
violations, of = sol_two.eval(light_verbose=verbose, verbose = False) #when light verbose, costs per category are printed
# print performance
print(f"{violations},{of}")
print(f"TIME: {'{:.2f}'.format(time.time() - t_start)}\n")
#uncomment to save
sol_two.json_dump(f'./results/sol_{filename}.json')