#!/usr/bin/env python3 """ Test Comparatif des Deux Solveurs avec Rotation Compare les performances et qualité des solutions entre Ad-Hoc et OR-Tools """ import subprocess import time import os import sys def run_solver(solver_name, input_file, timeout=30): """Exécute un solveur et mesure le temps + le résultat""" start = time.time() try: result = subprocess.run( f"python3 {solver_name} < {input_file}", shell=True, capture_output=True, text=True, timeout=timeout ) elapsed = time.time() - start output_lines = result.stdout.strip().split('\n') if output_lines and output_lines[0] == "SAT": vehicles = set() for line in output_lines[1:]: if line: try: vehicle_id = int(line.split()[0]) vehicles.add(vehicle_id) except: pass num_vehicles = len(vehicles) status = "SAT" else: status = "UNSAT" num_vehicles = -1 return { 'status': status, 'time': elapsed, 'vehicles': num_vehicles, 'success': True } except subprocess.TimeoutExpired: elapsed = time.time() - start return { 'status': 'TIMEOUT', 'time': elapsed, 'vehicles': -1, 'success': False } except Exception as e: return { 'status': f'ERROR: {e}', 'time': -1, 'vehicles': -1, 'success': False } def test_instance(input_file, instance_name=""): """Teste une instance avec les deux solveurs""" if not os.path.exists(input_file): print(f"❌ Fichier non trouvé: {input_file}") return None with open(input_file, 'r') as f: lines = f.read().strip().split('\n') L, W, H = map(int, lines[0].split()) M = int(lines[1]) print(f"\n{'='*70}") print(f"📦 Instance: {instance_name} ({M} colis | Camion {L}×{W}×{H})") print(f"{'='*70}") print(f"\n⏱️ Exécution Ad-Hoc...") adhoc_result = run_solver("solver_adhoc.py", input_file, timeout=30) print(f" Status: {adhoc_result['status']}") print(f" Temps: {adhoc_result['time']:.4f}s") if adhoc_result['vehicles'] > 0: print(f" Camions: {adhoc_result['vehicles']}") print(f"\n⏱️ Exécution OR-Tools...") ortools_result = run_solver("solver_ortools.py", input_file, timeout=30) print(f" Status: {ortools_result['status']}") print(f" Temps: {ortools_result['time']:.4f}s") if ortools_result['vehicles'] > 0: print(f" Camions: {ortools_result['vehicles']}") print(f"\n📊 Comparaison:") if adhoc_result['success'] and ortools_result['success']: adhoc_v = adhoc_result['vehicles'] ortools_v = ortools_result['vehicles'] if adhoc_v > 0 and ortools_v > 0: diff = ((adhoc_v - ortools_v) / ortools_v) * 100 print(f" Ad-Hoc vs OR-Tools: {adhoc_v} vs {ortools_v} camions") print(f" Écart: {diff:+.1f}% {'⚠️ Ad-Hoc pire' if diff > 0 else '✓ Ad-Hoc meilleur'}") if ortools_result['time'] > 0: ratio = adhoc_result['time'] / ortools_result['time'] print(f" Temps Ad-Hoc/OR-Tools: {ratio:.1f}×") else: print(f" ⚠️ Une solution n'a pas réussi") return { 'instance': instance_name, 'colis': M, 'adhoc': adhoc_result, 'ortools': ortools_result } def main(): """Teste les instances standards""" input_dir = "input" instances = [ ("input_bronze_gen.txt", "Bronze (Généré)"), ("input_silver_gen.txt", "Argent (Généré)"), ("input_gold_gen.txt", "Or (Généré)"), ] results = [] for filename, label in instances: filepath = os.path.join(input_dir, filename) if os.path.exists(filepath): result = test_instance(filepath, label) if result: results.append(result) print(f"\n\n{'='*70}") print(f"📈 RÉSUMÉ GLOBAL") print(f"{'='*70}\n") print(f"{'Instance':<30} {'Colis':>8} {'Ad-Hoc (s)':>12} {'OR-Tools (s)':>12} {'Ratio':>8}") print(f"{'-'*30} {'-'*8} {'-'*12} {'-'*12} {'-'*8}") for r in results: adhoc_time = f"{r['adhoc']['time']:.4f}" if r['adhoc']['success'] else "FAIL" ortools_time = f"{r['ortools']['time']:.4f}" if r['ortools']['success'] else "FAIL" if r['adhoc']['success'] and r['ortools']['success'] and r['ortools']['time'] > 0: ratio = f"{r['adhoc']['time'] / r['ortools']['time']:.1f}×" else: ratio = "N/A" print(f"{r['instance']:<30} {r['colis']:>8} {adhoc_time:>12} {ortools_time:>12} {ratio:>8}") print(f"\n✅ Tests terminés!") if __name__ == "__main__": os.chdir(os.path.dirname(os.path.abspath(__file__))) main()