Exemple #1
0
 def reset(self):
     # print("Rst!")
     if(self.env_config['training'] and self.env_config['init']=='rnd' and self.copy_world):
         self.world = self.copy_world
     elif(self.env_config['training'] and self.env_config['init']=='rst'):
         self.world.reset()
     else:
         self.world = WorldBuilder.create(80, 16)
     state, _ = self.state_calculator.world_to_state(self.world)
     if(Utils.get_demand_sampler()=='ONLINE'):
         self.set_retailer_step(0)
     # print(state)
     return state
Exemple #2
0
    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
Exemple #3
0
def visualization(env, policies, iteration, policy_mode, basestock=False):

    policy_mode = policy_mode  # + f'_{iteration}'

    renderer = AsciiWorldRenderer()
    frame_seq = []

    evaluation_epoch_len = env.env_config['evaluation_len']
    starter_step = env.env_config['episod_duration']+env.env_config['tail_timesteps']
    env.set_iteration(1, 1)
    # env.env_config.update({'episod_duration': evaluation_epoch_len, 'downsampling_rate': 1})
    print(
        f"Environment: Producer action space {env.action_space_producer}, Consumer action space {env.action_space_consumer}, Observation space {env.observation_space}"
        , flush=True)
    obss = env.reset()
    if basestock:
        from scheduler.inventory_base_stock_policy import ConsumerBaseStockPolicy
        ConsumerBaseStockPolicy.facilities = env.world.facilities    

    if Utils.get_demand_sampler()=='ONLINE':
        env.set_retailer_step(starter_step)
    _, infos = env.state_calculator.world_to_state(env.world)


    # policies = {}
    rnn_states = {}
    rewards = {}
    for agent_id in obss.keys():
        # policies[agent_id] = load_policy(agent_id)
        rnn_states[agent_id] = policies[agent_id].get_initial_state()
        rewards[agent_id] = 0

    # Simulation loop
    tracker = SimulationTracker(evaluation_epoch_len, 1, env.agent_ids())
    print(f"  === evaluation length {evaluation_epoch_len}, it will take about 1 min ....", flush=True)

    for epoch in range(evaluation_epoch_len):
        action_dict = {}
        for agent_id, obs in obss.items():
            policy = policies[agent_id]
            action, new_state, _ = policy.compute_single_action(obs, state=rnn_states[agent_id], info=infos[agent_id],
                                                                explore=False)
            action_dict[agent_id] = action
            # if agent_id.startswith('SKUStoreUnit') and Utils.is_consumer_agent(agent_id):
            #     print(agent_id, action, rewards[agent_id])
            #     print(obs.tolist())
        obss, rewards, dones, infos = env.step(action_dict)
        step_balances = {}
        for agent_id in rewards.keys():
            step_balances[agent_id] = env.world.facilities[Utils.agentid_to_fid(agent_id)].economy.step_balance.total()
        # print(env.world.economy.global_balance().total(), step_balances, rewards)
        tracker.add_sample(0, epoch, env.world.economy.global_balance().total(), step_balances, rewards)
        # some stats
        stock_status = env.get_stock_status()
        order_in_transit_status = env.get_order_in_transit_status()
        demand_status = env.get_demand_status()

        tracker.add_sku_status(0, epoch, stock_status, order_in_transit_status, demand_status)

        frame = renderer.render(env.world)
        frame_seq.append(np.asarray(frame))

    print(tracker.get_retailer_profit())

    if not os.path.exists('output'):
        os.mkdir('output')

    if not os.path.exists('output/%s' % policy_mode):
        os.mkdir('output/%s' % policy_mode)

    if not os.path.exists(f'output/{policy_mode}/iter_{iteration}'):
        os.mkdir(f'output/{policy_mode}/iter_{iteration}')

    # tracker.render("output/%s/plot.png" % policy_mode)
    tracker.render(f'output/{policy_mode}/iter_{iteration}/plot.png')
    tracker.render_sku(policy_mode, iteration)
    print(f"  === evaluation length end ", flush=True)