def _read_df(self): os.makedirs('data/GammaRetail/', exist_ok=True) file_name = f"data/GammaRetail/store{self.store_idx+1}.csv" if os.path.exists(file_name): return pd.read_csv(file_name, parse_dates=[self.dt_col]) sku_info_list = Utils.get_sku_of_store(self.store_idx) data_list = [] for sku_info in sku_info_list: sale_gamma = sku_info['sale_gamma'] sku_name = sku_info['sku_name'] sku_price = sku_info['price'] for i in range(self.total_span): demand = int(np.random.gamma(sale_gamma)) data_list.append([ sku_name, self.start_dt + timedelta(i), demand, sku_price ]) df = pd.DataFrame(data_list, columns=[ self.id_col, self.dt_col, self.sale_col, self.sale_price_col ]) df.to_csv(file_name) return df
def create(x = 80, y = 32): world = World(x, y) world.grid = [[TerrainCell(xi, yi) for yi in range(y)] for xi in range(x)] def default_economy_config(order_cost=0, initial_balance = initial_balance): return ProductUnit.EconomyConfig(order_cost, initial_balance) # facility placement map_margin = 4 size_y_margins = world.size_y - 2*map_margin supplier_x = 10 retailer_x = 70 n_supplies = Utils.get_supplier_num() suppliers = [] supplier_skus = [] supplier_sources = dict() for i in range(n_supplies): supplier_config = SupplierCell.Config(max_storage_capacity=Utils.get_supplier_capacity(i), unit_storage_cost=Utils.get_supplier_unit_storage_cost(i), fleet_size=Utils.get_supplier_fleet_size(i), unit_transport_cost=Utils.get_supplier_unit_transport_cost(i)) if n_supplies > 1: supplier_y = int(size_y_margins/(n_supplies - 1)*i + map_margin) else: supplier_y = int(size_y_margins/2 + map_margin) f = SupplierCell(supplier_x, supplier_y, world, supplier_config, default_economy_config() ) f.idx_in_config = i f.facility_info = Utils.get_supplier_info(i) f.facility_short_name = Utils.get_supplier_short_name() world.agent_echelon[f.id] = 0 world.place_cell(f) suppliers.append(f) sku_info_list = Utils.get_sku_of_supplier(i) for _, sku_info in enumerate(sku_info_list): bom = BillOfMaterials({}, sku_info['sku_name']) supplier_sku_config = ProductUnit.Config(sources=None, unit_manufacturing_cost=sku_info['cost'], sale_gamma=sku_info.get('sale_gamma', 10), bill_of_materials=bom) sku = SKUSupplierUnit(f, supplier_sku_config, default_economy_config(order_cost=f.facility_info['order_cost']) ) sku.idx_in_config = sku_info['sku_name'] f.sku_in_stock.append(sku) sku.distribution = f.distribution sku.storage = f.storage sku.sku_info = sku_info f.storage.try_add_units({sku_info['sku_name']: sku_info['init_stock']}) supplier_skus.append(sku) if sku_info['sku_name'] not in supplier_sources: supplier_sources[sku_info['sku_name']] = [] supplier_sources[sku_info['sku_name']].append(sku) world.agent_echelon[sku.id] = 0 # distribution n_echelon = Utils.get_num_warehouse_echelon() pre_warehouses = suppliers all_warehouses = [] warehouse_skus = [] pre_warehouse_sources = supplier_sources for echelon in range(n_echelon): echelon_gap = (retailer_x-supplier_x)/(n_echelon+1) echelon_x = int(supplier_x+(echelon+1)*echelon_gap) n_warehouses = Utils.get_warehouse_num(echelon) warehouses = [] warehouse_sources = dict() for i in range(n_warehouses): warehouse_config = WarehouseCell.Config(max_storage_capacity=Utils.get_warehouse_capacity(echelon, i), unit_storage_cost=Utils.get_warehouse_unit_storage_cost(echelon, i), fleet_size=Utils.get_warehouse_fleet_size(echelon, i), unit_transport_cost=Utils.get_warehouse_unit_transport_cost(echelon, i)) if n_warehouses > 1: warehouse_y = int(size_y_margins/(n_warehouses - 1)*i + map_margin) else: warehouse_y = int(size_y_margins/2 + map_margin) w = WarehouseCell(echelon_x, warehouse_y, world, warehouse_config, default_economy_config() ) w.idx_in_config = i w.echelon_level = echelon w.facility_info = Utils.get_warehouse_info(echelon, i) w.facility_short_name = Utils.get_warehouse_short_name(echelon) world.agent_echelon[w.id] = 1+echelon world.place_cell(w) warehouses.append(w) WorldBuilder.connect_cells(world, w, *pre_warehouses) sku_info_list = Utils.get_sku_of_warehouse(echelon, i) for _, sku_info in enumerate(sku_info_list): candidate_upstream_suppliers = pre_warehouse_sources[sku_info['sku_name']] upstream_suppliers = [] for s in candidate_upstream_suppliers: if i in s.facility.facility_info['downstream_facilities']: upstream_suppliers.append(s) bom = BillOfMaterials({sku_info['sku_name']: 1}, sku_info['sku_name']) warehouse_sku_config = ProductUnit.Config(sources=upstream_suppliers, unit_manufacturing_cost=sku_info.get('cost', 10), sale_gamma=sku_info.get('sale_gamma', 10), bill_of_materials=bom) sku = SKUWarehouseUnit(w, warehouse_sku_config, default_economy_config(order_cost= w.facility_info['order_cost']) ) sku.idx_in_config = sku_info['sku_name'] w.sku_in_stock.append(sku) sku.distribution = w.distribution sku.storage = w.storage sku.sku_info = sku_info warehouse_skus.append(sku) w.storage.try_add_units({sku_info['sku_name']: sku_info.get('init_stock', 0)}) if sku_info['sku_name'] not in warehouse_sources: warehouse_sources[sku_info['sku_name']] = [] warehouse_sources[sku_info['sku_name']].append(sku) world.agent_echelon[sku.id] = 1+echelon # update downstreaming sku list in supplier_list for s_sku in upstream_suppliers: s_sku.downstream_skus.append(sku) all_warehouses.extend(warehouses) pre_warehouse_sources = warehouse_sources pre_warehouses = warehouses # final consumers n_stores = Utils.get_store_num() stores = [] store_skus = [] for i in range(n_stores): store_config = RetailerCell.Config(max_storage_capacity=Utils.get_store_capacity(i), unit_storage_cost=Utils.get_store_unit_storage_cost(i), fleet_size=1000, unit_transport_cost=10) if n_stores > 1: retailer_y = int(size_y_margins/(n_stores - 1)*i + map_margin) else: retailer_y = int(size_y_margins/2 + map_margin) r = RetailerCell(retailer_x, retailer_y, world, store_config, default_economy_config() ) r.idx_in_config = i r.facility_info = Utils.get_store_info(i) r.facility_short_name = Utils.get_store_short_name() world.agent_echelon[r.id] = 1+n_echelon world.place_cell(r) stores.append(r) WorldBuilder.connect_cells(world, r, *pre_warehouses) sku_info_list = Utils.get_sku_of_store(i) for _, sku_info in enumerate(sku_info_list): candidate_upstream_warehouses = pre_warehouse_sources[sku_info['sku_name']] upstream_warehouses = [] for s in candidate_upstream_warehouses: if i in s.facility.facility_info['downstream_facilities']: upstream_warehouses.append(s) bom = BillOfMaterials({sku_info['sku_name']: 1}, sku_info['sku_name']) retail_sku_config = ProductUnit.Config(sources=upstream_warehouses, unit_manufacturing_cost=sku_info.get('cost', 10), sale_gamma=sku_info.get('sale_gamma', 10), bill_of_materials=bom) if Utils.get_demand_sampler() == "DYNAMIC_GAMMA": sku = SKUStoreUnit(r, retail_sku_config, default_economy_config(order_cost=r.facility_info['order_cost']) ) elif Utils.get_demand_sampler() == "GAMMA": sale_sampler = gamma_sale_sampler(i) sku = OuterSKUStoreUnit(r, retail_sku_config, default_economy_config(order_cost=r.facility_info['order_cost']), sale_sampler ) else: sale_sampler = online_sale_sampler(f"data/OnlineRetail/store{i+1}_new.csv") sku = OuterSKUStoreUnit(r, retail_sku_config, default_economy_config(order_cost=r.facility_info['order_cost']), sale_sampler ) sku.idx_in_config = sku_info['sku_name'] r.sku_in_stock.append(sku) sku.storage = r.storage sku.sku_info = sku_info r.storage.try_add_units({sku_info['sku_name']: sku_info.get('init_stock', 0)}) store_skus.append(sku) world.agent_echelon[sku.id] = 1+n_echelon # update downstreaming sku list in warehouse_list for w_sku in upstream_warehouses: w_sku.downstream_skus.append(sku) for facility in suppliers + all_warehouses + stores: world.facilities[facility.id] = facility for sku in supplier_skus + warehouse_skus + store_skus: world.facilities[sku.id] = sku if sku.sku_info.get('price', 0) > world.max_price: world.max_price = sku.sku_info.get('price', 0) world.total_echelon = Utils.get_total_echelon() return world