import gradio as gr import numpy as np import plotly.graph_objects as go import plotly.express as px from sklearn.metrics import pairwise_distances import torch def plot_from_npy(npy_data): fig = go.Figure() fig.add_trace(go.Scatter(x=[1, 2, 3, 4], y=[10, 11, 12, 13], mode='lines', name='New York')) fig.update_layout(title_text="Facility Distribution in Cities") fig.update_xaxes(title_text="Time") fig.update_yaxes(title_text="Facility Count") actual_fig = fig # Replace this line with your actual_fig solution_fig = fig # Replace this line with your solution_fig return actual_fig, solution_fig def solver_plot(data_npy, boost=False): actual_fig = go.Figure() solution_fig = go.Figure() actual_ac = 0 # Replace this line with your actual_ac solution_ac = 0 # Replace this line with your solution_ac return actual_fig, solution_fig, actual_ac, solution_ac def demo_plot(city, facility): facility_name = ["🏫 School", "🏥 Hospital", "🌳 Park"] all_facility = ["🏫 School", "🏥 Hospital", "🌳 Park"] for i in range(len(all_facility)): if all_facility[i] in facility: all_facility[i] = True else: all_facility[i] = False city_name = city.replace(' ', '_') data = np.loadtxt(f'demo/{city_name}.npy') positions = data[:, :2] demands = data[:, 2:5] actual_facility = data[:, 5:8] solution_facility = data[:, 8:11] actual_fig = go.Figure() solution_fig = go.Figure() for i in range(len(all_facility)): if not all_facility[i]: continue actual_fig.add_trace(go.Scattermapbox( lat=positions[actual_facility[:, i] == 1][:, 0], lon=positions[actual_facility[:, i] == 1][:, 1], mode='markers', marker=go.scattermapbox.Marker( size=10, color=px.colors.qualitative.Plotly[i] ), name=facility_name[i], )) solution_fig.add_trace(go.Scattermapbox( lat=positions[solution_facility[:, i] == 1][:, 0], lon=positions[solution_facility[:, i] == 1][:, 1], mode='markers', marker=go.scattermapbox.Marker( size=10, color=px.colors.qualitative.Plotly[i] ), name=facility_name[i], )) actual_fig.update_layout( mapbox=dict( style='carto-positron', center=dict(lat=np.mean(positions[actual_facility[:, i] == 1][:, 0]), \ lon=np.mean(positions[actual_facility[:, i] == 1][:, 1])), zoom=11.0 ), margin=dict(l=0, r=0, b=0, t=0),) solution_fig.update_layout( mapbox=dict( style='carto-positron', center=dict(lat=np.mean(positions[solution_facility[:, i] == 1][:, 0]), \ lon=np.mean(positions[solution_facility[:, i] == 1][:, 1])), zoom=11.0 ), margin=dict(l=0, r=0, b=0, t=0),) # show legend actual_fig.update_layout(showlegend=True) solution_fig.update_layout(showlegend=True) positions = np.deg2rad(positions) dist = pairwise_distances(positions, metric='haversine') * 6371 actual_ac = 0 solution_ac = 0 for i in range(len(all_facility)): if not all_facility[i]: continue ac_matrix = dist * demands[:, i][:, None] actual_ac += ac_matrix[:, actual_facility[:, i] == 1].min(axis=-1).sum() solution_ac += ac_matrix[:, solution_facility[:, i] == 1].min(axis=-1).sum() return actual_fig, solution_fig, actual_ac, solution_ac def solver_plot(data_npy, boost=False): data = data_npy.split('\n') n = len(data) p = int((len(data[0].split(' '))-2) / 2) positions = [] demands = [] actual_facilities = [] for row in data: row = row.split(' ') row = [x for x in row if len(x)] print(row) positions.append([float(row[0]), float(row[1])]) demand = [] for i in range(2, 2+p): demand.append(float(row[i])) demands.append(demand) actual_facility = [] for i in range(2+p, 2+2*p): actual_facility.append(bool(int(float(row[i])))) actual_facilities.append(actual_facility) positions = np.array(positions) demands = np.array(demands) actual_facilities = np.array(actual_facilities) solution_facilities = ~actual_facilities print(actual_facilities) actual_fig = go.Figure() solution_fig = go.Figure() for i in range(p): actual_fig.add_trace(go.Scattermapbox( lat=positions[actual_facilities[:, i]][:, 0], lon=positions[actual_facilities[:, i]][:, 1], mode='markers', marker=go.scattermapbox.Marker( size=10, color=px.colors.qualitative.Plotly[i] ), name=f'Facility {i+1}' )) solution_fig.add_trace(go.Scattermapbox( lat=positions[solution_facilities[:, i]][:, 0], lon=positions[solution_facilities[:, i]][:, 1], mode='markers', marker=go.scattermapbox.Marker( size=10, color=px.colors.qualitative.Plotly[i] ), name=f'Facility {i+1}' )) actual_fig.update_layout( mapbox=dict( style='carto-positron', center=dict(lat=np.mean(positions[actual_facilities[:, i]][:, 0]), \ lon=np.mean(positions[actual_facilities[:, i]][:, 1])), zoom=11.0 ), margin=dict(l=0, r=0, b=0, t=0),) solution_fig.update_layout( mapbox=dict( style='carto-positron', center=dict(lat=np.mean(positions[solution_facilities[:, i]][:, 0]), \ lon=np.mean(positions[solution_facilities[:, i]][:, 1])), zoom=11.0 ), margin=dict(l=0, r=0, b=0, t=0),) # show legend actual_fig.update_layout(showlegend=True) solution_fig.update_layout(showlegend=True) positions = np.deg2rad(positions) dist = pairwise_distances(positions, metric='haversine') * 6371 actual_ac = 0 solution_ac = 0 for i in range(p): ac_matrix = dist * demands[:, i][:, None] actual_ac += ac_matrix[:, actual_facilities[:, i]].min(axis=-1).sum() solution_ac += ac_matrix[:, solution_facilities[:, i]].min(axis=-1).sum() return actual_fig, solution_fig, actual_ac, solution_ac def get_example(): return [ ('40.71 -73.93 213 0\n40.72 -73.99 15 1\n40.65 -73.88 365 1\n40.57 -73.96 629 0\n40.70 -73.97 106 0\n40.61 -73.95 189 1'), ("40.71 -73.93 213 124 0 1\n40.72 -73.99 15 43 1 0\n40.65 -73.88 365 214 1 0\n40.57 -73.96 629 431 0 1\n40.70 -73.97 106 241 0 1\n40.61 -73.95 189 264 1 0") ] def load_npy_file(file_obj): data = np.load(file_obj.name) string_array = '\n'.join([' '.join(map(str, row)) for row in data]) return string_array with gr.Blocks() as demo: gr.Markdown("## Demo") with gr.Column(): city = gr.Radio(choices=["New York", "Boston", "Los Angeles", "Chicago"], value="New York", label="Select City:") facility = gr.CheckboxGroup(choices=["🏫 School", "🏥 Hospital", "🌳 Park"], value=["🏥 Hospital"], label="Select Facility:") btn = gr.Button(value="🚀 Generate") with gr.Row(): actual_map = gr.Plot(label='Actual Facility Distribution') solution_map = gr.Plot(label='Relocated Facility Distribution') with gr.Row(): actual_ac = gr.Textbox(label='Real-world Access Cost') solution_ac = gr.Textbox(label='Relocated Access Cost') demo.load(fn=demo_plot, inputs=[city, facility], outputs=[actual_map, solution_map, actual_ac, solution_ac]) btn.click(fn=demo_plot, inputs=[city, facility], outputs=[actual_map, solution_map, actual_ac, solution_ac]) gr.Markdown("## FLP & IUMFLP Solver") with gr.Column(): with gr.Row(): data_npy = gr.Textbox(label="Input") data_file = gr.UploadButton( label="📁 Upload a npy file", file_count="single", file_types=[".npy"]) with gr.Row(): gr.Examples( examples=get_example(), inputs=[data_npy], fn=plot_from_npy, outputs=[actual_map, solution_map], ) with gr.Row(): boost = gr.Checkbox(label="Turbo Boost (accelerate solution generation with fewer SWAP steps)", value=False) btn2 = gr.Button(value="🚀 Generate") with gr.Row(): actual_map = gr.Plot(label='Initial Solution') solution_map = gr.Plot(label='Final Solution') with gr.Row(): actual_ac = gr.Textbox(label='Initial Access Cost') solution_ac = gr.Textbox(label='Final Access Cost') data_file.upload(fn=load_npy_file, inputs=[data_file], outputs=[data_npy]) btn2.click(fn=solver_plot, inputs=[data_npy, boost], outputs=[actual_map, solution_map, actual_ac, solution_ac]) if __name__ == "__main__": demo.launch()