import gradio as gr from PIL import Image import matplotlib.pyplot as plt import matplotlib.image as mpimg import itertools import sys import math from tqdm import tqdm # Define maps maps = { "Map 1": [ ('A', 0, 'LO'), ('B', 1, 'HI'), ('C', 1, 'LO'), ('D', 2, 'HI'), ('C', 3, 'LO'), ('B', 3, 'HI'), ('A', 4, 'HI'), ('B', 2, 'LO'), ('C', 0, 'HI'), ('D', 4, 'LO') ], "Map 2": [ ('B', 0, 'LO'), ('C', 0, 'HI'), ('A', 1, 'HI'), ('D', 1, 'LO'), ('C', 2, 'LO'), ('B', 2, 'HI'), ('A', 3, 'LO'), ('D', 3, 'HI'), ('B', 4, 'HI'), ('C', 4, 'LO') ], "Map 3": [ ('A', 0, 'HI'), ('D', 0, 'LO'), ('B', 1, 'LO'), ('C', 1, 'HI'), ('A', 2, 'LO'), ('D', 2, 'HI'), ('B', 3, 'HI'), ('C', 3, 'LO'), ('A', 4, 'LO'), ('D', 4, 'HI') ], "Map Easy": [ ('B', 0, 'LO'), ('C', 0, 'LO'), ('C', 1, 'LO'), ('B', 1, 'LO'), ('B', 2, 'LO'), ('C', 2, 'LO'), ('C', 3, 'LO'), ('B', 3, 'LO'), ('B', 4, 'LO'), ('C', 4, 'LO') ] } def make_map(map1): # Load base image img_path = "map.png" base_img = mpimg.imread(img_path) # Mapping from Aisle to image X-coordinates (estimated from image) aisle_x_map = { 'A': 145, 'B': 185, 'C': 320, 'D': 355 } # Mapping from Row to image Y-coordinates (0-4 mapped top to bottom) row_y_map = { 0: 120, 1: 185, 2: 255, 3: 325, 4: 385 } # Prepare coordinates and colors x_coords = [aisle_x_map[a] for (a, r, h) in map1] y_coords = [row_y_map[r] for (a, r, h) in map1] colors = ['green' if h == 'LO' else 'red' for (a, r, h) in map1] # Plot on top of base image fig, ax = plt.subplots(figsize=(6, 6)) ax.imshow(base_img) # Plot points with different colors for i in range(len(x_coords)): ax.plot(x_coords[i], y_coords[i], marker='o', color=colors[i]) # Label each point for i, (x, y) in enumerate(zip(x_coords, y_coords)): ax.text(x, y, str(i + 1), color='black', fontsize=10, ha='center', va='bottom') # Add legend from matplotlib.lines import Line2D legend_elements = [Line2D([0], [0], marker='o', color='w', label='LO', markerfacecolor='green', markersize=10), Line2D([0], [0], marker='o', color='w', label='HI', markerfacecolor='red', markersize=10)] ax.legend(handles=legend_elements, loc='upper right') # Set axis ticks and labels ax.set_xticks(list(aisle_x_map.values())) ax.set_xticklabels(list(aisle_x_map.keys())) ax.set_yticks(list(row_y_map.values())) ax.set_yticklabels(list(row_y_map.keys())) ax.axis('on') plt.show() def calculate_shortest_path(map_coords): """ Calculates the shortest path to visit all points in a map using permutations. Args: map_coords: A list of tuples, where each tuple represents a point in the map as (aisle, row, height). Aisle is a string ('A', 'B', 'C', 'D'), row is an integer (0-4), and height is a string ('LO', 'HI'). Returns: A tuple containing the shortest length found and the corresponding path (list of indices). """ min_length = float('inf') best_path = None num_points = len(map_coords) # Iterate through all possible permutations of visiting the points with a progress bar for path_indices in tqdm(itertools.permutations(range(num_points)), total=math.factorial(num_points), desc="Calculating Shortest Path"): current_length = 0.0 # Calculate the length for the current permutation for i in range(num_points - 1): p1_index = path_indices[i] p2_index = path_indices[i+1] # Convert map coordinates to 3D space (aisle, row, height) x1 = aisle_map[map_coords[p1_index][0]] y1 = map_coords[p1_index][1] z1 = height_map[map_coords[p1_index][2]] x2 = aisle_map[map_coords[p2_index][0]] y2 = map_coords[p2_index][1] z2 = height_map[map_coords[p2_index][2]] # Calculate Euclidean distance between consecutive points distance = math.sqrt((x2 - x1)**2 + (y2 - y1)**2 + (z2 - z1)**2) current_length += distance # Update minimum length and best path if current path is shorter if current_length < min_length: min_length = current_length best_path = list(path_indices) return min_length, best_path def run_app(coord_text): # Parse the input text into a list of tuples (Aisle, Row, Height) coords = [] for line in coord_text.strip().split('\n'): parts = line.strip().split(',') if len(parts) == 3: aisle = parts[0].strip().upper() try: row = int(parts[1].strip()) except ValueError: continue height = parts[2].strip().upper() coords.append((aisle, row, height)) if not coords: return None # Generate and save the map image import matplotlib.pyplot as plt import matplotlib.image as mpimg import io from PIL import Image # Use the same logic as make_map, but output to a buffer img_path = "/content/map.png" # You may want to update this path base_img = mpimg.imread(img_path) aisle_x_map = {'A': 145, 'B': 185, 'C': 320, 'D': 355} row_y_map = {0: 120, 1: 185, 2: 255, 3: 325, 4: 385} x_coords = [aisle_x_map.get(a, 0) for (a, r, h) in coords] y_coords = [row_y_map.get(r, 0) for (a, r, h) in coords] colors = ['green' if h == 'LO' else 'red' for (a, r, h) in coords] fig, ax = plt.subplots(figsize=(6, 6)) ax.imshow(base_img) for i in range(len(x_coords)): ax.plot(x_coords[i], y_coords[i], marker='o', color=colors[i]) for i, (x, y) in enumerate(zip(x_coords, y_coords)): ax.text(x, y, str(i + 1), color='black', fontsize=10, ha='center', va='bottom') from matplotlib.lines import Line2D legend_elements = [Line2D([0], [0], marker='o', color='w', label='LO', markerfacecolor='green', markersize=10), Line2D([0], [0], marker='o', color='w', label='HI', markerfacecolor='red', markersize=10)] ax.legend(handles=legend_elements, loc='upper right') ax.set_xticks(list(aisle_x_map.values())) ax.set_xticklabels(list(aisle_x_map.keys())) ax.set_yticks(list(row_y_map.values())) ax.set_yticklabels(list(row_y_map.keys())) ax.axis('on') buf = io.BytesIO() plt.savefig(buf, format='png') plt.close(fig) buf.seek(0) img = Image.open(buf) return img # Update Gradio interface to accept multiline text and output image demo = gr.Interface(fn=run_app, inputs=gr.Textbox(lines=10, label="Enter coordinates (Aisle,Row,Height per line)"), outputs="image", title="Shortest Path Finder",) demo.launch()