#3 temp code

Open
opened 1 month ago by anpham · 0 comments
anpham commented 1 month ago
Owner

from gurobipy import GRB, Model, quicksum

Example data for costs, supply, and demand

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_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 = {'C1': 100, 'C2': 50, 'AI/ML': 50}

Egress cost between different providers (no self transfer cost)

egress_cost = {
('AWS', 'Azure'): 0.10, # hourly rate
('AWS', 'Google'): 0.15,
('Azure', 'AWS'): 0.10,
('Azure', 'Google'): 0.12,
('Google', 'AWS'): 0.15,
('Google', 'Azure'): 0.12
}

Budget constraint

budget = 1000

Create a model

model = Model()

Define decision variables

providers = ['AWS', 'Azure', 'Google']
services = ['C1', 'C2', 'AI/ML']
m = len(providers) # Number of providers
n = len(services) # Number of services

Decision variables

x = model.addVars(m, n, vtype=GRB.CONTINUOUS, name="x") # Allocation variables
w = model.addVars(m, n, m, vtype=GRB.CONTINUOUS, name="w") # Egress transfer flow
y = model.addVars(m, n, vtype=GRB.BINARY, name="y") # Provider selection binary variables

Objective function: Minimize the total cost (service allocation + egress costs)

model.setObjective(
quicksum(
costs_AWS[services[j]] * x[0, j] +
costs_Azure[services[j]] * x[1, j] +
costs_Google[services[j]] * x[2, j]
for j in range(n)
) +
quicksum(
egress_cost.get(('AWS', 'Azure'), 0) * w[0, j, 1] +
egress_cost.get(('AWS', 'Google'), 0) * w[0, j, 2] +
egress_cost.get(('Azure', 'AWS'), 0) * w[1, j, 0] +
egress_cost.get(('Azure', 'Google'), 0) * w[1, j, 2] +
egress_cost.get(('Google', 'AWS'), 0) * w[2, j, 0] +
egress_cost.get(('Google', 'Azure'), 0) * w[2, j, 1]
for j in range(n)
),
GRB.MINIMIZE
)

Supply-Demand Constraint: Ensure total allocation for each service meets the demand

model.addConstrs(
quicksum(x[i, j] for i in range(m)) == demand[services[j]]
for j in range(n)
)

Supply Constraint: Ensure allocation for each service from each provider doesn't exceed its supply for that service

model.addConstrs(
x[i, j] <= [supply_AWS, supply_Azure, supply_Google][i][services[j]]
for i in range(m)
for j in range(n)
)

One Provider Per Service Constraint: Ensure only one provider per service

model.addConstrs(
quicksum(y[i, j] for i in range(m)) == 1
for j in range(n)
)

Egress Transfer Constraints: Ensure egress flows match allocations

for i in range(m):
for j in range(n):
for k in range(m):
if i != k: # Only for different providers, flow is counted in term of hours.
model.addConstr(w[i, j, k] == x[i, j], name=f"egress_transfer_{i}_{j}_{k}")

Budget Constraint: Ensure the total cost (service allocation + egress costs) does not exceed the budget

total_cost = quicksum(
costs_AWS[services[j]] * x[0, j] +
costs_Azure[services[j]] * x[1, j] +
costs_Google[services[j]] * x[2, j]
for j in range(n)
) + quicksum(
egress_cost.get(('AWS', 'Azure'), 0) * w[0, j, 1] +
egress_cost.get(('AWS', 'Google'), 0) * w[0, j, 2] +
egress_cost.get(('Azure', 'AWS'), 0) * w[1, j, 0] +
egress_cost.get(('Azure', 'Google'), 0) * w[1, j, 2] +
egress_cost.get(('Google', 'AWS'), 0) * w[2, j, 0] +
egress_cost.get(('Google', 'Azure'), 0) * w[2, j, 1]
for j in range(n)
)

model.addConstr(total_cost <= budget, "BudgetConstraint")

Solve the model

model.optimize()

Display results

if model.status == GRB.OPTIMAL:
print("Optimal solution found!")
for i in range(m):
for j in range(n):
print(f"Provider {providers[i]} service {services[j]} allocation: {x[i, j].x}")
# Output total egress cost
total_egress_cost = sum(
egress_cost.get(('AWS', 'Azure'), 0) * w[0, j, 1].x +
egress_cost.get(('AWS', 'Google'), 0) * w[0, j, 2].x +
egress_cost.get(('Azure', 'AWS'), 0) * w[1, j, 0].x +
egress_cost.get(('Azure', 'Google'), 0) * w[1, j, 2].x +
egress_cost.get(('Google', 'AWS'), 0) * w[2, j, 0].x +
egress_cost.get(('Google', 'Azure'), 0) * w[2, j, 1].x
for j in range(n)
)
print(f"Total egress cost: {total_egress_cost}")
else:
print("No optimal solution found.")

from gurobipy import GRB, Model, quicksum # Example data for costs, supply, and demand 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_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 = {'C1': 100, 'C2': 50, 'AI/ML': 50} # Egress cost between different providers (no self transfer cost) egress_cost = { ('AWS', 'Azure'): 0.10, # hourly rate ('AWS', 'Google'): 0.15, ('Azure', 'AWS'): 0.10, ('Azure', 'Google'): 0.12, ('Google', 'AWS'): 0.15, ('Google', 'Azure'): 0.12 } # Budget constraint budget = 1000 # Create a model model = Model() # Define decision variables providers = ['AWS', 'Azure', 'Google'] services = ['C1', 'C2', 'AI/ML'] m = len(providers) # Number of providers n = len(services) # Number of services # Decision variables x = model.addVars(m, n, vtype=GRB.CONTINUOUS, name="x") # Allocation variables w = model.addVars(m, n, m, vtype=GRB.CONTINUOUS, name="w") # Egress transfer flow y = model.addVars(m, n, vtype=GRB.BINARY, name="y") # Provider selection binary variables # Objective function: Minimize the total cost (service allocation + egress costs) model.setObjective( quicksum( costs_AWS[services[j]] * x[0, j] + costs_Azure[services[j]] * x[1, j] + costs_Google[services[j]] * x[2, j] for j in range(n) ) + quicksum( egress_cost.get(('AWS', 'Azure'), 0) * w[0, j, 1] + egress_cost.get(('AWS', 'Google'), 0) * w[0, j, 2] + egress_cost.get(('Azure', 'AWS'), 0) * w[1, j, 0] + egress_cost.get(('Azure', 'Google'), 0) * w[1, j, 2] + egress_cost.get(('Google', 'AWS'), 0) * w[2, j, 0] + egress_cost.get(('Google', 'Azure'), 0) * w[2, j, 1] for j in range(n) ), GRB.MINIMIZE ) # **Supply-Demand Constraint**: Ensure total allocation for each service meets the demand model.addConstrs( quicksum(x[i, j] for i in range(m)) == demand[services[j]] for j in range(n) ) # **Supply Constraint**: Ensure allocation for each service from each provider doesn't exceed its supply for that service model.addConstrs( x[i, j] <= [supply_AWS, supply_Azure, supply_Google][i][services[j]] for i in range(m) for j in range(n) ) # **One Provider Per Service Constraint**: Ensure only one provider per service model.addConstrs( quicksum(y[i, j] for i in range(m)) == 1 for j in range(n) ) # **Egress Transfer Constraints**: Ensure egress flows match allocations for i in range(m): for j in range(n): for k in range(m): if i != k: # Only for different providers, flow is counted in term of hours. model.addConstr(w[i, j, k] == x[i, j], name=f"egress_transfer_{i}_{j}_{k}") # **Budget Constraint**: Ensure the total cost (service allocation + egress costs) does not exceed the budget total_cost = quicksum( costs_AWS[services[j]] * x[0, j] + costs_Azure[services[j]] * x[1, j] + costs_Google[services[j]] * x[2, j] for j in range(n) ) + quicksum( egress_cost.get(('AWS', 'Azure'), 0) * w[0, j, 1] + egress_cost.get(('AWS', 'Google'), 0) * w[0, j, 2] + egress_cost.get(('Azure', 'AWS'), 0) * w[1, j, 0] + egress_cost.get(('Azure', 'Google'), 0) * w[1, j, 2] + egress_cost.get(('Google', 'AWS'), 0) * w[2, j, 0] + egress_cost.get(('Google', 'Azure'), 0) * w[2, j, 1] for j in range(n) ) model.addConstr(total_cost <= budget, "BudgetConstraint") # Solve the model model.optimize() # Display results if model.status == GRB.OPTIMAL: print("Optimal solution found!") for i in range(m): for j in range(n): print(f"Provider {providers[i]} service {services[j]} allocation: {x[i, j].x}") # Output total egress cost total_egress_cost = sum( egress_cost.get(('AWS', 'Azure'), 0) * w[0, j, 1].x + egress_cost.get(('AWS', 'Google'), 0) * w[0, j, 2].x + egress_cost.get(('Azure', 'AWS'), 0) * w[1, j, 0].x + egress_cost.get(('Azure', 'Google'), 0) * w[1, j, 2].x + egress_cost.get(('Google', 'AWS'), 0) * w[2, j, 0].x + egress_cost.get(('Google', 'Azure'), 0) * w[2, j, 1].x for j in range(n) ) print(f"Total egress cost: {total_egress_cost}") else: print("No optimal solution found.")
Sign in to join this conversation.
No Label
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date

No due date set.

Dependencies

This issue currently doesn't have any dependencies.

Loading…
There is no content yet.