sankar5302k's picture
Update app.py
1668ff4 verified
import gradio as gr
import joblib
import numpy as np
import networkx as nx
import matplotlib.pyplot as plt
import io
from PIL import Image
import ast
import pandas as pd
def create_node_inputs(num_nodes):
"""Dynamically create input fields for each node's parameters, returning sliders only."""
inputs = []
for i in range(num_nodes):
inputs.append(gr.HTML(value=f"<h3>Node {i} Parameters</h3>")) # Display-only
inputs.append(gr.Slider(0.1, 0.5, value=0.3, label=f"Node {i} Active Time (s)"))
inputs.append(gr.Slider(0.5, 2.0, value=1.0, label=f"Node {i} Sleep Time (s)"))
inputs.append(gr.Slider(0.1, 1.0, value=0.5, label=f"Node {i} Energy Level"))
inputs.append(gr.Slider(0.1, 1.0, value=0.5, label=f"Node {i} Retransmission Interval (s)"))
inputs.append(gr.Slider(0.01, 0.3, value=0.1, label=f"Node {i} Packet Loss Rate"))
inputs.append(gr.Slider(10, 100, value=50, label=f"Node {i} Distance to Next Node (m)"))
return inputs
def simulate_network(num_nodes, edges_input, source_node, dest_node, *node_params):
# Load the trained model
model = joblib.load('energy_efficiency_model.pkl')
# Parse edges input (e.g., "0->1,1->2" or "[(0,1),(1,2)]")
try:
if edges_input.startswith('['):
edges = ast.literal_eval(edges_input)
if not all(isinstance(e, tuple) and len(e) == 2 for e in edges):
raise ValueError("Edges must be a list of tuples, e.g., [(0,1),(1,2)]")
else:
edges = [tuple(map(int, e.split('->'))) for e in edges_input.split(',')]
if not all(len(e) == 2 for e in edges):
raise ValueError("Edges must be in format '0->1,1->2' or [(0,1),(1,2)]")
except Exception as e:
return None, f"Error parsing edges: {str(e)}. Use format '0->1,1->2' or [(0,1),(1,2)]"
# Validate edges and source/destination nodes
try:
source_node = int(source_node)
dest_node = int(dest_node)
if not (0 <= source_node < num_nodes and 0 <= dest_node < num_nodes):
return None, f"Error: Source and destination nodes must be between 0 and {num_nodes - 1}"
if not all(0 <= u < num_nodes and 0 <= v < num_nodes for u, v in edges):
return None, f"Error: All node indices in edges must be between 0 and {num_nodes - 1}"
except ValueError:
return None, "Error: Source and destination nodes must be integers"
# Create directed graph
G = nx.DiGraph()
G.add_nodes_from(range(num_nodes))
G.add_edges_from(edges)
# Group node parameters, excluding HTML components
params_per_node = 6 # Number of numerical parameters per node
node_data = []
for i in range(num_nodes):
start_idx = i * (params_per_node + 1) + 1 # Skip HTML component
node_data.append({
'active_time': node_params[start_idx],
'sleep_time': node_params[start_idx + 1],
'energy_level': node_params[start_idx + 2],
'retransmission_interval': node_params[start_idx + 3],
'packet_loss_rate': node_params[start_idx + 4],
'distance_to_next_node': node_params[start_idx + 5]
})
# Calculate energy consumption for each edge
feature_names = ['active_time', 'sleep_time', 'energy_level',
'retransmission_interval', 'packet_loss_rate', 'distance_to_next_node']
for u, v in G.edges():
# Use source node's parameters for edge (u,v)
params = node_data[u]
input_features = pd.DataFrame([[
params['active_time'],
params['sleep_time'],
params['energy_level'],
params['retransmission_interval'],
params['packet_loss_rate'],
params['distance_to_next_node']
]], columns=feature_names)
energy_consumption = model.predict(input_features)[0]
G.edges[u, v]['energy'] = energy_consumption
# Find the most energy-efficient path
path = None
total_energy = None
try:
path = nx.shortest_path(G, source=source_node, target=dest_node, weight='energy')
total_energy = sum(G.edges[u, v]['energy'] for u, v in zip(path[:-1], path[1:]))
except nx.NetworkXNoPath:
# Find all possible paths and select the most energy-efficient one
all_paths = list(nx.all_simple_paths(G, source=source_node, target=dest_node))
if not all_paths:
return None, f"No path exists from node {source_node} to node {dest_node}"
# Calculate total energy for each path
min_energy = float('inf')
best_path = None
for p in all_paths:
energy = sum(G.edges[u, v]['energy'] for u, v in zip(p[:-1], p[1:]))
if energy < min_energy:
min_energy = energy
best_path = p
path = best_path
total_energy = min_energy
# Visualize the network
plt.figure(figsize=(12, 8))
pos = nx.spring_layout(G)
# Draw nodes and edges
nx.draw(G, pos, with_labels=True, node_color='lightblue',
node_size=500, font_size=12, font_weight='bold')
# Draw edge labels (energy consumption)
edge_labels = nx.get_edge_attributes(G, 'energy')
edge_labels = {k: f"{v:.3f}" for k, v in edge_labels.items()}
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels)
# Highlight the optimal path
path_edges = list(zip(path[:-1], path[1:]))
nx.draw_networkx_edges(G, pos, edgelist=path_edges, edge_color='r', width=2)
# Save plot to buffer
buf = io.BytesIO()
plt.savefig(buf, format='png')
buf.seek(0)
img = Image.open(buf)
plt.close()
# Prepare output
result = f"""
Network Simulation Results:
- Number of nodes: {num_nodes}
- Edges: {edges}
- Optimal path from node {source_node} to node {dest_node}: {path}
- Total energy consumption: {total_energy:.3f} units
- Node Parameters:
"""
for i, params in enumerate(node_data):
result += f"""
Node {i}:
* Active Time: {params['active_time']:.2f} s
* Sleep Time: {params['sleep_time']:.2f} s
* Energy Level: {params['energy_level']:.2f}
* Retransmission Interval: {params['retransmission_interval']:.2f} s
* Packet Loss Rate: {params['packet_loss_rate']:.2f}
* Distance to Next Node: {params['distance_to_next_node']:.2f} m
"""
return img, result
# Create Gradio interface
def create_dynamic_interface(num_nodes=5):
inputs = [
gr.Slider(0, 9, value=num_nodes, step=1, label="Number of Nodes"),
gr.Textbox(label="Edges (e.g., '0->1,1->2' or '[(0,1),(1,2)]')",
value="0->1,1->2,2->3,3->4" if num_nodes == 5 else ""),
gr.Number(value=0, label="Source Node", precision=0),
gr.Number(value=num_nodes - 1, label="Destination Node", precision=0),
]
inputs.extend(create_node_inputs(num_nodes))
return inputs
# Initial interface with default number of nodes
initial_inputs = create_dynamic_interface()
iface = gr.Interface(
fn=simulate_network,
inputs=initial_inputs,
outputs=[gr.Image(label="Network Visualization"), gr.Textbox(label="Simulation Results")],
title="Energy-Efficient Network Path Simulation",
description="Simulate energy-efficient path selection with custom node parameters and network topology. Specify edges as '0->1,1->2' or [(0,1),(1,2)]."
)
if __name__ == "__main__":
iface.launch()