Compare commits
	
		
			1 Commits
		
	
	
		
			v0.1.3
			...
			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; | ||||
|  | ||||
|     if (snapshot.hasData) { | ||||
|       greeter = AutoSizeText( | ||||
|         maxLines: 1, | ||||
|         'Generating your trip to ${snapshot.data}...', | ||||
|       greeter = AnimatedGradientText( | ||||
|         text: 'Generating your trip to ${snapshot.data}...', | ||||
|         style: greeterStyle, | ||||
|       ); | ||||
|     } else if (snapshot.hasError) { | ||||
|       // the exact error is shown in the central part of the trip overview. No need to show it here | ||||
|       greeter = AutoSizeText( | ||||
|         maxLines: 1, | ||||
|         'Error while loading trip.', | ||||
|       greeter = AnimatedGradientText( | ||||
|         text: 'Error while loading trip.', | ||||
|         style: greeterStyle, | ||||
|         ); | ||||
|       ); | ||||
|     } else { | ||||
|       greeter = AutoSizeText( | ||||
|         maxLines: 1, | ||||
|         'Generating your trip...', | ||||
|       greeter = AnimatedGradientText( | ||||
|         text: 'Generating your trip...', | ||||
|         style: greeterStyle, | ||||
|         ); | ||||
|       ); | ||||
|     } | ||||
|     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)}) { | ||||
|     switch (name) { | ||||
|       case 'sightseeing': | ||||
|         icon = const Icon(Icons.church); | ||||
|         icon = const Icon(Icons.castle); | ||||
|         break; | ||||
|       case 'nature': | ||||
|         icon = const Icon(Icons.eco); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user