""" Demo script to test Jackson's theorem analytical module. Compares analytical predictions with simulation results. """ from src.core.simulation import Simulator from src.core.scenarios import get_scenario_1, get_scenario_2, get_scenario_3 from src.analytics.jackson import JacksonAnalyzer from src.analytics.comparison import compare_results, print_comparison def test_scenario(scenario_name: str, config): """Test a scenario with both analytical and simulation.""" print("\n" + "=" * 80) print(f"{scenario_name}") print("=" * 80) # Analytical analysis using Jackson's theorem print("\nšŸ“ ANALYTICAL ANALYSIS (Jackson's Theorem)") print("-" * 80) analyzer = JacksonAnalyzer( external_arrival_rate=config.arrival_rate, coordinator_service_rate=config.coordinator_service_rate, coordinator_exit_prob=config.coordinator_exit_probability, server_service_rates=config.server_service_rates, server_routing_probs=config.server_routing_probs ) analytical_results = analyzer.analyze() # Print analytical results print(f"\nStability: {'āœ… STABLE' if analytical_results.is_stable else 'āŒ UNSTABLE'}") print(f"\nCoordinator:") coord = analytical_results.coordinator print(f" ρc = {coord.utilization:.4f}") if coord.is_stable: print(f" L = {coord.average_customers:.4f} customers") print(f" W = {coord.average_time:.4f} ms") for i, (server_id, server) in enumerate(analytical_results.servers.items()): print(f"\n{server_id}:") print(f" ρ = {server.utilization:.4f} {'āŒ UNSTABLE' if not server.is_stable else ''}") if server.is_stable: print(f" L = {server.average_customers:.4f} customers") print(f" W = {server.average_time:.4f} ms") if analytical_results.is_stable: print(f"\nSystem-Wide:") print(f" Total L = {analytical_results.total_average_customers:.4f} customers") print(f" Total W = {analytical_results.total_average_time:.4f} ms") # Simulation print("\n\nšŸŽ² SIMULATION") print("-" * 80) simulator = Simulator(config) simulation_results = simulator.run() print(f"\nCoordinator:") coord_sim = simulation_results.coordinator_stats print(f" ρc = {coord_sim['utilization']:.4f}") print(f" W = {coord_sim['average_system_time']:.4f} ms") for server_id, server_sim in simulation_results.server_stats.items(): print(f"\n{server_id}:") print(f" ρ = {server_sim['utilization']:.4f}") print(f" W = {server_sim['average_system_time']:.4f} ms") print(f"\nSystem-Wide:") print(f" Total W = {simulation_results.average_system_time:.4f} ms") # Comparison print("\n\nšŸ“Š COMPARISON") print("-" * 80) comparison = compare_results(analytical_results, simulation_results) print_comparison(comparison) return analytical_results, simulation_results, comparison def main(): print("=" * 80) print("JACKSON'S THEOREM VALIDATION") print("=" * 80) print("\nComparing analytical predictions with simulation results...") # Test Scenario 1 config1 = get_scenario_1() analytical1, simulation1, comparison1 = test_scenario( "SCENARIO 1: Single Fast Server", config1 ) # Test Scenario 2 config2 = get_scenario_2() analytical2, simulation2, comparison2 = test_scenario( "SCENARIO 2: Fast + Slow Server", config2 ) # Test Scenario 3 config3 = get_scenario_3() analytical3, simulation3, comparison3 = test_scenario( "SCENARIO 3: Three Slow Servers", config3 ) # Summary print("\n\n" + "=" * 80) print("VALIDATION SUMMARY") print("=" * 80) scenarios = [ ("Scenario 1", comparison1), ("Scenario 2", comparison2), ("Scenario 3", comparison3) ] print(f"\n{'Scenario':<15} {'Total W Diff %':<20} {'Coord ρ Diff %':<20} {'Max Server ρ Diff %':<20}") print("-" * 80) for name, comp in scenarios: max_server_rho_diff = max( abs(s.utilization_diff_percent) for s in comp.servers.values() ) print(f"{name:<15} {abs(comp.total_W_diff_percent):<20.2f} " f"{abs(comp.coordinator.utilization_diff_percent):<20.2f} " f"{max_server_rho_diff:<20.2f}") print("\nāœ… Validation complete!") print("\nObservations:") print(" - Differences are expected due to statistical variation in simulation") print(" - Utilization typically within 10-20% (simulation has finite sample)") print(" - Average times can vary more for heavily loaded systems") print(" - Analytical assumes infinite time; simulation has warmup + finite duration") print("=" * 80) if __name__ == "__main__": main()