From 53095409249e86837ffe2d4975f66b2354bef009 Mon Sep 17 00:00:00 2001 From: "Risbud, Sumedh" Date: Thu, 4 May 2023 16:04:34 -0700 Subject: [PATCH] Sparsification attempt #1: DistProxy with sign inversion and max cut-off Signed-off-by: Risbud, Sumedh --- .../optimization/apps/vrp/quality_sparsity.py | 79 +++ src/lava/lib/optimization/apps/vrp/solver.py | 61 ++- .../apps/vrp/test_dist_sparsification.py | 504 ++++++++++++++++++ .../apps/vrp/utils/q_matrix_generator.py | 28 +- 4 files changed, 642 insertions(+), 30 deletions(-) create mode 100644 src/lava/lib/optimization/apps/vrp/quality_sparsity.py create mode 100644 src/lava/lib/optimization/apps/vrp/test_dist_sparsification.py diff --git a/src/lava/lib/optimization/apps/vrp/quality_sparsity.py b/src/lava/lib/optimization/apps/vrp/quality_sparsity.py new file mode 100644 index 00000000..b8f5be7d --- /dev/null +++ b/src/lava/lib/optimization/apps/vrp/quality_sparsity.py @@ -0,0 +1,79 @@ +import numpy as np +import networkx as ntx +import argparse +from lava.lib.optimization.apps.vrp.problems import VRP +from lava.lib.optimization.apps.vrp.solver import VRPSolver, VRPConfig, \ + CoreSolver + + +def main(j=0): + max_dist_cutoff_fraction_list = np.around(np.geomspace(1.0, 0.1, + 15), 2).tolist() + max_dist_cutoff_fraction_list.reverse() + np.random.seed(42313) + max_dist_cutoff_fraction_list = [0.0, 0.1, 0.12, 0.14, 0.16, 0.19, + 0.23, 0.27, 0.32, 0.37, 0.44, 0.52] + dist_sparsity_list = [] + dist_proxy_sparsity_list = [] + total_cost_list = [] + frac_wp_clustered_list = [] + print(f"Loading vrp_instance_{j}.dat") + all_coords = np.loadtxt(f"vrp_instance_{j}.dat") + v_c = [tuple(coords) for coords in all_coords[:10, :].tolist()] + w_c = [tuple(coords) for coords in all_coords[10:, :].tolist()] + vrp_instance = VRP(node_coords=w_c, vehicle_coords=v_c) + solver = VRPSolver(vrp=vrp_instance) + print(f"Iterating over cutoff fractions\n") + for cutoff_factor in max_dist_cutoff_fraction_list: + scfg = VRPConfig(backend="Loihi2", + core_solver=CoreSolver.LAVA_QUBO, + max_dist_cutoff_fraction=cutoff_factor, + hyperparameters={}, + target_cost=-1000000, + timeout=10000, + probe_time=False, + log_level=40) + try: + clusters, routes = solver.solve(scfg=scfg) + except ValueError: + routes = dict( + zip( + range(1, vrp_instance.num_vehicles + 1), + [[-1]] * vrp_instance.num_vehicles + ) + ) + dist_sparsity_list.append(solver.dist_sparsity) + dist_proxy_sparsity_list.append(solver.dist_proxy_sparsity) + flat_waypoint_list = [] + total_cost = 0 + for route in routes.values(): + flat_waypoint_list.extend(route) + try: + route_cost = ntx.path_weight( + solver.problem.problem_graph, route, weight="cost") + except ntx.exception.NetworkXNoPath: + route_cost = -1 + total_cost += route_cost + flat_waypoint_list.sort() + frac_wp_clusered = np.sum(np.in1d(np.arange(11, 111), + flat_waypoint_list)) / 100 + frac_wp_clustered_list.append(frac_wp_clusered) + total_cost_list.append(total_cost) + + np.savetxt(f"problem_{j}_dist_sp.dat", + np.array(dist_sparsity_list), fmt="%.3f") + np.savetxt(f"problem_{j}_distpr_sp.dat", + np.array(dist_proxy_sparsity_list), fmt="%.3f") + np.savetxt(f"problem_{j}_total_cost.dat", + np.array(total_cost_list), fmt="%.3f") + np.savetxt(f"problem_{j}_frac_wp_clustered.dat", + np.array(frac_wp_clustered_list), fmt="%.3f") + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(prog="quality_sparsity.py") + parser.add_argument("prob_num", type=int, choices=list(range(15))) + args = parser.parse_args() + print(f"\n------------------\nProblem number: " + f"{args.prob_num}\n------------------\n") + main(j=args.prob_num) diff --git a/src/lava/lib/optimization/apps/vrp/solver.py b/src/lava/lib/optimization/apps/vrp/solver.py index 49bf8a53..53f5c7b4 100644 --- a/src/lava/lib/optimization/apps/vrp/solver.py +++ b/src/lava/lib/optimization/apps/vrp/solver.py @@ -73,6 +73,7 @@ class VRPConfig(SolverConfig): """ core_solver: CoreSolver = CoreSolver.VRPY_CPU + max_dist_cutoff_fraction: float = 1.0 class VRPSolver: @@ -80,6 +81,8 @@ class VRPSolver: """ def __init__(self, vrp: VRP): self.problem = vrp + self.dist_sparsity = 0. + self.dist_proxy_sparsity = 0. def solve(self, scfg: VRPConfig = VRPConfig()) -> \ Tuple[npty.NDArray, Dict[int, List[int]]]: @@ -127,9 +130,11 @@ def _prepare_graph_for_vrpy(g): g.add_edge("Source", n, cost=cost_src_to_nod) g.add_edge(n, "Sink", cost=cost_nod_to_snk) return g - vrp = VehicleRoutingProblem(self.problem.problem_graph) - vrpy_is_installed = not hasattr(vrp, "vrpy_not_installed") - if scfg.core_solver == CoreSolver.VRPY_CPU and vrpy_is_installed: + if scfg.core_solver == CoreSolver.VRPY_CPU: + vrp = VehicleRoutingProblem(self.problem.problem_graph) + vrpy_is_installed = not hasattr(vrp, "vrpy_not_installed") + if not vrpy_is_installed: + raise ImportError("VRPy is not installed.") # 1. Prepare problem for VRPy graph_to_solve = self.problem.problem_graph.copy() graph_to_solve = _prepare_graph_for_vrpy(graph_to_solve) @@ -162,17 +167,22 @@ def _prepare_graph_for_vrpy(g): self.problem.node_coords # number of binary variables = total_num_nodes * num_clusters mat_size = len(node_list_for_clustering) * self.problem.num_vehicles - Q_clust = QMatrixVRP(node_list_for_clustering, - num_vehicles=self.problem.num_vehicles, - problem_type=ProblemType.CLUSTER, - mat_size_for_random=mat_size, - lamda_dist=1, - lamda_wypts=100, - lamda_vhcles=100, - lamda_cnstrt=1, - fixed_pt=True, - fixed_pt_range=(-128, 127), - profile_mat_gen=False).matrix.astype(int) + q_clust_obj = QMatrixVRP( + node_list_for_clustering, + num_vehicles=self.problem.num_vehicles, + problem_type=ProblemType.CLUSTER, + mat_size_for_random=mat_size, + lamda_dist=1, + lamda_wypts=100, + lamda_vhcles=100, + lamda_cnstrt=1, + fixed_pt=True, + fixed_pt_range=(-128, 127), + max_dist_cutoff_fraction=scfg.max_dist_cutoff_fraction, + profile_mat_gen=False) + Q_clust = q_clust_obj.matrix.astype(int) + self.dist_sparsity = q_clust_obj.dist_sparsity + self.dist_proxy_sparsity = q_clust_obj.dist_proxy_sparsity # 2. Call Lava QUBO solvers prob = QUBO(q=Q_clust) solver = OptimizationSolver(problem=prob) @@ -203,17 +213,18 @@ def _prepare_graph_for_vrpy(g): node_idxs[0] >= self.problem.num_vehicles] nodes_to_pass = np.array(node_list_for_clustering)[node_idxs, :] nodes_to_pass = [tuple(node) for node in nodes_to_pass.tolist()] - Q_VRP = QMatrixVRP(nodes_to_pass, - num_vehicles=1, - problem_type=ProblemType.TSP, - mat_size_for_random=matsize, - lamda_dist=1, - lamda_wypts=1, - lamda_vhcles=1, - lamda_cnstrt=100, - fixed_pt=True, - fixed_pt_range=(-128, 127), - profile_mat_gen=False).matrix.astype(int) + Q_VRP = QMatrixVRP( + nodes_to_pass, + num_vehicles=1, + problem_type=ProblemType.TSP, + mat_size_for_random=matsize, + lamda_dist=1, + lamda_wypts=1, + lamda_vhcles=1, + lamda_cnstrt=100, + fixed_pt=True, + fixed_pt_range=(-128, 127), + profile_mat_gen=False).matrix.astype(int) tsp = QUBO(q=Q_VRP) tsp_solver = OptimizationSolver(problem=tsp) scfg.hyperparameters.update({ diff --git a/src/lava/lib/optimization/apps/vrp/test_dist_sparsification.py b/src/lava/lib/optimization/apps/vrp/test_dist_sparsification.py new file mode 100644 index 00000000..caa07145 --- /dev/null +++ b/src/lava/lib/optimization/apps/vrp/test_dist_sparsification.py @@ -0,0 +1,504 @@ +import os +import unittest +from pprint import pprint + +import numpy as np +import networkx as ntx + +from lava.lib.optimization.apps.vrp.problems import VRP +from lava.lib.optimization.apps.vrp.solver import VRPConfig, VRPSolver, \ + CoreSolver + + +def get_bool_env_setting(env_var: str): + """Get an environment varible and return + True if the variable is set to 1 else return + false + """ + env_test_setting = os.environ.get(env_var) + test_setting = False + if env_test_setting == "1": + test_setting = True + return test_setting + + +run_loihi_tests: bool = get_bool_env_setting("RUN_LOIHI_TESTS") + + +class testVRPDistSparsification(unittest.TestCase): + def setUp(self) -> None: + # random_coords = [(-4.059279987377371, 0.2634993055357767), + # (1.1281795944956552, 5.175621446427423), + # (-0.8626467020430133, 5.727146195588083), + # (2.3791079555888217, -2.2547317771592095), + # (3.053302915576018, 0.36798536497952783), + # (-0.22339731305343918, 5.319799186860349), + # (-3.4431900180644286, -1.6191362826484954), + # (3.05995997975835, -2.5296738649944155), + # (1.9048734589160006, 5.507348983829996), + # (-3.7669032685368173, 0.1433405949009186), + # (2.9599311367234677, 0.07330845789952478), + # (2.8731937708912034, 3.613046957300967), + # (-0.5592236103337909, -0.04866302726238196), + # (5.334242845817538, -0.5490183333619033), + # (-0.036373105228991766, -3.081158827096279), + # (5.199355204765913, -3.836811819628549), + # (-2.5533156562157724, -1.3221544936814427), + # (5.448831456433722, 3.899719632699414), + # (2.999317294974545, -0.4365261165579041), + # (-0.5180904879766037, -3.418875637867406), + # (-1.462267018922939, -6.728964204480666), + # (-1.0347477972933041, -1.9444096507916828), + # (0.6581008628630651, -1.7716209729930517), + # (-5.060100087143226, 2.0217042657879998), + # (-0.9835631531265923, 4.050955713025324), + # (1.2048318312684199, -5.502342417142779), + # (6.329076552612886, 5.7486253197623585), + # (-2.2276676875099293, -3.6389985798567235), + # (1.993613940536369, -0.3588445607027819), + # (-3.5391579651031213, -1.1990888209958), + # (-2.331834185017833, -2.2094234365134726), + # (-2.1928696559536913, 3.677093949140608), + # (2.123544520470039, -5.0823789866008), + # (1.3902120438270305, -1.966056350929448), + # (3.6518257611208105, 2.9742678453378923), + # (2.9759583027143934, -3.530090726522263), + # (-1.4197204251923188, -2.1462687677171206), + # (-0.09046648257795031, 0.8039307556144333), + # (-1.2890305928047077, 0.8130150435870644)] + random_coords = [(2.991856515417419, -0.11050038434490164), + (2.5679709437773095, 1.5676236042418639), + (-1.8016389889175777, -3.3550307255934344), + (-0.8976805164432626, 3.046604228122359), + (-3.1231063818908753, 3.129819006089811), + (0.8799491313962184, -4.313675830903533), + (1.6092274391447396, 4.117115520339513), + (2.186799971707968, -2.557091141688365), + (2.9123867767281206, 1.1755462797667684), + (-0.3468771713801038, -0.712666777234486), + (3.8779502661682983, 0.976491715869631), + (1.49346341409179, -1.3629817863533247), + (0.6180682851308862, 0.027494334205765723), + (4.384612588810176, -0.8795884084897176), + (2.787370317827694, -3.3296655066928613), + (-0.4057384410636953, 2.371680420327916), + (-4.1036075184923, 2.9538106552174805), + (-1.211522662600154, -1.1393936745648783), + (-3.799408317577336, 3.975432484413118), + (0.8315088452685997, -2.5465708645409837), + (-0.756920685347922, 3.709581626261972), + (1.2133060735243912, -1.572304045405462), + (-2.3729296438434124, -0.33246047123304157), + (1.4993871735792947, -1.9118069720847144), + (-3.1297943908487413, -0.919487587314894), + (-0.11218098923134034, -0.4032396849364229), + (-3.8132305257213064, -4.133125150701183), + (1.2682705806121461, 5.321194469916061), + (-2.379178062012721, 0.6658860135705608), + (2.0256804961744237, -3.3415529477996757), + (2.790348213938001, -1.8692795717734145), + (4.9606163853863725, -0.5265835671570405), + (4.648900888146808, -0.16386955604923836), + (5.8757124450826606, 3.4272355740538596), + (-3.195556127237863, 3.584277804440741), + (0.3366614338539774, -4.3598294996830935), + (-2.501580957662942, 0.8224360094817964), + (-1.0172191050839072, 1.7140410461985431), + (0.0918741331942179, -3.9532405653633376), + (0.15301766951643242, -2.7653198650744075), + (0.506615222601189, -5.066226216307449), + (1.1676369557403308, 2.1621489618954843), + (3.712078330536908, -0.12337341255031233), + (-5.319625978810217, 0.8490052714306975), + (-2.4964026003825124, -1.9299866335514673), + (1.6831819463901412, 2.3669816755158966), + (1.3191300800782602, 0.30199692392453603), + (3.3117487676553186, 0.13152369597185126), + (-2.414038918513469, 0.5690764254921222), + (-2.093364275879506, -0.2229336107014696), + (0.34269153143496744, -1.998252238546634), + (-0.28256368439270674, -3.533949864428059), + (-6.262428113724329, 1.8010538180981506), + (2.2815531259843693, -3.116995707251067), + (1.0943650722414975, 0.35345372032633293), + (-3.203609150899414, -4.2581155430547355), + (6.058543418591659, 4.051262743839964), + (0.010264316343140432, 3.7586940086587766), + (0.6400828080787551, -2.1893050666819813), + (0.8793880658761989, -0.3215818818910303), + (0.43919412386448253, 0.7051678365357834), + (-3.6925017798242883, 1.5173706259618702), + (1.746500074071198, -2.3627461137016104), + (-0.04534774715160189, 0.18424109025001853), + (-1.8892257870843019, 2.0859022184850784), + (2.1289729532516777, 0.3162185902486465), + (-4.648098820965475, 1.5530999638549243), + (0.9695336842644459, 0.23971935599294375), + (-1.7504152466516185, -3.440897905580605), + (1.659889313440638, 1.0186822162379063), + (1.0501670073143365, -0.09591486408126151), + (2.6176430106508928, -0.16935655734187202), + (-3.738301068591758, -1.1860016888406353), + (6.500632325311578, 2.560058057050909), + (-2.882058167709302, -2.4112421608985977), + (-0.38845608996541525, 0.08698827860993427), + (0.9386309332833571, 2.7553955674301864), + (0.5164810542496611, 0.4829847920533036), + (-0.6832264743050591, 2.0038007141015486), + (-0.7037195551498648, 2.1291495007323604), + (-7.0453180479827235, -2.8855866184709216), + (-0.7283567475967655, 4.158623388018567), + (-0.44191920505469917, -3.28668528717386), + (0.6164462843068644, -3.388761319758586), + (3.95592225568344, 0.6005274769499239), + (-4.922269936399404, 3.7379580587935353), + (-3.615823639625977, 2.8623118874896427), + (0.44403626552995656, -2.3108086579897944), + (-6.799240374090035, -1.4279812101785787), + (-3.0702397743808083, -1.25646852047276), + (3.001555651283704, -0.32608426803641966), + (-4.511302033404249, 3.627975373099667), + (-0.5378019118853501, -3.283724173507662), + (2.789812124599525, 1.3060958455107008), + (-3.32215913463912, 3.2123379444928464), + (4.515080623690555, 2.070772708849698), + (-2.2192339177414455, -1.3067777654533945), + (1.191759841837553, 3.914269265954602), + (2.5538694766899113, 0.636389766732259), + (7.0071245531968405, 2.1183383513507232), + (5.066953331263132, -0.8779997618370219), + (4.29198140555932, 2.927928628358796), + (2.031566034973002, 3.431611348511465), + (3.9135828841627456, 3.968941814653552), + (-2.6488685028386945, 1.5754019062140077), + (-1.520139491063997, 3.6712710897064786), + (-4.4104703542063755, 3.2943735648889727), + (0.21941679259086458, 0.9244579959228933), + (-0.37755105327870664, 0.772840592723555), + (2.3099287348633206, -1.700028273589832)] + # random_coords = [(0.0013715653786340355, -1.766090465685806), + # (-0.34266312945214866, -2.4753942588482136), + # (-4.693520189849252, -3.2572711051063266), + # (-1.5530003929202858, 1.8267707657218284), + # (-1.4449574466924517, -1.1797218516712675), + # (0.6816201651963296, 1.7600664356256401), + # (-0.32741897082180654, -0.9338578152081449), + # (-0.6970692558043043, -0.5251355071165966), + # (-1.0670929172198027, 4.057952379313232), + # (-1.6756100782244938, -0.3614957648451179), + # (-3.561046932723447, -6.088680802628419), + # (-0.1942954736130595, 4.192149852696951), + # (2.596109235149104, 7.228468316553727), + # (-1.43995873559478, 3.547876444193263), + # (0.6374902695844188, -0.9290614073957163), + # (1.0682167227940824, 1.5568472378494498), + # (-1.2290497256305672, -4.343363534571969), + # (-2.352251922999595, -1.654973860664863), + # (-4.551615404206807, 0.818750945654271), + # (-1.1263144734574033, 0.4787455425456515), + # (1.4070411171939334, -3.5792647367607575), + # (5.015718771190926, 0.2773466051717229), + # (5.920369079352397, -2.8741126424719345), + # (1.105634700632329, -5.204633744912772), + # (-4.051091513146433, 2.612683775619727), + # (1.2266833134677033, 2.187216919491237), + # (1.124936441979134, 0.4579781225529451), + # (-2.128276415433442, -3.357793585974374), + # (4.150170456143834, -0.6070221426508202), + # (0.3893093731420886, -0.6500739607656006), + # (-3.448881623136688, 6.935576703395294), + # (0.9283813764665134, -0.17669615904071764), + # (0.6504617416630065, -2.1984409195740495), + # (-2.3735668256719014, 4.634518993162795), + # (3.122848922372218, -2.090417798184795), + # (0.27600063269319763, 1.6214607550436286), + # (-2.0051151117341712, -2.617243004690433), + # (-1.8636584489440242, 2.878763916870344), + # (-0.0511177088999983, -3.7299923658158893), + # (-5.503560484508451, -0.8568926648719848), + # (-3.501663217548934, 5.173789429760431), + # (-0.1484170668970504, -2.5136027573462436), + # (-1.037185830160215, -1.0547319506704071), + # (-4.045481805330389, 2.4062584550786115), + # (-3.5462863872349866, 0.12850498992711465), + # (3.2550563574754046, -1.2981493952789673), + # (-4.066118098815235, 1.9623218142601222), + # (-3.247650472561274, -3.6993849974207382), + # (4.546357663532353, -1.6621401090589), + # (4.4770486515262, -2.19828663903981), + # (-0.7831770751891077, 0.9145026463646793), + # (0.16133964745233492, 2.920876070602729), + # (0.0832259076523992, 1.1695093547376343), + # (-3.0454271077774524, -1.231203508184302), + # (3.290674133216597, 0.5044807492940218), + # (-4.327109153140503, -0.6951283909181822), + # (7.217951537473272, 3.3611811864042345), + # (-0.3219626600554809, 1.8583397932451393), + # (-2.1761725004905177, 2.508976502436387), + # (0.10349319693421494, -2.1027133563041702), + # (-5.229710338679247, 0.6695038623576196), + # (-2.377665850933327, 1.0002733402563928), + # (2.254760383990523, -3.5875284818997653), + # (-1.6422702435081766, -3.070194415830275), + # (-1.314984238149073, 1.1064054263556422), + # (1.1708620233533624, 2.5319948422384875), + # (-1.9144934197661385, 1.1015147832527887), + # (-1.0009710682919724, 1.6462900177424227), + # (-0.03565177602979486, -2.090777812546629), + # (1.2190325890749212, 3.2599396627188266), + # (-0.9439643152467116, -4.315428528879569), + # (7.292617386033655, -2.0597996893908648), + # (0.8351720776023599, -5.860374930336576), + # (-3.638712600195865, -5.07656561255765), + # (-5.370564625591592, -3.7429807465983864), + # (-2.8181850080000523, 2.9362719781904807), + # (1.1479597371038013, 4.444868773149894), + # (-1.5881762204741345, -2.9383299478508063), + # (4.283487056881703, -2.6254024454086884), + # (-0.9989722280304122, 1.689551919325559), + # (1.5561451734334577, -0.34682840022863376), + # (-5.827548771121833, -0.8192796509022239), + # (-0.33281088214423754, -5.170100663241528), + # (-3.666642368404439, -0.7702705221485835), + # (-1.1377996517021962, -4.729458287497919), + # (-2.697274051849512, -0.8718203980726469), + # (0.24987669461026468, -0.07545931648190082), + # (-2.839055840207317, -3.1689543890441323), + # (-0.9937439112363067, 3.3768558855577946), + # (-1.8458054384292377, -6.702011937359167), + # (-0.4690504056321787, -5.920371750183765), + # (-2.629302013308446, 1.085385361210892), + # (4.572760732120296, 0.6086419195062464), + # (0.30748285904867156, 2.8752133750757416), + # (2.7460414219074023, -0.38786371255821767), + # (3.6164548106003, 2.090215514105796), + # (2.314837818653782, 5.796586508974916), + # (2.9050903897902836, -3.771366840888569), + # (6.055336528949722, 0.880779171830327), + # (-0.5426988936103078, 1.9778931808935054), + # (-2.8904197348396297, -0.7529500776492766), + # (1.4227105328666232, 3.338850459299348), + # (3.751961365185884, 1.1664259642725452), + # (-3.00049629253815, 3.9030150824289445), + # (0.28669684811724205, -1.4880518982659976), + # (5.195292279232718, -1.7087640293120172), + # (2.4000163075684995, 0.697351495006586), + # (0.4381486424131972, 7.609911970558635), + # (-1.0566637598833768, 3.090169720142662), + # (1.0997219785114174, 3.442171438476625), + # (2.509710299742314, 1.3929348288998376), + # (4.456881687438153, -4.625083675109402), + # (-5.171015923112717, 0.6030451782098241), + # (-2.9077839401903915, 3.1967870189235605), + # (-5.55544881794123, -0.4622566918082237), + # (-1.008138704539809, -5.285594462990953), + # (3.326946188580372, 0.2827131775098244), + # (1.4476762587522776, 1.9867182890833406), + # (-2.212596268489155, 4.410401027222368), + # (0.6783880370756125, -2.979606011073427), + # (-0.6954639165027043, -2.094533916958812), + # (-0.48860068037415816, 0.16281207332002254), + # (-2.8959810613172245, 4.646153900229714), + # (5.798683345524347, 1.1478775378616473), + # (5.999247987742309, 3.0558632728819903), + # (1.9762946431866413, -0.6517637518819401), + # (2.445556913714418, 1.3289522500822286), + # (2.4423666053459323, -0.4537277673516048), + # (0.28807338862963894, 6.395442695250971), + # (-5.015973505756573, 1.8135204325575702), + # (0.4278567101094991, -0.21224929350993382), + # (-1.362550916021221, -0.04288272708181361), + # (7.456283972568759, 0.2881023377001761), + # (3.295990995338922, 3.082718460623291), + # (-0.16315116793830114, -3.232750445795265), + # (3.2455343361227826, -1.404625624434184), + # (-2.437292480599277, 0.30490132227692557), + # (3.917457302243241, -0.06470706134982204), + # (2.2301272255361986, -1.6850707115914318), + # (-5.440110751349447, -1.0173293077835155), + # (2.1187860901785953, -0.5270432972447114), + # (2.862142433414987, -5.564176788784485), + # (-0.6116001845411358, 3.68030298692468), + # (-3.2537223821467416, -0.8786625136356183), + # (-1.489843969880974, 0.7377310031105101), + # (-2.753038676163625, 1.5362835385442135), + # (1.5461281199083752, -4.082210593564568), + # (0.2535034031261741, 0.37019744487253253), + # (-4.079050554319265, -0.865466313062612), + # (2.9792441602374375, -0.11754310680996924), + # (-4.9342057055574005, -3.1462451868385672), + # (-4.731795985391497, -0.25954849976530137), + # (3.597922437426437, -1.926433028313887), + # (4.321336547166203, -2.6358644358897454), + # (-0.8311119391627562, -1.3635979640909033), + # (0.3968943981192229, 1.9288238075291808), + # (-2.449465675603142, 2.206270762681031), + # (-0.33132013872628974, -2.50346938101275), + # (3.9462383654492497, -0.465586958142431), + # (5.00157584627323, 1.8912927407228775), + # (-2.65394960852674, 2.6920720646174563), + # (-2.3140866789895465, 0.23580416542066313), + # (0.8168293058261784, 0.9929642944282018), + # (-0.35680462444079786, -3.1994625826919187), + # (-1.638352226129795, -0.9241786197989709), + # (4.175158688601477, 5.572757388874937), + # (-0.2913904030715663, 1.2181388855546926), + # (2.660269998141673, 2.837841808525315), + # (2.7247922316096123, 0.947695592023889), + # (-2.6856928274935115, -0.25347221093199884), + # (6.7196021101868, -4.3827649853628285), + # (-4.772052170621471, 2.6607743236733437), + # (1.9292586312897804, -3.9931619741232156), + # (-0.4388157006050494, -5.043290547980813), + # (5.232690702382704, 1.0243607295763857), + # (-6.3239425277183505, -1.2997404043452856), + # (-1.7200437454967854, -3.018912987628096), + # (-2.144313154494279, 7.501876965034557), + # (-5.972171694727698, -1.2279463606641798), + # (-3.8417150415655983, -0.2809269216314173), + # (-0.16915509366750076, -6.762108824640015), + # (-1.3041279482778065, -3.1992051656973732), + # (3.707260524032333, 4.701473571275248), + # (4.257187014140493, 3.131115172352386), + # (-1.5881773124745213, 3.789164798252524), + # (-0.44460456725748165, 3.2204701803319704), + # (1.5033320592202104, -1.9163132100781124), + # (1.4940583311590838, 1.5193273055190986), + # (0.49075522016553297, -1.6882016198922103), + # (2.7683462267918046, 4.332870363738882), + # (7.120480083803914, -2.078209577503846), + # (2.8988610435165816, -0.15906424194789923), + # (4.295257892684736, -6.267914313475613), + # (-1.5907040835723607, -0.3231758863728872), + # (1.3790168530042601, 0.9239076418855561), + # (3.1760701030165803, -2.2434780186492405), + # (-5.7182531886262575, 2.4150216721174322), + # (-1.9928122475773424, 6.209537370396051), + # (0.5011051607175588, -4.104973898526319), + # (2.684956062639741, -5.44101099937947), + # (-2.353792003189969, 0.1684974482464803), + # (-2.5935482246404327, -0.05501381997133632), + # (2.5630325802546547, 1.5668997488146061), + # (0.5054697387979711, 9.83613381588339), + # (2.3001881689236843, -1.7578027175591457), + # (1.42436070412109, -3.7677436960454327), + # (0.20658239098338332, -1.3594575870606922), + # (2.258188803106446, -4.234272821906978), + # (-8.471134017253947, 1.6151800418765414), + # (-1.9149940909525662, 1.4741554886517858), + # (2.1736370153629707, 5.428517433074987), + # (2.5345026885993693, -2.7617963632390503), + # (-1.0413244923148608, -2.3207548720589157), + # (-2.199472056554569, 3.220375091208529), + # (-2.4918527678239633, 2.3276806020580074), + # (-0.7838394129647351, -0.3559431099588658), + # (0.05062590383944063, -2.777720776668412), + # (-5.16720656155532, 0.604730544951074), + # (-0.7975178391566209, -7.457331266152808), + # (-5.26678072414212, -1.2456597202998294), + # (-1.2054966206758229, -1.585632442256002), + # (-1.8305397202841078, -3.4725533986870722), + # (-0.9977079714493711, -4.352313696921561), + # (-2.112254480487449, -1.950918389961516), + # (1.5673166072985023, -0.35236212338427514), + # (4.510051159742126, 2.388472595871802), + # (6.484866341191518, 2.7265499341369113), + # (2.943223409669163, 0.6985857687342915), + # (-0.7754352427990013, 1.8836849074404396), + # (-3.0299767011432763, 0.7226262677966395), + # (7.963812996606318, -0.5292268441448802), + # (2.938892733774055, -1.0935226947704197), + # (-3.124715508315778, 5.482365962329318), + # (1.5072874025099465, 3.2217916450779276), + # (-0.4125024402855396, 1.8905632208058927), + # (-1.0187315607381733, -2.3910294274119215), + # (-3.2015899186531813, -4.194472132040278), + # (-0.26275246844104655, -1.4916969195109133), + # (4.198353403380045, -3.915180458479708), + # (-5.052833287663592, 4.186193011622451)] + self.vehicle_coords = random_coords[:10] + self.node_coords = random_coords[10:] + self.vrp_instance = VRP( + node_coords=self.node_coords, vehicle_coords=self.vehicle_coords) + + def test_sparsification(self): + solver = VRPSolver(vrp=self.vrp_instance) + scfg = VRPConfig(backend="Loihi2", + core_solver=CoreSolver.LAVA_QUBO, + max_dist_cutoff_fraction=0.25, + hyperparameters={}, + target_cost=-1000000, + timeout=10000, + probe_time=False, + log_level=40) + np.random.seed(42313) + clusters, routes = solver.solve(scfg=scfg) + pprint(clusters) + pprint(routes) + + def test_quality_sparsity_tradeoff(self): + max_dist_cutoff_fraction_list = np.around(np.geomspace(1.0, 0.1, + 15), 2).tolist() + max_dist_cutoff_fraction_list.reverse() + np.random.seed(42313) + max_dist_cutoff_fraction_list = [0.0, 0.1, 0.12, 0.14, 0.16, 0.19, + 0.23, 0.27, 0.32, 0.37, 0.44, 0.52] + for j in range(1, 15): + dist_sparsity_list = [] + dist_proxy_sparsity_list = [] + total_cost_list = [] + frac_wp_clustered_list = [] + all_coords = np.loadtxt(f"vrp_instance_{j}.dat") + v_c = [tuple(coords) for coords in all_coords[:10, :].tolist()] + w_c = [tuple(coords) for coords in all_coords[10:, :].tolist()] + vrp_instance = VRP(node_coords=w_c, vehicle_coords=v_c) + solver = VRPSolver(vrp=vrp_instance) + for cutoff_factor in max_dist_cutoff_fraction_list: + scfg = VRPConfig(backend="Loihi2", + core_solver=CoreSolver.LAVA_QUBO, + max_dist_cutoff_fraction=cutoff_factor, + hyperparameters={}, + target_cost=-1000000, + timeout=10000, + probe_time=False, + log_level=40) + try: + clusters, routes = solver.solve(scfg=scfg) + except ValueError: + routes = dict( + zip( + range(1, self.vrp_instance.num_vehicles + 1), + [[-1]] * self.vrp_instance.num_vehicles + ) + ) + dist_sparsity_list.append(solver.dist_sparsity) + dist_proxy_sparsity_list.append(solver.dist_proxy_sparsity) + flat_waypoint_list = [] + total_cost = 0 + for route in routes.values(): + flat_waypoint_list.extend(route) + try: + route_cost = ntx.path_weight( + solver.problem.problem_graph, route, weight="cost") + except ntx.exception.NetworkXNoPath: + route_cost = -1 + total_cost += route_cost + flat_waypoint_list.sort() + frac_wp_clusered = np.sum(np.in1d(np.arange(11, 111), + flat_waypoint_list)) / 100 + frac_wp_clustered_list.append(frac_wp_clusered) + total_cost_list.append(total_cost) + np.savetxt(f"problem_{j}_dist_sp.dat", + np.array(dist_sparsity_list), fmt="%.3f") + np.savetxt(f"problem_{j}_distpr_sp.dat", + np.array(dist_proxy_sparsity_list), fmt="%.3f") + np.savetxt(f"problem_{j}_total_cost.dat", + np.array(total_cost_list), fmt="%.3f") + np.savetxt(f"problem_{j}_frac_wp_clustered.dat", + np.array(frac_wp_clustered_list), fmt="%.3f") + del solver + del vrp_instance + + +if __name__ == '__main__': + unittest.main() diff --git a/src/lava/lib/optimization/apps/vrp/utils/q_matrix_generator.py b/src/lava/lib/optimization/apps/vrp/utils/q_matrix_generator.py index 51a8d1d7..47ee03df 100644 --- a/src/lava/lib/optimization/apps/vrp/utils/q_matrix_generator.py +++ b/src/lava/lib/optimization/apps/vrp/utils/q_matrix_generator.py @@ -44,6 +44,7 @@ def __init__( lamda_cnstrt=1, fixed_pt=False, fixed_pt_range=(0, 127), + max_dist_cutoff_fraction=1.0, profile_mat_gen=False ) -> None: """The Constructor of the class generates Q matrices depending on the @@ -90,6 +91,11 @@ def __init__( value of min and max values that the Q matrix can have if `fixed_pt =True`. + max_dist_cutoff_fraction (float, optional) : Specifies the + fraction of maximum distance in the distance matrix at which + distances are cut-off. Helps in sparsifying the distance matrix. + Default is 1.0, which means no cut-off. + profile_mat_gen (bool, optional): Specifies if Q matrix generation needs to be timed using python's time.time() """ @@ -98,15 +104,18 @@ def __init__( self.max_fixed_pt_mant = fixed_pt_range[1] self.problem_type = problem_type self.num_vehicles = num_vehicles + self.max_cutoff_frac = max_dist_cutoff_fraction + self.dist_sparsity = 0. + self.dist_proxy_sparsity = 0. if self.problem_type == ProblemType.RANDOM: self.matrix = np.random.randint(-128, 127, size=( mat_size_for_random, mat_size_for_random)) elif self.problem_type == ProblemType.CLUSTER: start_time = time.time() - self.matrix = self._gen_clustering_Q_matrix( - input_nodes, lamda_dist, lamda_wypts, lamda_vhcles - ) + self.matrix, self.dist_sparsity, self.dist_proxy_sparsity = \ + self._gen_clustering_Q_matrix(input_nodes, lamda_dist, + lamda_wypts, lamda_vhcles) if profile_mat_gen: time_taken_clustering = time.time() - start_time pprint(f"Clustering Q matrix generated in" @@ -251,11 +260,20 @@ def _gen_clustering_Q_matrix( # Dist_proxy[Dist <= 1] = Dist[Dist <= 1] # Dist_proxy[Dist > 1] = 2 - log_dist_mtrx[Dist > 1] # Dist_proxy = 100 * (1 - np.exp(-Dist/100)) + max_dist_cutoff = self.max_cutoff_frac * np.max(Dist) + Dist_proxy = Dist.copy() + Dist_proxy[Dist_proxy >= max_dist_cutoff] = max_dist_cutoff + Dist_proxy = np.around(Dist_proxy - max_dist_cutoff, 2) + dist_sparsity = 1 - (np.count_nonzero(Dist) / np.prod(Dist.shape)) + dist_proxy_sparsity = 1 - ( + np.count_nonzero(Dist_proxy) / np.prod(Dist_proxy.shape) + ) + print(f"{dist_sparsity=}\t{dist_proxy_sparsity=}") # TODO: Introduce cut-off distancing later to sparsify distance # matrix later using one of the proxies above. # Distance matrix for the encoding - dist_mtrx = np.kron(np.eye(self.num_vehicles), Dist) + dist_mtrx = np.kron(np.eye(self.num_vehicles), Dist_proxy) # Vehicles can only belong to one cluster # Off-diagonal elements are two, populating matrix with 2 @@ -308,7 +326,7 @@ def _gen_clustering_Q_matrix( + lamda_wypts * cnstrnt_wypts_blck) if self.fixed_pt: Q = self._stochastic_rounding(Q) - return Q + return Q, dist_sparsity, dist_proxy_sparsity def _stochastic_rounding(self, tensor): """A function to rescale and stochastically round tensor to fixed