Source code for job_shop_lib.generation._instance_generator
"""Home of the `InstanceGenerator` class."""fromabcimportABC,abstractmethodimportrandomfromtypingimportIteratorfromjob_shop_libimportJobShopInstancefromjob_shop_lib.exceptionsimportUninitializedAttributeError
[docs]classInstanceGenerator(ABC):"""Common interface for all generators. The class supports both single instance generation and iteration over multiple instances, controlled by the ``iteration_limit`` parameter. It implements the iterator protocol, allowing it to be used in a ``for`` loop. Note: When used as an iterator, the generator will produce instances until it reaches the specified ``iteration_limit``. If ``iteration_limit`` is ``None``, it will continue indefinitely. Attributes: num_jobs_range: The range of the number of jobs to generate. If a single int is provided, it is used as both the minimum and maximum. duration_range: The range of durations for each operation. num_machines_range: The range of the number of machines available. If a single int is provided, it is used as both the minimum and maximum. name_suffix: A suffix to append to each instance's name for identification. seed: Seed for the random number generator to ensure reproducibility. Args: num_jobs: The range of the number of jobs to generate. num_machines: The range of the number of machines available. duration_range: The range of durations for each operation. name_suffix: Suffix for instance names. seed: Seed for the random number generator. iteration_limit: Maximum number of instances to generate in iteration mode. """def__init__(# pylint: disable=too-many-argumentsself,num_jobs:int|tuple[int,int]=(10,20),num_machines:int|tuple[int,int]=(5,10),duration_range:tuple[int,int]=(1,99),name_suffix:str="generated_instance",seed:int|None=None,iteration_limit:int|None=None,):ifisinstance(num_jobs,int):num_jobs=(num_jobs,num_jobs)ifisinstance(num_machines,int):num_machines=(num_machines,num_machines)ifseedisnotNone:random.seed(seed)self.num_jobs_range=num_jobsself.num_machines_range=num_machinesself.duration_range=duration_rangeself.name_suffix=name_suffixself._counter=0self._current_iteration=0self._iteration_limit=iteration_limit
[docs]@abstractmethoddefgenerate(self,num_jobs:int|None=None,num_machines:int|None=None,)->JobShopInstance:"""Generates a single job shop instance Args: num_jobs: The number of jobs to generate. If None, a random value within the specified range will be used. num_machines: The number of machines to generate. If None, a random value within the specified range will be used. """
def_next_name(self)->str:self._counter+=1returnf"{self.name_suffix}_{self._counter}"def__iter__(self)->Iterator[JobShopInstance]:self._current_iteration=0returnselfdef__next__(self)->JobShopInstance:if(self._iteration_limitisnotNoneandself._current_iteration>=self._iteration_limit):raiseStopIterationself._current_iteration+=1returnself.generate()def__len__(self)->int:ifself._iteration_limitisNone:raiseUninitializedAttributeError("Iteration limit is not set.")returnself._iteration_limit@propertydefmax_num_jobs(self)->int:"""Returns the maximum number of jobs that can be generated."""returnself.num_jobs_range[1]@propertydefmin_num_jobs(self)->int:"""Returns the minimum number of jobs that can be generated."""returnself.num_jobs_range[0]@propertydefmax_num_machines(self)->int:"""Returns the maximum number of machines that can be generated."""returnself.num_machines_range[1]@propertydefmin_num_machines(self)->int:"""Returns the minimum number of machines that can be generated."""returnself.num_machines_range[0]