def finish(instance: CVRPInstance, model: QRPModel) -> CVRPSolution: subinstances = [ CVRPInstance( name="", region="", deliveries=vehicle.deliveries, origin=vehicle.origin, vehicle_capacity=3 * instance.vehicle_capacity, # More relaxed. ) for idx, subinstance in enumerate(model.cluster_subsolutions.values()) for vehicle in subinstance ] logger.info("Reordering routes.") subsolutions = [ ortools_solve(subinstance, model.params.ortools_tsp_params) for subinstance in subinstances ] return CVRPSolution( name=instance.name, vehicles=[ v for subsolution in subsolutions for v in subsolution.vehicles ], )
def solve(file): instance = CVRPInstance.from_file(file) logger.info("Finetunning on evaluation instance.") model_finetuned = finetune(model, instance) logger.info("Starting to dynamic route.") for delivery in tqdm(instance.deliveries): model_finetuned = route(model_finetuned, delivery) solution = finish(instance, model_finetuned) solution.to_file(output_dir / f"{instance.name}.json")
def solve_cluster(deliveries): if len(deliveries) < 2: return [deliveries] cluster_instance = CVRPInstance( name=instance.name, deliveries=deliveries, origin=instance.origin, vehicle_capacity=instance.vehicle_capacity, ) cluster_solution = ortools_solve(cluster_instance, params.cluster_ortools_params) return [v.deliveries for v in cluster_solution.vehicles]
def solve( instance: CVRPInstance, params: Optional[KmeansPartitionORToolsParams] = None, ) -> Optional[CVRPSolution]: params = params or KmeansPartitionORToolsParams.get_baseline() num_deliveries = len(instance.deliveries) num_clusters = int( params.fixed_num_clusters or np.ceil( num_deliveries / (params.variable_num_clusters or num_deliveries) ) ) logger.info(f"Clustering instance into {num_clusters} subinstances") clustering = KMeans(num_clusters, random_state=params.seed) points = np.array( [[d.point.lng, d.point.lat] for d in instance.deliveries] ) clusters = clustering.fit_predict(points) delivery_array = np.array(instance.deliveries) subsinstance_deliveries = [ delivery_array[clusters == i] for i in range(num_clusters) ] subinstances = [ CVRPInstance( name=instance.name, deliveries=subinstance.tolist(), origin=instance.origin, vehicle_capacity=instance.vehicle_capacity, ) for subinstance in subsinstance_deliveries ] subsolutions = [ ortools_solve(subinstance, params.ortools_params) for subinstance in subinstances ] return CVRPSolution( name=instance.name, vehicles=[v for sol in subsolutions for v in sol.vehicles], )
def solve( instance: CVRPInstance, params: Optional[KmeansAggregateORToolsParams] = None, ) -> Optional[CVRPSolution]: params = params or KmeansAggregateORToolsParams.get_baseline() num_deliveries = len(instance.deliveries) num_clusters = int(params.fixed_num_clusters or np.ceil(num_deliveries / (params.variable_num_clusters or 1))) logger.info(f"Clustering instance into {num_clusters} subinstances") clustering = MiniBatchKMeans(num_clusters, random_state=params.seed) points = np.array([[d.point.lng, d.point.lat] for d in instance.deliveries]) clusters = clustering.fit_predict(points) delivery_array = np.array(instance.deliveries) deliveries_per_cluster = [ delivery_array[clusters == i] for i in range(num_clusters) ] def solve_cluster(deliveries): if len(deliveries) < 2: return [deliveries] cluster_instance = CVRPInstance( name=instance.name, deliveries=deliveries, origin=instance.origin, vehicle_capacity=instance.vehicle_capacity, ) cluster_solution = ortools_solve(cluster_instance, params.cluster_ortools_params) return [v.deliveries for v in cluster_solution.vehicles] def aggregate_deliveries(idx, deliveries): return Delivery( id=str(idx), point=deliveries[0].point, size=sum([d.size for d in deliveries]), ) subsolutions = [ deliveries for group in deliveries_per_cluster for deliveries in solve_cluster(group.tolist()) if group.any() ] aggregated_deliveries = [ aggregate_deliveries(idx, s) for idx, s in enumerate(subsolutions) ] aggregated_instance = CVRPInstance( name=instance.name, deliveries=aggregated_deliveries, origin=instance.origin, vehicle_capacity=instance.vehicle_capacity, ) aggregated_solution = ortools_solve(aggregated_instance) vehicles = [ CVRPSolutionVehicle( origin=v.origin, deliveries=[ d for v in solve_cluster([ d for groups in v.deliveries for d in subsolutions[int(groups.id)] ]) for d in v ], ) for v in aggregated_solution.vehicles ] return CVRPSolution( name=instance.name, vehicles=vehicles, )
eval_files = ([eval_path] if eval_path.is_file() else list(eval_path.iterdir())) train_path = Path(args.train_instances) train_path_dir = train_path if train_path.is_dir() else train_path.parent train_files = ([train_path] if train_path.is_file() else list(train_path.iterdir())) # params = params_class.from_file(args.params) if args.params else None params = None output_dir = Path(args.output or ".") output_dir.mkdir(parents=True, exist_ok=True) train_instances = [CVRPInstance.from_file(f) for f in train_files[:240]] logger.info("Pretraining on training instances.") model = pretrain(train_instances) def solve(file): instance = CVRPInstance.from_file(file) logger.info("Finetunning on evaluation instance.") model_finetuned = finetune(model, instance) logger.info("Starting to dynamic route.") for delivery in tqdm(instance.deliveries): model_finetuned = route(model_finetuned, delivery) solution = finish(instance, model_finetuned)
def solve(file): instance = CVRPInstance.from_file(file) solution = method(instance, params) solution.to_file(output_dir / f"{instance.name}.json")