156 lines
5.1 KiB
Python
156 lines
5.1 KiB
Python
#!/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()
|