Compare commits
	
		
			1 Commits
		
	
	
		
			main
			...
			dd48fda99f
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| dd48fda99f | 
							
								
								
									
										111
									
								
								backend/test.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										111
									
								
								backend/test.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,111 @@ | |||||||
|  | import numpy as np | ||||||
|  |  | ||||||
|  | def euclidean_distance(p1, p2): | ||||||
|  |     print(p1, p2) | ||||||
|  |     return np.sqrt((p1[0] - p2[0])**2 + (p1[1] - p2[1])**2) | ||||||
|  |  | ||||||
|  |  | ||||||
|  | def maximize_score(places, max_distance, fixed_entry, top_k=3): | ||||||
|  |     """ | ||||||
|  |     Maximizes the total score of visited places while staying below the maximum distance. | ||||||
|  |      | ||||||
|  |     Parameters: | ||||||
|  |     places (list of tuples): Each tuple contains (score, (x, y), location). | ||||||
|  |     max_distance (float): The maximum distance that can be traveled. | ||||||
|  |     fixed_entry (tuple): The place that needs to be visited independently of its score. | ||||||
|  |     top_k (int): Number of top candidates to consider in each iteration. | ||||||
|  |      | ||||||
|  |     Returns: | ||||||
|  |     list of tuples: The visited places. | ||||||
|  |     float: The total score of the visited places. | ||||||
|  |     """ | ||||||
|  |     # Initialize total distance and score | ||||||
|  |     total_distance = 0 | ||||||
|  |     total_score = 0 | ||||||
|  |     visited_places = [] | ||||||
|  |  | ||||||
|  |     # Add the fixed entry to the visited list | ||||||
|  |     score, (x, y), _ = fixed_entry | ||||||
|  |     visited_places.append(fixed_entry) | ||||||
|  |     total_score += score | ||||||
|  |  | ||||||
|  |     # Remove the fixed entry from the list of places | ||||||
|  |     remaining_places = [place for place in places if place != fixed_entry] | ||||||
|  |  | ||||||
|  |     # Sort remaining places by score-to-distance ratio | ||||||
|  |      | ||||||
|  |     remaining_places.sort(key=lambda p: p[0] / euclidean_distance((x, y), (p[1][0], p[1][1])), reverse=True) | ||||||
|  |  | ||||||
|  |     # Add places to the visited list if they don't exceed the maximum distance | ||||||
|  |     current_location = (x, y) | ||||||
|  |     while remaining_places and total_distance < max_distance: | ||||||
|  |         # Consider top_k candidates | ||||||
|  |         candidates = remaining_places[:top_k] | ||||||
|  |         best_candidate = None | ||||||
|  |         best_score_increase = -np.inf | ||||||
|  |  | ||||||
|  |         for candidate in candidates: | ||||||
|  |             score, (cx, cy), location = candidate | ||||||
|  |             distance = euclidean_distance(current_location, (cx, cy)) | ||||||
|  |             if total_distance + distance <= max_distance: | ||||||
|  |                 score_increase = score / distance | ||||||
|  |                 if score_increase > best_score_increase: | ||||||
|  |                     best_score_increase = score_increase | ||||||
|  |                     best_candidate = candidate | ||||||
|  |  | ||||||
|  |         if best_candidate: | ||||||
|  |             visited_places.append(best_candidate) | ||||||
|  |             total_distance += euclidean_distance(current_location, best_candidate[1]) | ||||||
|  |             total_score += best_candidate[0] | ||||||
|  |             current_location = best_candidate[1] | ||||||
|  |             remaining_places.remove(best_candidate) | ||||||
|  |         else: | ||||||
|  |             break | ||||||
|  |  | ||||||
|  |     return visited_places, total_score | ||||||
|  |  | ||||||
|  | # Example usage | ||||||
|  | places = [ | ||||||
|  |     (10, (0, 0), 'A'), | ||||||
|  |     (8, (4, 2), 'B'), | ||||||
|  |     (15, (6, 4), 'C'), | ||||||
|  |     (7, (5, 6), 'D'), | ||||||
|  |     (12, (1, 8), 'E'), | ||||||
|  |     (14, (34, 10), 'F'), | ||||||
|  |     (15, (65, 12), 'G'), | ||||||
|  |     (12, (3, 14), 'H'), | ||||||
|  |     (12, (15, 1), 'I'), | ||||||
|  |     (7, (17, 4), 'J'), | ||||||
|  |     (12, (3, 3), 'K'), | ||||||
|  |     (4, (21, 22), 'L'), | ||||||
|  |     (12, (23, 24), 'M'), | ||||||
|  |     (4, (25, 26), 'N'), | ||||||
|  |     (2, (27, 28), 'O'), | ||||||
|  | ] | ||||||
|  | fixed_entry = (10, (0, 0), 'A') | ||||||
|  | max_distance = 50 | ||||||
|  |  | ||||||
|  | visited_places, total_score = maximize_score(places, max_distance, fixed_entry) | ||||||
|  | print("Visited Places:", visited_places) | ||||||
|  | print("Total Score:", total_score) | ||||||
|  |  | ||||||
|  | import matplotlib.pyplot as plt | ||||||
|  |  | ||||||
|  | # Plot the route | ||||||
|  | def plot_route(visited_places): | ||||||
|  |     x_coords = [place[1][0] for place in visited_places] | ||||||
|  |     y_coords = [place[1][1] for place in visited_places] | ||||||
|  |     labels = [place[2] for place in visited_places] | ||||||
|  |  | ||||||
|  |     plt.figure(figsize=(10, 6)) | ||||||
|  |     plt.plot(x_coords, y_coords, marker='o', linestyle='-', color='b') | ||||||
|  |     for i, label in enumerate(labels): | ||||||
|  |         plt.text(x_coords[i], y_coords[i], label, fontsize=12, ha='right') | ||||||
|  |  | ||||||
|  |     plt.title('Route of Visited Places') | ||||||
|  |     plt.xlabel('X Coordinate') | ||||||
|  |     plt.ylabel('Y Coordinate') | ||||||
|  |     plt.grid(True) | ||||||
|  |     plt.savefig('route.png') | ||||||
|  |  | ||||||
|  | plot_route(visited_places) | ||||||
| @@ -34,29 +34,85 @@ Widget loadingText(Trip trip) => FutureBuilder( | |||||||
|     Widget greeter; |     Widget greeter; | ||||||
|  |  | ||||||
|     if (snapshot.hasData) { |     if (snapshot.hasData) { | ||||||
|       greeter = AutoSizeText( |       greeter = AnimatedGradientText( | ||||||
|         maxLines: 1, |         text: 'Generating your trip to ${snapshot.data}...', | ||||||
|         'Generating your trip to ${snapshot.data}...', |  | ||||||
|         style: greeterStyle, |         style: greeterStyle, | ||||||
|       ); |       ); | ||||||
|     } else if (snapshot.hasError) { |     } else if (snapshot.hasError) { | ||||||
|       // the exact error is shown in the central part of the trip overview. No need to show it here |       // the exact error is shown in the central part of the trip overview. No need to show it here | ||||||
|       greeter = AutoSizeText( |       greeter = AnimatedGradientText( | ||||||
|         maxLines: 1, |         text: 'Error while loading trip.', | ||||||
|         'Error while loading trip.', |  | ||||||
|         style: greeterStyle, |         style: greeterStyle, | ||||||
|         ); |       ); | ||||||
|     } else { |     } else { | ||||||
|       greeter = AutoSizeText( |       greeter = AnimatedGradientText( | ||||||
|         maxLines: 1, |         text: 'Generating your trip...', | ||||||
|         'Generating your trip...', |  | ||||||
|         style: greeterStyle, |         style: greeterStyle, | ||||||
|         ); |       ); | ||||||
|     } |     } | ||||||
|     return greeter; |     return greeter; | ||||||
|   } |   } | ||||||
| ); | ); | ||||||
|  |  | ||||||
|  | class AnimatedGradientText extends StatefulWidget { | ||||||
|  |   final String text; | ||||||
|  |   final TextStyle style; | ||||||
|  |  | ||||||
|  |   const AnimatedGradientText({ | ||||||
|  |     Key? key, | ||||||
|  |     required this.text, | ||||||
|  |     required this.style, | ||||||
|  |   }) : super(key: key); | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   _AnimatedGradientTextState createState() => _AnimatedGradientTextState(); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | class _AnimatedGradientTextState extends State<AnimatedGradientText> with SingleTickerProviderStateMixin { | ||||||
|  |   late AnimationController _controller; | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   void initState() { | ||||||
|  |     super.initState(); | ||||||
|  |     _controller = AnimationController( | ||||||
|  |       duration: const Duration(seconds: 1), | ||||||
|  |       vsync: this, | ||||||
|  |     )..repeat(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   void dispose() { | ||||||
|  |     _controller.dispose(); | ||||||
|  |     super.dispose(); | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   @override | ||||||
|  |   Widget build(BuildContext context) { | ||||||
|  |     return AnimatedBuilder( | ||||||
|  |       animation: _controller, | ||||||
|  |       builder: (context, child) { | ||||||
|  |         return ShaderMask( | ||||||
|  |           shaderCallback: (bounds) { | ||||||
|  |             return LinearGradient( | ||||||
|  |               colors: [Colors.blue, Colors.red, Colors.blue], | ||||||
|  |               stops: [ | ||||||
|  |                 _controller.value - 1.0, | ||||||
|  |                 _controller.value, | ||||||
|  |                 _controller.value + 1.0, | ||||||
|  |               ], | ||||||
|  |               tileMode: TileMode.mirror, | ||||||
|  |             ).createShader(bounds); | ||||||
|  |           }, | ||||||
|  |           child: Text( | ||||||
|  |             widget.text, | ||||||
|  |             style: widget.style, | ||||||
|  |           ), | ||||||
|  |         ); | ||||||
|  |       }, | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
| @@ -125,7 +125,7 @@ class LandmarkType { | |||||||
|   LandmarkType({required this.name, this.icon = const Icon(Icons.location_on)}) { |   LandmarkType({required this.name, this.icon = const Icon(Icons.location_on)}) { | ||||||
|     switch (name) { |     switch (name) { | ||||||
|       case 'sightseeing': |       case 'sightseeing': | ||||||
|         icon = const Icon(Icons.church); |         icon = const Icon(Icons.castle); | ||||||
|         break; |         break; | ||||||
|       case 'nature': |       case 'nature': | ||||||
|         icon = const Icon(Icons.eco); |         icon = const Icon(Icons.eco); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user