summrs commited on
Commit
dbdfd6d
·
verified ·
1 Parent(s): fdfa161

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()

Files changed (1) hide show
  1. app.py +27 -57
app.py CHANGED
@@ -4,7 +4,7 @@ import subprocess
4
  def install(package):
5
  subprocess.check_call(["pip", "install", package])
6
 
7
- # Manually install each required library
8
  install("numpy")
9
  install("networkx")
10
  install("matplotlib")
@@ -21,9 +21,6 @@ import gradio as gr
21
  # --- Topological Index Functions ---
22
 
23
  def wiener_index(graph):
24
- """
25
- Wiener Index: Sum of shortest path distances between all pairs of vertices.
26
- """
27
  sp = dict(nx.all_pairs_shortest_path_length(graph))
28
  total = 0
29
  for u in sp:
@@ -35,86 +32,57 @@ def wiener_index(graph):
35
  def compute_indices(graph, index_type):
36
  if index_type == "Wiener Index":
37
  return wiener_index(graph)
38
-
39
  elif index_type == "Randić Index":
40
- # Randić Index = Σ[1/√(d(u)*d(v))] for every edge (u,v)
41
  return sum(1 / math.sqrt(graph.degree(u) * graph.degree(v)) for u, v in graph.edges())
42
-
43
  elif index_type == "Balaban Index":
44
  n = graph.number_of_nodes()
45
  m = graph.number_of_edges()
46
  if m == 0 or n <= 1:
47
  return 0
48
  return (m / (n - 1)) * sum(1 / math.sqrt(graph.degree(u) * graph.degree(v)) for u, v in graph.edges())
49
-
50
  elif index_type == "Zagreb Index M1":
51
- # M1 = Σ[d(v)]² over all vertices
52
  return sum(d**2 for _, d in graph.degree())
53
-
54
  elif index_type == "Zagreb Index M2":
55
- # M2 = Σ[d(u)*d(v)] for every edge (u,v)
56
  return sum(graph.degree(u) * graph.degree(v) for u, v in graph.edges())
57
-
58
  elif index_type == "Harary Index":
59
- # H = Σ[1 / d(u,v)] for all distinct vertex pairs
60
- return sum(1 / nx.shortest_path_length(graph, u, v)
61
- for u, v in itertools.combinations(graph.nodes(), 2))
62
-
63
  elif index_type == "Schultz Index":
64
- # Schultz Index = Σ[(d(u)+d(v))*d(u,v)] over all edges (as a simplified version)
65
- return sum((graph.degree(u) + graph.degree(v)) * nx.shortest_path_length(graph, u, v)
66
- for u, v in graph.edges())
67
-
68
  elif index_type == "Gutman Index":
69
- # Gutman Index = Σ[d(u)*d(v)*d(u,v)] over all edges
70
- return sum(graph.degree(u) * graph.degree(v) * nx.shortest_path_length(graph, u, v)
71
- for u, v in graph.edges())
72
-
73
  elif index_type == "Estrada Index":
74
- # Estrada Index = Σ(exp(λ)) over all eigenvalues of the adjacency matrix.
75
  A = nx.adjacency_matrix(graph).todense()
76
  eigenvalues = np.linalg.eigvals(A)
77
  return sum(math.exp(ev) for ev in eigenvalues)
78
-
79
  elif index_type == "Hosoya Index":
80
- # Hosoya Index counts the number of matchings in a graph.
81
- # For simplicity, we use a dummy value: the number of edges.
82
  return graph.number_of_edges()
83
-
84
  else:
85
  return "Invalid Index Type"
86
 
87
- # --- Graph Visualization Function ---
88
 
89
  def draw_graph(graph, index_type, index_value):
90
- """
91
- Draws the graph using a spring layout.
92
- Only the edges are drawn (removing the blue nodes with numbers).
93
- The title shows the index type and computed value.
94
- """
95
  plt.figure(figsize=(6, 6))
96
- pos = nx.spring_layout(graph, seed=42)
97
-
98
- # Draw only the edges
99
- nx.draw_networkx_edges(graph, pos, edge_color="gray")
100
 
 
 
 
 
 
 
101
  plt.title(f"{index_type}: {round(index_value, 3)}", fontsize=14)
102
-
103
- # Save the plot as an image and return its filename.
104
  filename = "graph.png"
105
- plt.savefig(filename)
106
  plt.close()
107
  return filename
108
 
109
- # --- Main Processing Function ---
110
 
111
  def process_graph(node_count, edge_count, index_type, custom_edges):
112
- """
113
- Creates a graph either from random generation or from custom edge input.
114
- Then computes the selected topological index and draws the graph.
115
- """
116
  G = nx.Graph()
117
- # If custom_edges is empty, generate a random graph with given node and edge counts.
118
  if not custom_edges.strip():
119
  G = nx.gnm_random_graph(int(node_count), int(edge_count))
120
  else:
@@ -124,7 +92,6 @@ def process_graph(node_count, edge_count, index_type, custom_edges):
124
  for u, v in edges:
125
  all_nodes.update([u, v])
126
  n = max(all_nodes) + 1
127
- G = nx.Graph()
128
  G.add_nodes_from(range(n))
129
  G.add_edges_from(edges)
130
  except Exception as e:
@@ -134,27 +101,30 @@ def process_graph(node_count, edge_count, index_type, custom_edges):
134
  graph_img = draw_graph(G, index_type, index_value)
135
  return index_value, graph_img
136
 
137
- # --- Gradio Interface Setup ---
138
 
139
  with gr.Blocks() as demo:
140
- gr.Markdown("# Topological Index Calculator with Graph Visualization")
141
 
142
  with gr.Row():
143
  node_count = gr.Number(label="Number of Nodes", value=5, minimum=1)
144
  edge_count = gr.Number(label="Number of Edges", value=5, minimum=0)
145
-
146
  index_type = gr.Dropdown(
147
  choices=["Wiener Index", "Randić Index", "Balaban Index", "Zagreb Index M1", "Zagreb Index M2",
148
  "Harary Index", "Schultz Index", "Gutman Index", "Estrada Index", "Hosoya Index"],
149
  label="Select Topological Index"
150
  )
151
-
152
- custom_edges = gr.Textbox(label="Custom Edges (e.g., 0-1,1-2,2-3)", placeholder="Leave blank for random graph")
153
-
 
 
 
154
  calc_button = gr.Button("Calculate & Visualize")
155
  result_box = gr.Textbox(label="Computed Index Value", interactive=False)
156
  graph_output = gr.Image(label="Graph Visualization", interactive=False)
157
-
158
  calc_button.click(
159
  fn=process_graph,
160
  inputs=[node_count, edge_count, index_type, custom_edges],
@@ -164,4 +134,4 @@ with gr.Blocks() as demo:
164
  # --- Run the App ---
165
 
166
  if __name__ == "__main__":
167
- demo.launch()
 
4
  def install(package):
5
  subprocess.check_call(["pip", "install", package])
6
 
7
+ # Install dependencies
8
  install("numpy")
9
  install("networkx")
10
  install("matplotlib")
 
21
  # --- Topological Index Functions ---
22
 
23
  def wiener_index(graph):
 
 
 
24
  sp = dict(nx.all_pairs_shortest_path_length(graph))
25
  total = 0
26
  for u in sp:
 
32
  def compute_indices(graph, index_type):
33
  if index_type == "Wiener Index":
34
  return wiener_index(graph)
 
35
  elif index_type == "Randić Index":
 
36
  return sum(1 / math.sqrt(graph.degree(u) * graph.degree(v)) for u, v in graph.edges())
 
37
  elif index_type == "Balaban Index":
38
  n = graph.number_of_nodes()
39
  m = graph.number_of_edges()
40
  if m == 0 or n <= 1:
41
  return 0
42
  return (m / (n - 1)) * sum(1 / math.sqrt(graph.degree(u) * graph.degree(v)) for u, v in graph.edges())
 
43
  elif index_type == "Zagreb Index M1":
 
44
  return sum(d**2 for _, d in graph.degree())
 
45
  elif index_type == "Zagreb Index M2":
 
46
  return sum(graph.degree(u) * graph.degree(v) for u, v in graph.edges())
 
47
  elif index_type == "Harary Index":
48
+ return sum(1 / nx.shortest_path_length(graph, u, v) for u, v in itertools.combinations(graph.nodes(), 2))
 
 
 
49
  elif index_type == "Schultz Index":
50
+ return sum((graph.degree(u) + graph.degree(v)) * nx.shortest_path_length(graph, u, v) for u, v in graph.edges())
 
 
 
51
  elif index_type == "Gutman Index":
52
+ return sum(graph.degree(u) * graph.degree(v) * nx.shortest_path_length(graph, u, v) for u, v in graph.edges())
 
 
 
53
  elif index_type == "Estrada Index":
 
54
  A = nx.adjacency_matrix(graph).todense()
55
  eigenvalues = np.linalg.eigvals(A)
56
  return sum(math.exp(ev) for ev in eigenvalues)
 
57
  elif index_type == "Hosoya Index":
 
 
58
  return graph.number_of_edges()
 
59
  else:
60
  return "Invalid Index Type"
61
 
62
+ # --- Graph Drawing Function ---
63
 
64
  def draw_graph(graph, index_type, index_value):
 
 
 
 
 
65
  plt.figure(figsize=(6, 6))
 
 
 
 
66
 
67
+ # Fixed layout for more consistent shapes
68
+ pos = nx.spring_layout(graph, seed=42)
69
+
70
+ # Draw only edges (no nodes, no labels)
71
+ nx.draw_networkx_edges(graph, pos, edge_color="gray", width=2)
72
+
73
  plt.title(f"{index_type}: {round(index_value, 3)}", fontsize=14)
74
+ plt.axis('off')
75
+
76
  filename = "graph.png"
77
+ plt.savefig(filename, bbox_inches='tight')
78
  plt.close()
79
  return filename
80
 
81
+ # --- Main Logic ---
82
 
83
  def process_graph(node_count, edge_count, index_type, custom_edges):
 
 
 
 
84
  G = nx.Graph()
85
+
86
  if not custom_edges.strip():
87
  G = nx.gnm_random_graph(int(node_count), int(edge_count))
88
  else:
 
92
  for u, v in edges:
93
  all_nodes.update([u, v])
94
  n = max(all_nodes) + 1
 
95
  G.add_nodes_from(range(n))
96
  G.add_edges_from(edges)
97
  except Exception as e:
 
101
  graph_img = draw_graph(G, index_type, index_value)
102
  return index_value, graph_img
103
 
104
+ # --- Gradio App ---
105
 
106
  with gr.Blocks() as demo:
107
+ gr.Markdown("# 🧠 Topological Index Calculator with Graph Visualization")
108
 
109
  with gr.Row():
110
  node_count = gr.Number(label="Number of Nodes", value=5, minimum=1)
111
  edge_count = gr.Number(label="Number of Edges", value=5, minimum=0)
112
+
113
  index_type = gr.Dropdown(
114
  choices=["Wiener Index", "Randić Index", "Balaban Index", "Zagreb Index M1", "Zagreb Index M2",
115
  "Harary Index", "Schultz Index", "Gutman Index", "Estrada Index", "Hosoya Index"],
116
  label="Select Topological Index"
117
  )
118
+
119
+ custom_edges = gr.Textbox(
120
+ label="Custom Edges (e.g., 0-1,1-2,2-3)",
121
+ placeholder="Leave blank for random graph"
122
+ )
123
+
124
  calc_button = gr.Button("Calculate & Visualize")
125
  result_box = gr.Textbox(label="Computed Index Value", interactive=False)
126
  graph_output = gr.Image(label="Graph Visualization", interactive=False)
127
+
128
  calc_button.click(
129
  fn=process_graph,
130
  inputs=[node_count, edge_count, index_type, custom_edges],
 
134
  # --- Run the App ---
135
 
136
  if __name__ == "__main__":
137
+ demo.launch()