akalikadien / shell-ai-hackaton-2023

Repo for the agricultural waste challenge of Shell.ai 2023 https://www.shell.com/energy-and-innovation/digitalisation/digital-and-ai-competitions/shell-ai-hackathon-for-sustainable-and-affordable-energy.html
0 stars 0 forks source link

Add flow from site to depot #8

Open vsinha027 opened 1 year ago

vsinha027 commented 1 year ago

https://github.com/akalikadien/shell-ai-hackaton-2023/blob/96f4d4721210dd5bfbfc90faf08dc17a9c5ca04f/place_storage_and_refineries_optimize_flow.py#L181C17-L184C97

Here the code simply fills up the depot until it reaches 20000 capacity. This will not respect constraint 1.

We need to create a flow where biomass is provided from a site i and dumped onto a depot. I suggest to modify the code such that input from sites that can contribute biomass i.e. same label as the depot from kmedoids is taken until the depot is full capacity. Then we need to make sure that rest of the biomass is also routed to other depots. An idea could be to first connect the sites to their respective depots until full capacity of depot is reached. This will lead to:

  1. Sites with excess biomass
  2. Depots that are under capacity. Then make a rerun with the next nearest neighbor kind of approach until 80% of biomass is used.
BuenoGrande commented 1 year ago

What do you think of this code:

def mutate(self, offspring):
    if np.random.rand() > self.mutation_rate:
        return offspring

    offspring1, offspring2 = offspring

    # Mutation for flow from sites to depots
    remaining_biomass = self.biomass_df_values.copy()
    depot_capacities = np.full(self.num_depots, 20000)
    for i in range(offspring1.shape[0]):
        for j in range(offspring1.shape[1]):
            # Calculate the remaining capacity of the depot
            remaining_capacity = depot_capacities[j]
            if remaining_capacity > 0 and remaining_biomass[i] > 0:
                # Generate a new flow within the minimum of the remaining capacity, the site's biomass, and the remaining biomass
                new_flow = min(remaining_capacity, remaining_biomass[i])
                offspring1[i, j] = new_flow
                remaining_biomass[i] -= new_flow
                depot_capacities[j] -= new_flow

    # Mutation for flow from depots to refineries
    remaining_capacity = np.full(self.num_biorefineries, 100000)
    for j in range(offspring2.shape[0]):
        for k in range(offspring2.shape[1]):
            # Calculate the remaining capacity of the refinery
            depot_remaining_capacity = depot_capacities[j]
            refinery_remaining_capacity = remaining_capacity[k]
            if depot_remaining_capacity > 0 and refinery_remaining_capacity > 0:
                # Generate a new flow within the remaining capacity
                new_flow = min(depot_remaining_capacity, refinery_remaining_capacity)
                offspring2[j, k] = new_flow
                depot_capacities[j] -= new_flow
                remaining_capacity[k] -= new_flow

    # Ensure mass balance for the offspring
    offspring1 = self.balance_mass(offspring1)
    offspring2 = self.balance_mass(offspring2)
    return offspring1, offspring2

We first assign the biomass from each site to its associated depot until the depot's capacity is reached or the site's biomass is exhausted. It then assigns biomass from each depot to its associated refinery until the refinery's capacity is reached or the depot's biomass is exhausted. This ensures that the total biomass assigned from each site does not exceed its actual value, and that the total biomass assigned to each depot or refinery does not exceed its capacity.

I have not pushed this code yet. Let me know if this is what you meant.