boundml.instances
1from .ecole_instances import * 2from .instances import * 3from .miplib import * 4from .folder_instances import * 5 6__all__ = [ 7 "Instances", 8 "FolderInstances", 9 "MipLibInstances", 10] + [ 11 "CapacitatedFacilityLocationGenerator", 12 "CombinatorialAuctionGenerator", 13 "IndependentSetGenerator", 14 "SetCoverGenerator" 15] if HAS_ECOLE_FORK else []
7class Instances(ABC): 8 """ 9 An Instances object is an iterator that yields pyscipopt.Model. 10 """ 11 def __iter__(self): 12 return self 13 14 @abstractmethod 15 def __next__(self) -> Model: 16 raise NotImplementedError("Subclasses must implement this method.")
An Instances object is an iterator that yields pyscipopt.Model.
11class FolderInstances(Instances): 12 """ 13 FolderInstances allows to iterate through the instances in a folder. 14 """ 15 _archives_urls = { 16 "collection": "https://miplib.zib.de/downloads/collection.zip", 17 "benchmark": "https://miplib.zib.de/downloads/benchmark.zip" 18 } 19 20 def __init__(self, folder: str, filter: Callable[[str], bool] = lambda x: True): 21 """ 22 Parameters 23 ---------- 24 folder : str 25 Name of the folder containing the instances. 26 filter : Callable[[str], bool] 27 Filter instances based on their name to work only with a desired subset of instances 28 """ 29 self._instances_dir = folder 30 31 self._instances_files = [name for name in os.listdir(self._instances_dir) if filter(name)] 32 self._instances_files.sort() 33 self._index = 0 34 35 def __next__(self): 36 if self._index >= len(self._instances_files): 37 raise StopIteration 38 39 path = os.path.join(self._instances_dir, self._instances_files[self._index]) 40 model = Model() 41 model.setParam("display/verblevel", 0) 42 model.readProblem(path) 43 self._index += 1 44 return model 45 46 def seed(self, seed: int): 47 """ 48 Shuffle the instances based on the given seed 49 Parameters 50 ---------- 51 seed : int 52 """ 53 random.Random(seed).shuffle(self._instances_files) 54 self._index = 0 55 56 def __len__(self): 57 return len(self._instances_files)
FolderInstances allows to iterate through the instances in a folder.
20 def __init__(self, folder: str, filter: Callable[[str], bool] = lambda x: True): 21 """ 22 Parameters 23 ---------- 24 folder : str 25 Name of the folder containing the instances. 26 filter : Callable[[str], bool] 27 Filter instances based on their name to work only with a desired subset of instances 28 """ 29 self._instances_dir = folder 30 31 self._instances_files = [name for name in os.listdir(self._instances_dir) if filter(name)] 32 self._instances_files.sort() 33 self._index = 0
Parameters
- folder (str): Name of the folder containing the instances.
- filter (Callable[[str], bool]): Filter instances based on their name to work only with a desired subset of instances
46 def seed(self, seed: int): 47 """ 48 Shuffle the instances based on the given seed 49 Parameters 50 ---------- 51 seed : int 52 """ 53 random.Random(seed).shuffle(self._instances_files) 54 self._index = 0
Shuffle the instances based on the given seed
Parameters
- seed (int):
17class MipLibInstances(FolderInstances): 18 """ 19 MipLibInstances allow to iterate through MipLib instances. 20 It downloads archive files once and cache it as long with all the extracted instances. 21 It is highly recommended to use the argument force_download and force_extract if the process is killed while 22 performing one of these operations. 23 By default, MipLibInstances iterates through the instances ordered by alphabetical order, a seed can be set to 24 randomize the order. 25 """ 26 _archives_urls = { 27 "collection": "https://miplib.zib.de/downloads/collection.zip", 28 "benchmark": "https://miplib.zib.de/downloads/benchmark.zip" 29 } 30 31 def __init__(self, subset: str = "benchmark", force_download: bool = False, force_extract: bool = False, 32 filter: Callable[[str], bool] = lambda x: True): 33 """ 34 Parameters 35 ---------- 36 subset : str 37 Name of the subset of instances to used, either "collection" or "benchmark" 38 force_download : bool 39 Force the download even if the file already exists. 40 force_extract : bool 41 Force the extraction even if the folder already exists. 42 filter : Callable[[str], bool] 43 Filter instances based on their name (name.mps) to work only with a desired subset of instances 44 """ 45 # Create a cache directory specific to your library 46 self._cache_dir = Path(user_cache_dir("boundml")) 47 self._cache_dir.mkdir(parents=True, exist_ok=True) 48 self._zip_file = self._cache_dir.joinpath(f"{subset}.zip") 49 self._instances_dir = self._cache_dir.joinpath(f"{subset}") 50 51 if subset in MipLibInstances._archives_urls: 52 url = MipLibInstances._archives_urls[subset] 53 else: 54 raise ValueError(f"Unknown subset: {subset}. Must be one of {MipLibInstances._archives_urls}") 55 56 self._download(url, force_download) 57 self._extract(force_download or force_extract) 58 59 super().__init__(str(self._instances_dir), filter) 60 61 def _download(self, url: str, force: bool = False): 62 if force or not self._zip_file.exists(): 63 resp = requests.get(url, stream=True) 64 total = int(resp.headers.get('content-length', 0)) 65 with open(self._zip_file, 'wb') as file, tqdm( 66 desc=str("Downloading MIPLIB instances"), 67 total=total, 68 unit='iB', 69 unit_scale=True, 70 unit_divisor=1024, 71 ) as bar: 72 for data in resp.iter_content(chunk_size=1024): 73 size = file.write(data) 74 bar.update(size) 75 76 def _extract(self, force: bool = False): 77 if force or not self._instances_dir.exists(): 78 if self._instances_dir.exists(): 79 shutil.rmtree(self._instances_dir) 80 81 print("Extracting collections.zip...") 82 self._instances_dir.mkdir(exist_ok=True) 83 with zipfile.ZipFile(self._zip_file, 'r') as zip_ref: 84 zip_ref.extractall(self._instances_dir) 85 86 files = os.listdir(self._instances_dir) 87 with tqdm( 88 desc=str("Extracting instances"), 89 total=len(files), 90 unit='it', 91 unit_scale=True, 92 unit_divisor=1, 93 ) as bar: 94 for file in files: 95 path = os.path.join(self._instances_dir, file) 96 dest_path = ".".join(path.split(".")[:-1]) 97 with gzip.open(path, 'rb') as f_in: 98 with open(dest_path, 'wb') as f_out: 99 shutil.copyfileobj(f_in, f_out) 100 os.remove(path) 101 102 bar.update(1)
MipLibInstances allow to iterate through MipLib instances. It downloads archive files once and cache it as long with all the extracted instances. It is highly recommended to use the argument force_download and force_extract if the process is killed while performing one of these operations. By default, MipLibInstances iterates through the instances ordered by alphabetical order, a seed can be set to randomize the order.
31 def __init__(self, subset: str = "benchmark", force_download: bool = False, force_extract: bool = False, 32 filter: Callable[[str], bool] = lambda x: True): 33 """ 34 Parameters 35 ---------- 36 subset : str 37 Name of the subset of instances to used, either "collection" or "benchmark" 38 force_download : bool 39 Force the download even if the file already exists. 40 force_extract : bool 41 Force the extraction even if the folder already exists. 42 filter : Callable[[str], bool] 43 Filter instances based on their name (name.mps) to work only with a desired subset of instances 44 """ 45 # Create a cache directory specific to your library 46 self._cache_dir = Path(user_cache_dir("boundml")) 47 self._cache_dir.mkdir(parents=True, exist_ok=True) 48 self._zip_file = self._cache_dir.joinpath(f"{subset}.zip") 49 self._instances_dir = self._cache_dir.joinpath(f"{subset}") 50 51 if subset in MipLibInstances._archives_urls: 52 url = MipLibInstances._archives_urls[subset] 53 else: 54 raise ValueError(f"Unknown subset: {subset}. Must be one of {MipLibInstances._archives_urls}") 55 56 self._download(url, force_download) 57 self._extract(force_download or force_extract) 58 59 super().__init__(str(self._instances_dir), filter)
Parameters
- subset (str): Name of the subset of instances to used, either "collection" or "benchmark"
- force_download (bool): Force the download even if the file already exists.
- force_extract (bool): Force the extraction even if the folder already exists.
- filter (Callable[[str], bool]): Filter instances based on their name (name.mps) to work only with a desired subset of instances
23class CapacitatedFacilityLocationGenerator(EcoleInstances): 24 def __init__(self, *args, **kwargs): 25 super().__init__(ecole.instance.CapacitatedFacilityLocationGenerator(*args, **kwargs))
An Instances object is an iterator that yields pyscipopt.Model.
27class CombinatorialAuctionGenerator(EcoleInstances): 28 def __init__(self, *args, **kwargs): 29 super().__init__(ecole.instance.CombinatorialAuctionGenerator(*args, **kwargs))
An Instances object is an iterator that yields pyscipopt.Model.
31class IndependentSetGenerator(EcoleInstances): 32 def __init__(self, *args, **kwargs): 33 super().__init__(ecole.instance.IndependentSetGenerator(*args, **kwargs))
An Instances object is an iterator that yields pyscipopt.Model.
35class SetCoverGenerator(EcoleInstances): 36 def __init__(self, *args, **kwargs): 37 super().__init__(ecole.instance.SetCoverGenerator(*args, **kwargs))
An Instances object is an iterator that yields pyscipopt.Model.