def build_knapsack_cqm(costs, weights, max_weight): """Construct a CQM for the knapsack problem. Args: costs (array-like): Array of costs for the items. weights (array-like): Array of weights for the items. max_weight (int): Maximum allowable weight for the knapsack. Returns: Constrained quadratic model instance that represents the knapsack problem. """ num_items = len(costs) print("\nBuilding a CQM for {} items.".format(str(num_items))) cqm = ConstrainedQuadraticModel() obj = BinaryQuadraticModel(vartype='BINARY') constraint = QuadraticModel() for i in range(num_items): # Objective is to maximize the total costs obj.add_variable(i) obj.set_linear(i, -costs[i]) # Constraint is to keep the sum of items' weights under or equal capacity constraint.add_variable('BINARY', i) constraint.set_linear(i, weights[i]) cqm.set_objective(obj) cqm.add_constraint(constraint, sense="<=", rhs=max_weight, label='capacity') return cqm
def build_cqm(W, C, n, p, a, verbose=True): """Builds constrained quadratic model representing the optimization problem. Args: - W: Numpy matrix. Represents passenger demand. Normalized with total demand equal to 1. - C: Numpy matrix. Represents airline leg cost. - n: Int. Number of cities in play. - p: Int. Number of hubs airports allowed. - a: Float in [0.0, 1.0]. Discount allowed for hub-hub legs. - verbose: Print to command-line for user. Returns: - cqm: ConstrainedQuadraticModel representing the optimization problem. """ if verbose: print("\nBuilding CQM...\n") # Initialize the CQM object cqm = ConstrainedQuadraticModel() # Objective: Minimize cost. min c'x+x'Qx # See reference paper for full explanation. M = np.sum(W, axis=0) + np.sum(W, axis=1) Q = a * np.kron(W, C) linear = ((M * C.T).T).flatten() obj = BinaryQuadraticModel(linear, Q, 'BINARY') obj.relabel_variables({ idx: (i, j) for idx, (i, j) in enumerate( (i, j) for i in range(n) for j in range(n)) }) cqm.set_objective(obj) # Add constraint to make variables discrete for v in range(n): cqm.add_discrete([(v, i) for i in range(n)]) # Constraint: Every leg must connect to a hub. for i in range(n): for j in range(n): if i != j: c1 = BinaryQuadraticModel('BINARY') c1.add_linear((i, j), 1) c1.add_quadratic((i, j), (j, j), -1) cqm.add_constraint(c1 == 0) # Constraint: Exactly p hubs required. linear_terms = {(i, i): 1.0 for i in range(n)} c2 = BinaryQuadraticModel('BINARY') c2.add_linear_from(linear_terms) cqm.add_constraint(c2 == p, label='num hubs') return cqm