|
|
- # Import necessary libraries
- %pip install gurobipy
- import pandas as pd
- from gurobipy import *
-
- # Define model
- model = Model("CloudServiceTransportation")
-
- # Number of providers (AWS, Azure, Google)
- m = 3 # AWS, Azure, Google
- # Number of services (C1, C2, AI/ML)
- n = 3 # C1, C2, AI/ML
-
- # Cost coefficients for AWS, Azure, and Google for each service (no storage cost)
- costs_AWS = {'C1': 0.1664, 'C2': 0.08, 'AI/ML': 3.06}
- costs_Azure = {'C1': 0.2021, 'C2': 0.10, 'AI/ML': 0.90}
- costs_Google = {'C1': 0.1900, 'C2': 0.10, 'AI/ML': 1.80}
-
- # Supply limits for each provider (AWS, Azure, Google) - fixed units
- supply_AWS = {'C1': 100, 'C2': 300, 'AI/ML': 50}
- supply_Azure = {'C1': 120, 'C2': 180, 'AI/ML': 80}
- supply_Google = {'C1': 130, 'C2': 200, 'AI/ML': 70}
-
- # Demand for each service (C1, C2, AI/ML)
- demand = {'C1': 100, 'C2': 100, 'AI/ML': 50}
-
- # Inter-provider egress costs
- inter_provider_egress = {
- ('AWS', 'Azure'): 20,
- ('AWS', 'Google'): 30,
- ('Azure', 'Google'): 15,
- ('Azure', 'AWS'): 25,
- ('Google', 'AWS'): 35,
- ('Google', 'Azure'): 10
- }
-
- # Budget constraint
- budget = 20000 # Total budget
-
- # Decision variables for quantities to transport
- x = {} # Amount of service allocated
- y = {} # Binary variable indicating provider selection
- w = {} # Egress costs between providers
-
- # Create decision variables
- for i, provider_from in enumerate(['AWS', 'Azure', 'Google']):
- for j, service in enumerate(['C1', 'C2', 'AI/ML']):
- x[i, j] = model.addVar(vtype=GRB.CONTINUOUS, lb=0, name=f"{provider_from}_{service}")
- y[i, j] = model.addVar(vtype=GRB.BINARY, name=f"provider_{provider_from}_service_{service}")
- for k, provider_to in enumerate(['AWS', 'Azure', 'Google']):
- if provider_from != provider_to:
- w[i, j, k] = model.addVar(vtype=GRB.CONTINUOUS, lb=0, name=f"egress_{provider_from}_{service}_{provider_to}")
-
- # Update model
- model.update()
-
- # Objective function: Minimize total cost (including egress costs)
- total_cost = (
- sum(costs_AWS[service] * x[0, j] for j, service in enumerate(['C1', 'C2', 'AI/ML'])) +
- sum(costs_Azure[service] * x[1, j] for j, service in enumerate(['C1', 'C2', 'AI/ML'])) +
- sum(costs_Google[service] * x[2, j] for j, service in enumerate(['C1', 'C2', 'AI/ML'])) +
- sum(inter_provider_egress[('AWS', 'Azure')] * w[0, j, 1] for j in range(n)) +
- sum(inter_provider_egress[('AWS', 'Google')] * w[0, j, 2] for j in range(n)) +
- sum(inter_provider_egress[('Azure', 'Google')] * w[1, j, 2] for j in range(n)) +
- sum(inter_provider_egress[('Azure', 'AWS')] * w[1, j, 0] for j in range(n)) +
- sum(inter_provider_egress[('Google', 'AWS')] * w[2, j, 0] for j in range(n)) +
- sum(inter_provider_egress[('Google', 'Azure')] * w[2, j, 1] for j in range(n))
- )
- model.setObjective(total_cost, GRB.MINIMIZE)
-
- # Supply constraints
- for i, provider in enumerate(['AWS', 'Azure', 'Google']):
- for j, service in enumerate(['C1', 'C2', 'AI/ML']):
- supply_limit = {'AWS': supply_AWS, 'Azure': supply_Azure, 'Google': supply_Google}[provider][service]
- model.addConstr(x[i, j] <= supply_limit * y[i, j], name=f"supply_{provider}_{service}")
-
- # Demand constraints
- for j, service in enumerate(['C1', 'C2', 'AI/ML']):
- model.addConstr(sum(x[i, j] for i in range(m)) == demand[service], name=f"demand_{service}")
-
- # Budget constraint
- model.addConstr(total_cost <= budget, name="BudgetConstraint")
-
- # Only one provider per service
- for j, service in enumerate(['C1', 'C2', 'AI/ML']):
- model.addConstr(sum(y[i, j] for i in range(m)) == 1, name=f"one_provider_per_service_{service}")
-
- # Egress constraints: Egress cost applies only when transferring between providers
- for i in range(m):
- for j in range(n):
- for k in range(m):
- if i != k:
- model.addConstr(w[i, j, k] <= x[i, j], name=f"egress_constraint_{i}_{j}_{k}")
-
- # Optimize model
- model.optimize()
-
- # Display results in a table format if optimal solution is found
- if model.status == GRB.OPTIMAL:
- # Create a list to hold the results
- results = []
-
- # Calculate egress costs dynamically for each provider
- egress_costs = {'AWS': 0, 'Azure': 0, 'Google': 0}
- for i, provider_from in enumerate(['AWS', 'Azure', 'Google']):
- for j in range(n):
- for k, provider_to in enumerate(['AWS', 'Azure', 'Google']):
- if provider_from != provider_to:
- egress_costs[provider_from] += w[i, j, k].x * inter_provider_egress[(provider_from, provider_to)]
-
- # Gather results for each provider
- for i, provider in enumerate(['AWS', 'Azure', 'Google']):
- row = [provider]
- # Add allocated quantities of each service
- for j, service in enumerate(['C1', 'C2', 'AI/ML']):
- allocated_quantity = x[i, j].x
- row.append(allocated_quantity)
- # Append the calculated egress cost
- row.append(egress_costs[provider])
- results.append(row)
-
- # Convert to DataFrame for display
- columns = ['Provider', 'C1 (units)', 'C2 (units)', 'AI/ML (units)', 'Egress Cost ($)']
- df = pd.DataFrame(results, columns=columns)
-
- # Display the DataFrame and the total optimal cost
- print(f"Optimal Cost: {model.objVal}")
- print(df)
- else:
- print("No optimal solution found")
-
|