|
|
import os |
|
|
import subprocess |
|
|
|
|
|
def install(package): |
|
|
subprocess.check_call(["pip", "install", package]) |
|
|
|
|
|
|
|
|
install("numpy") |
|
|
install("networkx") |
|
|
install("matplotlib") |
|
|
install("gradio") |
|
|
|
|
|
|
|
|
import math |
|
|
import itertools |
|
|
import numpy as np |
|
|
import networkx as nx |
|
|
import matplotlib.pyplot as plt |
|
|
import gradio as gr |
|
|
|
|
|
|
|
|
|
|
|
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" |
|
|
|
|
|
|
|
|
|
|
|
def draw_graph(graph, index_type, index_value): |
|
|
plt.figure(figsize=(6, 6)) |
|
|
|
|
|
|
|
|
pos = nx.spring_layout(graph, seed=42) |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
|
|
|
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] |
|
|
) |
|
|
|
|
|
|
|
|
|
|
|
if __name__ == "__main__": |
|
|
demo.launch() |