Skip to main content
Glama

Constrained Optimization MCP Server

knapsack.pyโ€ข10.3 kB
#!/usr/bin/env python3 """ Knapsack Problem using Constrained Optimization MCP Server The knapsack problem is a classic optimization problem where we have a set of items, each with a weight and value, and we want to maximize the total value while staying within a weight limit. This example demonstrates: - Integer programming - OR-Tools constraint programming - Binary decision variables - Multiple knapsack variants """ import numpy as np import matplotlib.pyplot as plt from constrained_opt_mcp.models.ortools_models import ( ORToolsProblem, ORToolsVariable, ORToolsConstraint ) from constrained_opt_mcp.solvers.ortools_solver import solve_problem def solve_knapsack(values, weights, capacity): """Solve the 0/1 knapsack problem""" n_items = len(values) # Create problem problem = ORToolsProblem( name="Knapsack Problem", problem_type="constraint_programming" ) # Create binary variables: x[i] = 1 if item i is selected items = [] for i in range(n_items): var = ORToolsVariable( name=f"item_{i}", domain=[0, 1], var_type="binary" ) items.append(var) problem.add_variable(var) # Objective: maximize total value problem.set_objective( objective_type="maximize", coefficients=values, variables=items ) # Constraint: total weight <= capacity problem.add_constraint(ORToolsConstraint( name="weight_constraint", constraint_type="less_equal", variables=items, coefficients=weights, constant=capacity )) # Solve the problem solution = solve_problem(problem) if solution.is_optimal: selected_items = [solution.variable_values[f"item_{i}"] for i in range(n_items)] total_value = sum(values[i] * selected_items[i] for i in range(n_items)) total_weight = sum(weights[i] * selected_items[i] for i in range(n_items)) return { 'selected_items': selected_items, 'total_value': total_value, 'total_weight': total_weight, 'capacity': capacity } else: return None def solve_multiple_knapsack(values, weights, capacities): """Solve the multiple knapsack problem""" n_items = len(values) n_knapsacks = len(capacities) # Create problem problem = ORToolsProblem( name="Multiple Knapsack Problem", problem_type="constraint_programming" ) # Create binary variables: x[i][j] = 1 if item i is in knapsack j items = [] for i in range(n_items): for j in range(n_knapsacks): var = ORToolsVariable( name=f"item_{i}_knapsack_{j}", domain=[0, 1], var_type="binary" ) items.append(var) problem.add_variable(var) # Objective: maximize total value objective_coeffs = [] for i in range(n_items): for j in range(n_knapsacks): objective_coeffs.append(values[i]) problem.set_objective( objective_type="maximize", coefficients=objective_coeffs, variables=items ) # Constraints: each item can be in at most one knapsack for i in range(n_items): item_vars = [items[i * n_knapsacks + j] for j in range(n_knapsacks)] problem.add_constraint(ORToolsConstraint( name=f"item_{i}_unique", constraint_type="less_equal", variables=item_vars, coefficients=[1] * n_knapsacks, constant=1 )) # Constraints: each knapsack weight limit for j in range(n_knapsacks): knapsack_vars = [items[i * n_knapsacks + j] for i in range(n_items)] knapsack_weights = [weights[i] for i in range(n_items)] problem.add_constraint(ORToolsConstraint( name=f"knapsack_{j}_capacity", constraint_type="less_equal", variables=knapsack_vars, coefficients=knapsack_weights, constant=capacities[j] )) # Solve the problem solution = solve_problem(problem) if solution.is_optimal: result = { 'assignments': {}, 'total_value': 0, 'knapsack_weights': [0] * n_knapsacks } for i in range(n_items): for j in range(n_knapsacks): var_name = f"item_{i}_knapsack_{j}" if solution.variable_values[var_name] == 1: if j not in result['assignments']: result['assignments'][j] = [] result['assignments'][j].append(i) result['total_value'] += values[i] result['knapsack_weights'][j] += weights[i] return result else: return None def visualize_knapsack_solution(values, weights, solution, capacity): """Visualize the knapsack solution""" if not solution: print("No solution found!") return selected_items = solution['selected_items'] total_value = solution['total_value'] total_weight = solution['total_weight'] # Create visualization fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(15, 6)) # Plot 1: Item selection n_items = len(values) x_pos = np.arange(n_items) colors = ['green' if selected_items[i] else 'red' for i in range(n_items)] bars = ax1.bar(x_pos, values, color=colors, alpha=0.7) ax1.set_xlabel('Item Index') ax1.set_ylabel('Value') ax1.set_title('Knapsack Solution: Selected Items') ax1.set_xticks(x_pos) ax1.grid(True, alpha=0.3) # Add value labels on bars for i, (bar, value) in enumerate(zip(bars, values)): if selected_items[i]: ax1.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.1, f'{value}', ha='center', va='bottom', fontweight='bold') # Plot 2: Weight vs Value scatter selected_values = [values[i] for i in range(n_items) if selected_items[i]] selected_weights = [weights[i] for i in range(n_items) if selected_items[i]] unselected_values = [values[i] for i in range(n_items) if not selected_items[i]] unselected_weights = [weights[i] for i in range(n_items) if not selected_items[i]] ax2.scatter(selected_weights, selected_values, c='green', s=100, alpha=0.7, label='Selected') ax2.scatter(unselected_weights, unselected_values, c='red', s=100, alpha=0.7, label='Not Selected') ax2.set_xlabel('Weight') ax2.set_ylabel('Value') ax2.set_title('Weight vs Value Distribution') ax2.legend() ax2.grid(True, alpha=0.3) # Add capacity line ax2.axvline(x=capacity, color='blue', linestyle='--', alpha=0.7, label=f'Capacity: {capacity}') ax2.legend() plt.tight_layout() plt.show() # Print summary print(f"\nKnapsack Solution Summary:") print(f"Total Value: {total_value}") print(f"Total Weight: {total_weight}/{capacity}") print(f"Capacity Utilization: {total_weight/capacity:.1%}") print(f"Selected Items: {[i for i in range(n_items) if selected_items[i]]}") def generate_knapsack_data(n_items=20, max_value=100, max_weight=50): """Generate random knapsack data""" np.random.seed(42) values = np.random.randint(1, max_value + 1, n_items) weights = np.random.randint(1, max_weight + 1, n_items) capacity = int(0.6 * sum(weights)) # 60% of total weight return values, weights, capacity def analyze_knapsack_performance(): """Analyze performance for different problem sizes""" sizes = [10, 20, 50, 100] solve_times = [] optimal_values = [] for n in sizes: print(f"Solving knapsack with {n} items...") values, weights, capacity = generate_knapsack_data(n) import time start_time = time.time() solution = solve_knapsack(values, weights, capacity) end_time = time.time() solve_time = end_time - start_time solve_times.append(solve_time) if solution: optimal_values.append(solution['total_value']) print(f" Optimal value: {solution['total_value']}, Time: {solve_time:.3f}s") else: optimal_values.append(0) print(f" No solution found, Time: {solve_time:.3f}s") # Plot performance fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5)) ax1.plot(sizes, solve_times, 'bo-', linewidth=2, markersize=8) ax1.set_xlabel('Number of Items') ax1.set_ylabel('Solve Time (seconds)') ax1.set_title('Knapsack Solve Time') ax1.grid(True, alpha=0.3) ax2.plot(sizes, optimal_values, 'go-', linewidth=2, markersize=8) ax2.set_xlabel('Number of Items') ax2.set_ylabel('Optimal Value') ax2.set_title('Optimal Values') ax2.grid(True, alpha=0.3) plt.tight_layout() plt.show() if __name__ == "__main__": print("Knapsack Problem Solver") print("=" * 50) # Generate sample data values, weights, capacity = generate_knapsack_data(20) print(f"Problem: {len(values)} items, capacity = {capacity}") print(f"Values: {values}") print(f"Weights: {weights}") # Solve single knapsack print("\nSolving single knapsack problem...") solution = solve_knapsack(values, weights, capacity) if solution: visualize_knapsack_solution(values, weights, solution, capacity) else: print("No solution found!") # Solve multiple knapsack print("\nSolving multiple knapsack problem...") capacities = [capacity // 2, capacity // 2] multi_solution = solve_multiple_knapsack(values, weights, capacities) if multi_solution: print(f"Multiple knapsack solution:") print(f"Total value: {multi_solution['total_value']}") for knapsack, items in multi_solution['assignments'].items(): print(f"Knapsack {knapsack}: items {items}, weight: {multi_solution['knapsack_weights'][knapsack]}") print("\nPerformance Analysis:") analyze_knapsack_performance()

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/Sharmarajnish/MCP-Constrained-Optimization'

If you have feedback or need assistance with the MCP directory API, please join our Discord server