Source code for experiments.jUFLP_simscores_M

"""Generates and solves the special class j-UFLP instances.

Instances and the experiment as discussed in the paper, in Section 4.2 and
Appendix F.2. Instances are generated using
:py:func:`UFLP_2_cav.gen_special_jUFLP`, which is a wrapper for function
:py:func:`darkcloud.gen_caveman_inst` for this class of instances. The
experiment is implemented in :py:func:`UFLP_2_cav.main`.

The rest of the code implemented alternative experiments (left out from the
second revision of the paper).

"""
import numpy as np
from time import time

from jUFLP_cavemen import solve_cm_jUFLP_MIP, solve_cm_jUFLP_CPPMIP_fullDDs
from jUFLP_cavemen import solve_cm_jUFLP_fullDDs
from jUFLP_utils import save_inst

from BDD import simscore
from UFLP_2_cav import gen_special_jUFLP, make_cluster_reverse_custom_matching
from UFLP_2_cav import COL_caves

from UFLP_fullDD import create_cover_DD
from UFLPOrder import UFLP_greedy_order


[docs]def main(): """The j-UFLP experiment involving instances w/different simscores.""" print("experiment, n, M, L, N, A, inst_type, linking, param, CPP_simscore, tMIP, tMIP_CPP, tDD_VS, tDD_toA, int_VS, int_VS_toA") L = 0.35 n = 2 linking = "cluster-reverse-custom" inst_type = "cavemen" k = 0 for M in [5, 8, 10, 13, 15]: for i in range(1, 10+1): i1, i2, jm = gen_special_jUFLP(n, M, L, linking, inst_type, 0.0) for param in [0.00, 0.25, 0.50, 0.75, 1.00]: k += 1 ca1 = [S for S in i1[COL_caves]] ca2 = [S for S in i2[COL_caves]] jm = make_cluster_reverse_custom_matching(ca1, ca2, param) save_inst(i1, i2, jm, f"instances/jUFLP_ss_M/inst_{M}_{param}_{k}.json") print("---") t0 = time() objMIP = solve_cm_jUFLP_MIP(i1, i2, jm) tMIP = time() - t0 print(f"✅ MIP in {tMIP:.2f} sec", flush=True) # solve with CPP MIP t0 = time() objMIP_CPP = solve_cm_jUFLP_CPPMIP_fullDDs(i1, i2, jm) tMIP_CPP = time() - t0 print(f"✅ CPP MIP in {tMIP_CPP:.2f} sec", flush=True) t0 = time() objDD_VS, int_VS = solve_cm_jUFLP_fullDDs(i1, i2, jm, "VS", True) tDD_VS = time() - t0 print(f"✅ Full DDs VS in {tDD_VS:.2f} sec", flush=True) t0 = time() objDD_toA, int_VS_toA = solve_cm_jUFLP_fullDDs(i1, i2, jm, "toA", True) tDD_toA = time() - t0 print(f"✅ Full DDs toA in {tDD_toA:.2f} sec", flush=True) assert abs(objMIP - objMIP_CPP) < 0.01, f"objMIP = {objMIP:.2f}, objMIP_CPP={objMIP_CPP:.2f}" assert abs(objMIP - objDD_VS) < 0.01, f"objMIP = {objMIP:.2f}, objDD_VS={objDD_VS:.2f}" assert abs(objMIP - objDD_toA) < 0.01, f"objMIP = {objMIP:.2f}, objDD_toA={objDD_toA:.2f}" A = sum([len(s)-1 for s in i1[0]])/2+sum([len(s)-1 for s in i2[0]])/2 # check the resulting CPP BDDs simscore S, f, c, caves = i1 S2, f2, c2, caves2 = i2 B1, _ = create_cover_DD(S, f, c, UFLP_greedy_order(S, True)) B2, _ = create_cover_DD(S2, f2, c2, UFLP_greedy_order(S2, False)) B1.make_reduced() B2.make_reduced() B1.rename_vars(jm) print(f"{k}, {n}, {M}, {L}, {len(i1[0])+len(i2[0])}, {A}, " + f"{inst_type}, {linking}, {param}, " + f"{simscore(B1.vars, B2.vars)}, " + f"{tMIP:.2f}, {tMIP_CPP:.2f}, {tDD_VS:.2f}, {tDD_toA:.2f}, {int_VS}, {int_VS_toA}", flush=True)
if __name__ == '__main__': main()