From 3ebe0b7191146d536c5a80c903d962e88ab1f61c Mon Sep 17 00:00:00 2001 From: Helldragon67 Date: Wed, 15 Jan 2025 19:55:48 +0100 Subject: [PATCH] good starting point, working pulp --- backend/src/tests/test_main.py | 28 ++++++++++++++-------------- backend/src/utils/optimizer.py | 12 +----------- 2 files changed, 15 insertions(+), 25 deletions(-) diff --git a/backend/src/tests/test_main.py b/backend/src/tests/test_main.py index c95b6f8..bff5b00 100644 --- a/backend/src/tests/test_main.py +++ b/backend/src/tests/test_main.py @@ -11,7 +11,7 @@ def client(): """Client used to call the app.""" return TestClient(app) -''' + def test_turckheim(client, request): # pylint: disable=redefined-outer-name """ Test n°1 : Custom test in Turckheim to ensure small villages are also supported. @@ -45,8 +45,8 @@ def test_turckheim(client, request): # pylint: disable=redefined-outer-name # Add details to report log_trip_details(request, landmarks, result['total_time'], duration_minutes) - for elem in landmarks : - print(elem) + # for elem in landmarks : + # print(elem) # checks : assert response.status_code == 200 # check for successful planning @@ -54,8 +54,8 @@ def test_turckheim(client, request): # pylint: disable=redefined-outer-name assert duration_minutes*0.8 < int(result['total_time']) < duration_minutes*1.2 assert len(landmarks) > 2 # check that there is something to visit assert comp_time < 30, f"Computation time exceeded 30 seconds: {comp_time:.2f} seconds" - assert 2==3 -''' + # assert 2==3 + def test_bellecour(client, request) : # pylint: disable=redefined-outer-name @@ -97,9 +97,9 @@ def test_bellecour(client, request) : # pylint: disable=redefined-outer-name assert response.status_code == 200 # check for successful planning assert comp_time < 30, f"Computation time exceeded 30 seconds: {comp_time:.2f} seconds" assert duration_minutes*0.8 < int(result['total_time']) < duration_minutes*1.2 - assert 2 == 3 + # assert 2 == 3 + -''' def test_Paris(client, request) : # pylint: disable=redefined-outer-name """ Test n°2 : Custom test in Paris (les Halles) centre to ensure proper decision making in crowded area. @@ -131,8 +131,8 @@ def test_Paris(client, request) : # pylint: disable=redefined-outer-name # Add details to report log_trip_details(request, landmarks, result['total_time'], duration_minutes) - # for elem in landmarks : - # print(elem) + for elem in landmarks : + print(elem) # checks : assert response.status_code == 200 # check for successful planning @@ -171,8 +171,8 @@ def test_New_York(client, request) : # pylint: disable=redefined-outer-name # Add details to report log_trip_details(request, landmarks, result['total_time'], duration_minutes) - # for elem in landmarks : - # print(elem) + for elem in landmarks : + print(elem) # checks : assert response.status_code == 200 # check for successful planning @@ -211,14 +211,14 @@ def test_shopping(client, request) : # pylint: disable=redefined-outer-name # Add details to report log_trip_details(request, landmarks, result['total_time'], duration_minutes) - # for elem in landmarks : - # print(elem) + for elem in landmarks : + print(elem) # checks : assert response.status_code == 200 # check for successful planning assert comp_time < 30, f"Computation time exceeded 30 seconds: {comp_time:.2f} seconds" assert duration_minutes*0.8 < int(result['total_time']) < duration_minutes*1.2 -''' + # def test_new_trip_single_prefs(client): # response = client.post( diff --git a/backend/src/utils/optimizer.py b/backend/src/utils/optimizer.py index 7218971..210559f 100644 --- a/backend/src/utils/optimizer.py +++ b/backend/src/utils/optimizer.py @@ -2,7 +2,6 @@ import yaml, logging import numpy as np import pulp as pl from scipy.optimize import linprog -from scipy.sparse import lil_matrix, csr_matrix from collections import defaultdict, deque from ..structs.landmark import Landmark @@ -508,21 +507,14 @@ class Optimizer: # SET CONSTRAINTS FOR INEQUALITY c, A_ub, b_ub = self.init_ub_time(landmarks, max_time) # Adds the distances from each landmark to the other. - print("ok1") self.respect_number(A_ub, b_ub, L, max_landmarks) # Respects max number of visits (no more possible stops than landmarks). - print("ok2") self.break_sym(A_ub, b_ub, L) # Breaks the 'zig-zag' symmetry. Avoids d12 and d21 but not larger cirlces. # SET CONSTRAINTS FOR EQUALITY - print("ok3") A_eq, b_eq = self.init_eq_not_stay(landmarks) # Force solution not to stay in same place - print("ok4") self.respect_start_finish(A_eq, b_eq, L) # Force start and finish positions - print("ok5") self.respect_order(A_eq, b_eq, L) # Respect order of visit (only works when max_time is limiting factor) - print("ok6") self.respect_user_must(A_eq, b_eq, landmarks) # Force to do/avoid landmarks set by user. - print("ok7") self.logger.debug(f"Optimizing with {A_ub.shape[0]} + {A_eq.shape[0]} = {A_ub.shape[0] + A_eq.shape[0]} constraints.") @@ -545,14 +537,12 @@ class Optimizer: prob += (pl.lpSum([A_eq[i][j] * x[j] for j in range(L*L)]) == b_eq[i]) # 6. Solve the problem - prob.solve(pl.PULP_CBC_CMD(msg=False)) + prob.solve(pl.PULP_CBC_CMD(msg=False, gapRel=0.3)) # 7. Extract Results status = pl.LpStatus[prob.status] solution = [pl.value(var) for var in x] # The values of the decision variables (will be 0 or 1) - print(status) - self.logger.debug("First results are out. Looking out for circles and correcting.") # Raise error if no solution is found. FIXME: for now this throws the internal server error