thegraph2 / app.py
summrs's picture
app.y
779056a verified
import os
import subprocess
def install(package):
subprocess.check_call(["pip", "install", package])
# Install dependencies
install("numpy")
install("networkx")
install("matplotlib")
install("gradio")
# Now import the installed libraries
import math
import itertools
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import gradio as gr
# --- Topological Index Functions ---
def wiener_index(graph):
sp = dict(nx.all_pairs_shortest_path_length(graph))
total = 0
for u in sp:
for v in sp[u]:
if u < v:
total += sp[u][v]
return total
def compute_indices(graph, index_type):
if index_type == "Wiener Index":
return wiener_index(graph)
elif index_type == "Randić Index":
return sum(1 / math.sqrt(graph.degree(u) * graph.degree(v)) for u, v in graph.edges())
elif index_type == "Balaban Index":
n = graph.number_of_nodes()
m = graph.number_of_edges()
if m == 0 or n <= 1:
return 0
return (m / (n - 1)) * sum(1 / math.sqrt(graph.degree(u) * graph.degree(v)) for u, v in graph.edges())
elif index_type == "Zagreb Index M1":
return sum(d**2 for _, d in graph.degree())
elif index_type == "Zagreb Index M2":
return sum(graph.degree(u) * graph.degree(v) for u, v in graph.edges())
elif index_type == "Harary Index":
return sum(1 / nx.shortest_path_length(graph, u, v) for u, v in itertools.combinations(graph.nodes(), 2))
elif index_type == "Schultz Index":
return sum((graph.degree(u) + graph.degree(v)) * nx.shortest_path_length(graph, u, v) for u, v in graph.edges())
elif index_type == "Gutman Index":
return sum(graph.degree(u) * graph.degree(v) * nx.shortest_path_length(graph, u, v) for u, v in graph.edges())
elif index_type == "Estrada Index":
A = nx.adjacency_matrix(graph).todense()
eigenvalues = np.linalg.eigvals(A)
return sum(math.exp(ev) for ev in eigenvalues)
elif index_type == "Hosoya Index":
return graph.number_of_edges()
else:
return "Invalid Index Type"
# --- Graph Drawing Function ---
def draw_graph(graph, index_type, index_value):
plt.figure(figsize=(6, 6))
# Fixed layout for more consistent shapes
pos = nx.spring_layout(graph, seed=42)
# Draw only edges (no nodes, no labels)
nx.draw_networkx_edges(graph, pos, edge_color="gray", width=2)
plt.title(f"{index_type}: {round(index_value, 3)}", fontsize=14)
plt.axis('off')
filename = "graph.png"
plt.savefig(filename, bbox_inches='tight')
plt.close()
return filename
# --- Main Logic ---
def process_graph(node_count, edge_count, index_type, custom_edges):
G = nx.Graph()
if not custom_edges.strip():
G = nx.gnm_random_graph(int(node_count), int(edge_count))
else:
try:
edges = [tuple(map(int, e.strip().split("-"))) for e in custom_edges.split(",")]
all_nodes = set()
for u, v in edges:
all_nodes.update([u, v])
n = max(all_nodes) + 1
G.add_nodes_from(range(n))
G.add_edges_from(edges)
except Exception as e:
return f"Error in custom edges input: {e}", None
index_value = compute_indices(G, index_type)
graph_img = draw_graph(G, index_type, index_value)
return index_value, graph_img
# --- Gradio App ---
with gr.Blocks() as demo:
gr.Markdown("# 🧠 Topological Index Calculator with Graph Visualization")
with gr.Row():
node_count = gr.Number(label="Number of Nodes", value=5, minimum=1)
edge_count = gr.Number(label="Number of Edges", value=5, minimum=0)
index_type = gr.Dropdown(
choices=["Wiener Index", "Randić Index", "Balaban Index", "Zagreb Index M1", "Zagreb Index M2",
"Harary Index", "Schultz Index", "Gutman Index", "Estrada Index", "Hosoya Index"],
label="Select Topological Index"
)
custom_edges = gr.Textbox(
label="Custom Edges (e.g., 0-1,1-2,2-3)",
placeholder="Leave blank for random graph"
)
calc_button = gr.Button("Calculate & Visualize")
result_box = gr.Textbox(label="Computed Index Value", interactive=False)
graph_output = gr.Image(label="Graph Visualization", interactive=False)
calc_button.click(
fn=process_graph,
inputs=[node_count, edge_count, index_type, custom_edges],
outputs=[result_box, graph_output]
)
# --- Run the App ---
if __name__ == "__main__":
demo.launch()