Added early stopping to the headless simulation.
Some checks failed
Build Simulation and Test / Run All Tests (push) Failing after 14m52s
Some checks failed
Build Simulation and Test / Run All Tests (push) Failing after 14m52s
This commit is contained in:
parent
b87106f8f3
commit
9b009ef593
@ -68,6 +68,7 @@ class HeadlessConfig:
|
|||||||
# Simulation settings
|
# Simulation settings
|
||||||
max_ticks: Optional[int] = None
|
max_ticks: Optional[int] = None
|
||||||
max_duration: Optional[float] = None # seconds
|
max_duration: Optional[float] = None # seconds
|
||||||
|
early_stop: bool = False # Stop when 0 cells remaining
|
||||||
|
|
||||||
# Output settings
|
# Output settings
|
||||||
output: OutputConfig = field(default_factory=OutputConfig)
|
output: OutputConfig = field(default_factory=OutputConfig)
|
||||||
|
|||||||
@ -35,7 +35,7 @@
|
|||||||
"starting_energy": 500,
|
"starting_energy": 500,
|
||||||
"interaction_radius": 50,
|
"interaction_radius": 50,
|
||||||
"drag_coefficient": 0.02,
|
"drag_coefficient": 0.02,
|
||||||
"energy_cost_base": 1.5,
|
"energy_cost_base": 1.4,
|
||||||
"neural_network_complexity_cost": 0.05,
|
"neural_network_complexity_cost": 0.05,
|
||||||
"movement_cost": 0.25,
|
"movement_cost": 0.25,
|
||||||
"food_energy_value": 140,
|
"food_energy_value": 140,
|
||||||
|
|||||||
@ -33,6 +33,7 @@ class HeadlessConfig:
|
|||||||
evolution_interval: int = 1000
|
evolution_interval: int = 1000
|
||||||
output_formats: List[str] = None # ['json', 'csv']
|
output_formats: List[str] = None # ['json', 'csv']
|
||||||
real_time: bool = False # Whether to run in real-time or as fast as possible
|
real_time: bool = False # Whether to run in real-time or as fast as possible
|
||||||
|
early_stop: bool = False # Stop when 0 cells remaining
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
if self.output_formats is None:
|
if self.output_formats is None:
|
||||||
@ -121,14 +122,14 @@ class HeadlessSimulationEngine:
|
|||||||
unit=unit,
|
unit=unit,
|
||||||
desc="Simulation",
|
desc="Simulation",
|
||||||
leave=True, # Keep the bar when done
|
leave=True, # Keep the bar when done
|
||||||
bar_format='{l_bar}{bar}| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, {rate_fmt}]'
|
bar_format='{l_bar}{bar}| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, {rate_fmt}] {postfix}'
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
self.progress_bar = tqdm(
|
self.progress_bar = tqdm(
|
||||||
unit='ticks',
|
unit='ticks',
|
||||||
desc="Simulation",
|
desc="Simulation",
|
||||||
leave=True,
|
leave=True,
|
||||||
bar_format='{l_bar}{bar}| {n_fmt} [{elapsed}, {rate_fmt}]'
|
bar_format='{l_bar}{bar}| {n_fmt} [{elapsed}, {rate_fmt}] {postfix}'
|
||||||
)
|
)
|
||||||
|
|
||||||
def _update_progress_bar(self):
|
def _update_progress_bar(self):
|
||||||
@ -141,6 +142,10 @@ class HeadlessSimulationEngine:
|
|||||||
tps = self.simulation_core.state.actual_tps
|
tps = self.simulation_core.state.actual_tps
|
||||||
elapsed = current_time - self.start_time
|
elapsed = current_time - self.start_time
|
||||||
|
|
||||||
|
# Get current cell count
|
||||||
|
world_state = self.simulation_core.get_world_state()
|
||||||
|
cell_count = world_state.get('entity_counts', {}).get('cells', 0)
|
||||||
|
|
||||||
if TQDM_AVAILABLE and self.progress_bar:
|
if TQDM_AVAILABLE and self.progress_bar:
|
||||||
# Use tqdm progress bar
|
# Use tqdm progress bar
|
||||||
if self.config.max_ticks:
|
if self.config.max_ticks:
|
||||||
@ -149,6 +154,7 @@ class HeadlessSimulationEngine:
|
|||||||
self.progress_bar.n = progress
|
self.progress_bar.n = progress
|
||||||
self.progress_bar.set_postfix({
|
self.progress_bar.set_postfix({
|
||||||
'TPS': f'{tps:.1f}',
|
'TPS': f'{tps:.1f}',
|
||||||
|
'Cells': cell_count,
|
||||||
'Files': self.files_written
|
'Files': self.files_written
|
||||||
})
|
})
|
||||||
elif self.config.max_duration:
|
elif self.config.max_duration:
|
||||||
@ -157,6 +163,7 @@ class HeadlessSimulationEngine:
|
|||||||
self.progress_bar.n = int(progress)
|
self.progress_bar.n = int(progress)
|
||||||
self.progress_bar.set_postfix({
|
self.progress_bar.set_postfix({
|
||||||
'TPS': f'{tps:.1f}',
|
'TPS': f'{tps:.1f}',
|
||||||
|
'Cells': cell_count,
|
||||||
'Files': self.files_written,
|
'Files': self.files_written,
|
||||||
'Tick': current_tick
|
'Tick': current_tick
|
||||||
})
|
})
|
||||||
@ -165,6 +172,7 @@ class HeadlessSimulationEngine:
|
|||||||
self.progress_bar.n = current_tick
|
self.progress_bar.n = current_tick
|
||||||
self.progress_bar.set_postfix({
|
self.progress_bar.set_postfix({
|
||||||
'TPS': f'{tps:.1f}',
|
'TPS': f'{tps:.1f}',
|
||||||
|
'Cells': cell_count,
|
||||||
'Files': self.files_written
|
'Files': self.files_written
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -295,6 +303,14 @@ class HeadlessSimulationEngine:
|
|||||||
print(f"Reached max duration: {self.config.max_duration} seconds")
|
print(f"Reached max duration: {self.config.max_duration} seconds")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
# Check early stopping condition (0 cells remaining)
|
||||||
|
if self.config.early_stop:
|
||||||
|
world_state = self.simulation_core.get_world_state()
|
||||||
|
cell_count = world_state.get('entity_counts', {}).get('cells', 0)
|
||||||
|
if cell_count == 0:
|
||||||
|
print(f"Early stopping: 0 cells remaining at tick {self.simulation_core.state.total_ticks}")
|
||||||
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def _collect_data(self):
|
def _collect_data(self):
|
||||||
|
|||||||
@ -81,6 +81,11 @@ def main():
|
|||||||
action="store_true",
|
action="store_true",
|
||||||
help="Create sample configuration files and exit"
|
help="Create sample configuration files and exit"
|
||||||
)
|
)
|
||||||
|
parser.add_argument(
|
||||||
|
"--early-stop",
|
||||||
|
action="store_true",
|
||||||
|
help="Stop simulation when there are 0 cells remaining"
|
||||||
|
)
|
||||||
|
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
@ -140,6 +145,10 @@ def main():
|
|||||||
headless_config.output.collect_entities = True
|
headless_config.output.collect_entities = True
|
||||||
headless_config.output.collect_evolution = True
|
headless_config.output.collect_evolution = True
|
||||||
|
|
||||||
|
# Set early stopping flag
|
||||||
|
if args.early_stop:
|
||||||
|
headless_config.early_stop = True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error loading configuration: {e}")
|
print(f"Error loading configuration: {e}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
@ -157,7 +166,8 @@ def main():
|
|||||||
entities_interval=headless_config.output.entities_interval,
|
entities_interval=headless_config.output.entities_interval,
|
||||||
evolution_interval=headless_config.output.evolution_interval,
|
evolution_interval=headless_config.output.evolution_interval,
|
||||||
output_formats=headless_config.output.formats,
|
output_formats=headless_config.output.formats,
|
||||||
real_time=headless_config.output.real_time
|
real_time=headless_config.output.real_time,
|
||||||
|
early_stop=headless_config.early_stop
|
||||||
)
|
)
|
||||||
|
|
||||||
# Create and run simulation
|
# Create and run simulation
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user