@@ -237,6 +237,8 @@ def evaluate(program_path):
237237 "validity" : 0.0 ,
238238 "eval_time" : float (eval_time ),
239239 "combined_score" : 0.0 ,
240+ "radius_variance" : 0.0 ,
241+ "spatial_spread" : 0.0 ,
240242 },
241243 artifacts = {
242244 "stderr" : shape_error ,
@@ -250,6 +252,20 @@ def evaluate(program_path):
250252 # Calculate sum
251253 sum_radii = np .sum (radii ) if valid else 0.0
252254
255+ # Calculate feature metrics for MAP-Elites diversity
256+ # radius_variance: normalized variance of radii (0-1)
257+ # Max theoretical variance for radii in [0, 0.5] is ~0.0625
258+ radius_variance = float (np .var (radii ) / 0.0625 ) if valid else 0.0
259+ radius_variance = min (1.0 , max (0.0 , radius_variance )) # Clamp to [0, 1]
260+
261+ # spatial_spread: how spread out centers are (0-1)
262+ # Based on std of distances from centroid, normalized by max possible (0.5 * sqrt(2))
263+ centroid = np .mean (centers , axis = 0 )
264+ distances_from_centroid = np .sqrt (np .sum ((centers - centroid ) ** 2 , axis = 1 ))
265+ max_spread = 0.5 * np .sqrt (2 ) # Max distance from center to corner
266+ spatial_spread = float (np .std (distances_from_centroid ) / max_spread ) if valid else 0.0
267+ spatial_spread = min (1.0 , max (0.0 , spatial_spread )) # Clamp to [0, 1]
268+
253269 # Make sure reported_sum matches the calculated sum
254270 sum_mismatch = abs (sum_radii - reported_sum ) > 1e-6
255271 if sum_mismatch :
@@ -306,6 +322,8 @@ def evaluate(program_path):
306322 "validity" : float (validity ),
307323 "eval_time" : float (eval_time ),
308324 "combined_score" : float (combined_score ),
325+ "radius_variance" : radius_variance ,
326+ "spatial_spread" : spatial_spread ,
309327 },
310328 artifacts = artifacts ,
311329 )
@@ -320,6 +338,8 @@ def evaluate(program_path):
320338 "validity" : 0.0 ,
321339 "eval_time" : 600.0 , # Timeout duration
322340 "combined_score" : 0.0 ,
341+ "radius_variance" : 0.0 ,
342+ "spatial_spread" : 0.0 ,
323343 },
324344 artifacts = {
325345 "stderr" : error_msg ,
@@ -339,6 +359,8 @@ def evaluate(program_path):
339359 "validity" : 0.0 ,
340360 "eval_time" : 0.0 ,
341361 "combined_score" : 0.0 ,
362+ "radius_variance" : 0.0 ,
363+ "spatial_spread" : 0.0 ,
342364 },
343365 artifacts = {
344366 "stderr" : error_msg ,
@@ -374,7 +396,7 @@ def evaluate_stage1(program_path):
374396 shape_error = f"Invalid shapes: centers={ centers .shape } , radii={ radii .shape } "
375397 print (shape_error )
376398 return EvaluationResult (
377- metrics = {"validity" : 0.0 , "combined_score" : 0.0 },
399+ metrics = {"validity" : 0.0 , "combined_score" : 0.0 , "radius_variance" : 0.0 , "spatial_spread" : 0.0 },
378400 artifacts = {
379401 "stderr" : shape_error ,
380402 "failure_stage" : "stage1_shape_validation" ,
@@ -389,6 +411,14 @@ def evaluate_stage1(program_path):
389411 # Calculate sum
390412 actual_sum = np .sum (radii ) if valid else 0.0
391413
414+ # Calculate feature metrics for MAP-Elites diversity
415+ radius_variance = float (np .var (radii ) / 0.0625 ) if valid else 0.0
416+ radius_variance = min (1.0 , max (0.0 , radius_variance ))
417+ centroid = np .mean (centers , axis = 0 )
418+ distances_from_centroid = np .sqrt (np .sum ((centers - centroid ) ** 2 , axis = 1 ))
419+ spatial_spread = float (np .std (distances_from_centroid ) / (0.5 * np .sqrt (2 ))) if valid else 0.0
420+ spatial_spread = min (1.0 , max (0.0 , spatial_spread ))
421+
392422 # Target from paper
393423 target = 2.635
394424
@@ -424,6 +454,8 @@ def evaluate_stage1(program_path):
424454 "sum_radii" : float (actual_sum ),
425455 "target_ratio" : float (actual_sum / target if valid else 0.0 ),
426456 "combined_score" : float (combined_score ),
457+ "radius_variance" : radius_variance ,
458+ "spatial_spread" : spatial_spread ,
427459 },
428460 artifacts = artifacts ,
429461 )
@@ -432,7 +464,7 @@ def evaluate_stage1(program_path):
432464 error_msg = f"Stage 1 evaluation timed out: { e } "
433465 print (error_msg )
434466 return EvaluationResult (
435- metrics = {"validity" : 0.0 , "combined_score" : 0.0 },
467+ metrics = {"validity" : 0.0 , "combined_score" : 0.0 , "radius_variance" : 0.0 , "spatial_spread" : 0.0 },
436468 artifacts = {
437469 "stderr" : error_msg ,
438470 "failure_stage" : "stage1_timeout" ,
@@ -445,7 +477,7 @@ def evaluate_stage1(program_path):
445477 print (error_msg )
446478 print (traceback .format_exc ())
447479 return EvaluationResult (
448- metrics = {"validity" : 0.0 , "combined_score" : 0.0 },
480+ metrics = {"validity" : 0.0 , "combined_score" : 0.0 , "radius_variance" : 0.0 , "spatial_spread" : 0.0 },
449481 artifacts = {
450482 "stderr" : error_msg ,
451483 "traceback" : traceback .format_exc (),
@@ -459,7 +491,7 @@ def evaluate_stage1(program_path):
459491 print (error_msg )
460492 print (traceback .format_exc ())
461493 return EvaluationResult (
462- metrics = {"validity" : 0.0 , "combined_score" : 0.0 },
494+ metrics = {"validity" : 0.0 , "combined_score" : 0.0 , "radius_variance" : 0.0 , "spatial_spread" : 0.0 },
463495 artifacts = {
464496 "stderr" : error_msg ,
465497 "traceback" : traceback .format_exc (),
0 commit comments