# Complete Optimization Problem and Solution: workshop_paper

## 1. Problem Context and Goals

### Context  
The conference organizer is tasked with selecting submissions for various workshops, aiming to maximize the overall quality of accepted submissions. Each submission is evaluated based on a quality score, and the decision to accept a submission is represented by a binary variable indicating acceptance status. The organizer must ensure that each workshop meets a minimum number of accepted submissions while not exceeding the venue's capacity. The operational parameters include the minimum number of submissions required per workshop and the maximum number of submissions that can be accepted in each workshop. These parameters are critical in guiding the decision-making process and ensuring that the optimization problem remains linear. The business configuration includes scalar parameters that define these constraints, ensuring that the optimization aligns with the operational realities of the conference.

### Goals  
The primary goal of the optimization is to maximize the total score of accepted submissions. This involves selecting submissions that contribute the highest quality scores while adhering to the constraints of venue capacity and minimum submission requirements. The success of this optimization is measured by the total score achieved, which is calculated by summing the quality scores of all accepted submissions. The objective is clearly defined in linear terms, focusing on maximizing the sum of scores associated with accepted submissions.

## 2. Constraints    

The optimization problem is subject to several constraints that ensure the feasibility of the solution:

- Each workshop has a maximum capacity, which means the total number of accepted submissions for any workshop must not exceed its designated capacity. This constraint ensures that the venue's limitations are respected.
  
- Additionally, each workshop must have a minimum number of accepted submissions to ensure that the workshop is viable and meets the expectations of attendees. This constraint guarantees that workshops are sufficiently populated.

These constraints are expressed in business terms that naturally lead to linear mathematical forms, ensuring that the optimization problem remains tractable and aligned with the operational goals of the conference.

## 3. Available Data  

### Database Schema  
```sql
-- Iteration 1 Database Schema
-- Objective: Schema changes include adding tables for venue capacity and minimum submissions per workshop, modifying existing tables to improve mapping adequacy, and updating configuration logic for scalar parameters and formulas.

CREATE TABLE submission (
  Scores FLOAT
);

CREATE TABLE VenueCapacity (
  workshop_id INTEGER,
  capacity INTEGER
);

CREATE TABLE WorkshopSubmissions (
  workshop_id INTEGER,
  min_submissions INTEGER
);

CREATE TABLE Acceptance (
  Result BOOLEAN,
  workshop_id INTEGER
);
```

### Data Dictionary  
The data dictionary provides a comprehensive mapping of tables and columns to their business purposes and optimization roles:

- **Submission Table**: This table stores information about each submission, specifically the quality score, which is used to calculate the total score of accepted submissions. The scores range from 0.0 to 10.0, reflecting the quality of each submission.

- **VenueCapacity Table**: This table records the maximum capacity for each workshop, linking the capacity to specific workshops. The capacity represents the maximum number of submissions that can be accepted, ensuring that the venue's limitations are respected.

- **WorkshopSubmissions Table**: This table captures the minimum required submissions for each workshop, linking these requirements to specific workshops. The minimum submissions ensure that each workshop is viable and meets the expectations of attendees.

- **Acceptance Table**: This table tracks the acceptance status of submissions, indicating whether a submission is accepted. The acceptance status is a binary decision variable in the optimization process, associating submissions with specific workshops.

### Current Stored Values  
```sql
-- Iteration 1 Realistic Data
-- Generated by triple expert (business + data + optimization)
-- Values were determined based on typical conference workshop sizes and submission quality scores, ensuring a balance between capacity and minimum submission requirements.

-- Realistic data for submission
INSERT INTO submission (Scores) VALUES (8.5);
INSERT INTO submission (Scores) VALUES (6.0);
INSERT INTO submission (Scores) VALUES (9.2);
INSERT INTO submission (Scores) VALUES (7.3);
INSERT INTO submission (Scores) VALUES (5.5);

-- Realistic data for VenueCapacity
INSERT INTO VenueCapacity (workshop_id, capacity) VALUES (1, 50);
INSERT INTO VenueCapacity (workshop_id, capacity) VALUES (2, 100);
INSERT INTO VenueCapacity (workshop_id, capacity) VALUES (3, 150);

-- Realistic data for WorkshopSubmissions
INSERT INTO WorkshopSubmissions (workshop_id, min_submissions) VALUES (1, 3);
INSERT INTO WorkshopSubmissions (workshop_id, min_submissions) VALUES (2, 5);
INSERT INTO WorkshopSubmissions (workshop_id, min_submissions) VALUES (3, 7);

-- Realistic data for Acceptance
INSERT INTO Acceptance (Result, workshop_id) VALUES (True, 1);
INSERT INTO Acceptance (Result, workshop_id) VALUES (False, 1);
INSERT INTO Acceptance (Result, workshop_id) VALUES (True, 2);
INSERT INTO Acceptance (Result, workshop_id) VALUES (True, 3);
INSERT INTO Acceptance (Result, workshop_id) VALUES (False, 3);
```

## 4. Mathematical Optimization Formulation

#### Decision Variables
- Let \( x_{ij} \) be a binary decision variable where \( x_{ij} = 1 \) if submission \( j \) is accepted for workshop \( i \), and \( x_{ij} = 0 \) otherwise.

#### Objective Function
Maximize the total quality score of accepted submissions:
\[ \text{Maximize } \sum_{i} \sum_{j} \text{Scores}_j \times x_{ij} \]

Data Source Verification:
- Coefficient \(\text{Scores}_j\) comes from `submission.Scores`.

#### Constraints
1. **Workshop Capacity Constraints**: Ensure that the total number of accepted submissions for each workshop does not exceed its capacity.
   \[
   \sum_{j} x_{ij} \leq \text{capacity}_i \quad \forall i
   \]

   Data Source Verification:
   - Coefficient \(\text{capacity}_i\) comes from `VenueCapacity.capacity`.

2. **Minimum Submissions Constraints**: Ensure that each workshop has at least the minimum required number of accepted submissions.
   \[
   \sum_{j} x_{ij} \geq \text{min\_submissions}_i \quad \forall i
   \]

   Data Source Verification:
   - Coefficient \(\text{min\_submissions}_i\) comes from `WorkshopSubmissions.min_submissions`.

3. **Binary Decision Variables**: Ensure that each decision variable is binary.
   \[
   x_{ij} \in \{0, 1\} \quad \forall i, j
   \]

This formulation provides a complete linear optimization model that can be solved using standard linear programming or mixed-integer programming solvers. The objective function and constraints are derived directly from the provided data, ensuring alignment with the business problem's requirements.

## 5. Gurobipy Implementation

```python
# Complete GUROBIPY implementation - Retry Attempt 4

import gurobipy as gp
from gurobipy import GRB

def optimize_workshop_paper():
    # 1. MODEL & DATA SETUP
    model = gp.Model("workshop_paper")
    
    # Data from the database
    scores = [8.5, 6.0, 9.2, 7.3, 5.5]
    capacities = {1: 50, 2: 100, 3: 150}
    min_submissions = {1: 3, 2: 5, 3: 7}
    
    # Number of submissions
    n_submissions = len(scores)
    n_workshops = len(capacities)
    
    # CRITICAL: Validate array lengths before loops
    assert len(scores) == n_submissions, "Array length mismatch for scores"
    
    # 2. VARIABLES
    # Binary decision variables for acceptance of submissions
    x = model.addVars(n_workshops, n_submissions, vtype=GRB.BINARY, name="x")
    
    # 3. OBJECTIVE FUNCTION
    # Maximize the total quality score of accepted submissions
    model.setObjective(gp.quicksum(scores[j] * x[i, j] for i in range(n_workshops) for j in range(n_submissions)), GRB.MAXIMIZE)
    
    # 4. CONSTRAINTS - CORRECT SYNTAX PATTERNS
    
    # Workshop Capacity Constraints
    for i in range(n_workshops):
        model.addConstr(gp.quicksum(x[i, j] for j in range(n_submissions)) <= capacities[i+1], name=f"capacity_{i+1}")
    
    # Minimum Submissions Constraints
    for i in range(n_workshops):
        model.addConstr(gp.quicksum(x[i, j] for j in range(n_submissions)) >= min_submissions[i+1], name=f"min_submissions_{i+1}")
    
    # 5. SOLVING & RESULTS
    model.optimize()
    
    if model.status == GRB.OPTIMAL:
        print(f"Optimal value: {model.objVal}")
        for i in range(n_workshops):
            for j in range(n_submissions):
                if x[i, j].x > 1e-6:
                    print(f"x[{i},{j}] = {x[i, j].x:.3f}")
    elif model.status == GRB.INFEASIBLE:
        print("Problem is infeasible")
    elif model.status == GRB.UNBOUNDED:
        print("Problem is unbounded")
    
    return model

# Run the optimization
optimize_workshop_paper()
```

### Execution Results
**Status**: INFEASIBLE
**Error**: Problem is infeasible
**Analysis**: Gurobipy consistently reported the problem as infeasible across multiple retry attempts, indicating a potential issue with the problem formulation or data constraints.

## 6. DOCplex Implementation

```python
# Complete DOCPLEX implementation - Retry Attempt 4

from docplex.mp.model import Model

def optimize_workshop_submissions():
    # 1. MODEL & DATA SETUP
    mdl = Model(name="workshop_paper")
    
    # Data from the database
    scores = [8.5, 6.0, 9.2, 7.3, 5.5]  # Submission scores
    capacities = [50, 100, 150]  # Venue capacities for each workshop
    min_submissions = [3, 5, 7]  # Minimum submissions required for each workshop
    
    # Validate array lengths to prevent IndexError
    n_submissions = len(scores)
    n_workshops = len(capacities)
    assert len(min_submissions) == n_workshops, "Array length mismatch"
    
    # Safe indexing
    safe_range_submissions = range(n_submissions)
    safe_range_workshops = range(n_workshops)
    
    # 2. VARIABLES
    # Binary decision variables for acceptance of submissions
    x = {(i, j): mdl.binary_var(name=f"x_{i}_{j}") for i in safe_range_workshops for j in safe_range_submissions}
    
    # 3. OBJECTIVE FUNCTION
    # Maximize the total quality score of accepted submissions
    objective = mdl.sum(scores[j] * x[i, j] for i in safe_range_workshops for j in safe_range_submissions)
    mdl.maximize(objective)
    
    # 4. CONSTRAINTS
    # Workshop Capacity Constraints
    for i in safe_range_workshops:
        mdl.add_constraint(mdl.sum(x[i, j] for j in safe_range_submissions) <= capacities[i], ctname=f"capacity_{i}")
    
    # Minimum Submissions Constraints
    for i in safe_range_workshops:
        mdl.add_constraint(mdl.sum(x[i, j] for j in safe_range_submissions) >= min_submissions[i], ctname=f"min_submissions_{i}")
    
    # 5. SOLVING & RESULTS
    solution = mdl.solve()
    
    if solution:
        print(f"Optimal value: {solution.objective_value}")
        for i in safe_range_workshops:
            for j in safe_range_submissions:
                if solution.get_value(x[i, j]) > 0.5:  # Check if submission is accepted
                    print(f"Submission {j} accepted for Workshop {i}")
    else:
        print("No solution found")
        print(f"Status: {mdl.solve_details.status}")

    return mdl

# Execute the optimization
optimize_workshop_submissions()
```

### Execution Results
**Status**: INFEASIBLE
**Error**: Problem is infeasible
**Analysis**: DOCplex also reported the problem as infeasible, aligning with the results from other solvers, suggesting a systemic issue rather than a solver-specific problem.

## 7. Pyomo Implementation

```python
# Complete PYOMO implementation - Retry Attempt 4

import pyomo.environ as pyo
from pyomo.opt import SolverFactory

def conference_optimization():
    """Pyomo model for optimizing conference workshop submissions"""
    
    # 1. MODEL CREATION
    model = pyo.ConcreteModel()
    
    # 2. DATA SETUP
    # Assuming 5 submissions and 3 workshops based on the provided data
    n_submissions = 5
    n_workshops = 3
    
    # Scores for each submission
    scores = [8.5, 6.0, 9.2, 7.3, 5.5]
    
    # Workshop capacities
    capacities = {1: 50, 2: 100, 3: 150}
    
    # Minimum submissions required for each workshop
    min_submissions = {1: 3, 2: 5, 3: 7}
    
    # CRITICAL: Validate array lengths before indexing
    assert len(scores) == n_submissions, "Array length mismatch for scores"
    
    # 3. SETS
    model.Submissions = pyo.RangeSet(1, n_submissions)
    model.Workshops = pyo.RangeSet(1, n_workshops)
    
    # 4. PARAMETERS
    model.Scores = pyo.Param(model.Submissions, initialize={i+1: scores[i] for i in range(n_submissions)})
    model.Capacity = pyo.Param(model.Workshops, initialize=capacities)
    model.MinSubmissions = pyo.Param(model.Workshops, initialize=min_submissions)
    
    # 5. VARIABLES
    model.x = pyo.Var(model.Workshops, model.Submissions, within=pyo.Binary)
    
    # 6. OBJECTIVE FUNCTION
    def obj_rule(model):
        return sum(model.Scores[j] * model.x[i, j] for i in model.Workshops for j in model.Submissions)
    model.objective = pyo.Objective(rule=obj_rule, sense=pyo.maximize)
    
    # 7. CONSTRAINTS
    
    # Workshop Capacity Constraints
    def capacity_rule(model, i):
        return sum(model.x[i, j] for j in model.Submissions) <= model.Capacity[i]
    model.capacity_constraint = pyo.Constraint(model.Workshops, rule=capacity_rule)
    
    # Minimum Submissions Constraints
    def min_submissions_rule(model, i):
        return sum(model.x[i, j] for j in model.Submissions) >= model.MinSubmissions[i]
    model.min_submissions_constraint = pyo.Constraint(model.Workshops, rule=min_submissions_rule)
    
    # 8. SOLVING WITH GUROBI
    solver = SolverFactory('gurobi')
    
    # Optional: Set solver options
    solver.options['TimeLimit'] = 300  # 5 minutes
    solver.options['MIPGap'] = 0.01    # 1% gap
    
    # Solve the model
    results = solver.solve(model, tee=True)
    
    # 9. RESULT PROCESSING
    # Check solver status
    if results.solver.termination_condition == pyo.TerminationCondition.optimal:
        print("Optimal solution found!")
        print(f"Optimal value: {pyo.value(model.objective)}")
        
        # Extract variable values
        print("\nAccepted Submissions:")
        for i in model.Workshops:
            for j in model.Submissions:
                if pyo.value(model.x[i, j]) > 0.5:  # Binary variable, check if it's 1
                    print(f"Workshop {i}, Submission {j} accepted")
        
    elif results.solver.termination_condition == pyo.TerminationCondition.infeasible:
        print("Problem is infeasible")
    elif results.solver.termination_condition == pyo.TerminationCondition.unbounded:
        print("Problem is unbounded")
    else:
        print(f"Solver terminated with condition: {results.solver.termination_condition}")
    
    return model

# Execute the optimization
conference_optimization()
```

### Execution Results
**Status**: INFEASIBLE
**Error**: Problem is infeasible
**Analysis**: Pyomo's infeasibility result is consistent with the other solvers, reinforcing the likelihood of an issue with the constraints or data inputs.

## 8. Cross-Solver Analysis and Final Recommendation

### Solver Results Comparison

| Solver | Status | Optimal Value | Execution Time | Decision Variables | Retry Attempt |
|--------|--------|---------------|----------------|-------------------|---------------|
| Gurobipy | INFEASIBLE | N/A | 0.21s | N/A | 4 |
| Docplex | INFEASIBLE | N/A | 1.23s | N/A | 4 |
| Pyomo | INFEASIBLE | N/A | 1.43s | N/A | 4 |

### Solver Consistency Analysis
**Result**: All solvers produced consistent results ✓
**Consistent Solvers**: gurobipy, docplex, pyomo
**Solver Retry Summary**: gurobipy: 4 attempts, docplex: 4 attempts, pyomo: 4 attempts

### Final Recommendation
**Confidence Level**: LOW
**Preferred Solver(s)**: multiple
**Reasoning**: All solvers consistently reported infeasibility, suggesting the issue lies with the problem setup rather than the solvers themselves.

### Business Interpretation
**Overall Strategy**: The current problem formulation cannot be solved as it stands due to infeasibility, indicating that the constraints or data inputs need to be revisited.
**Objective Value Meaning**: The objective value cannot be interpreted as the problem is infeasible. The goal was to maximize the total quality score of accepted submissions.
**Resource Allocation Summary**: No resources can be allocated as the problem constraints are not satisfiable with the current data.
**Implementation Recommendations**: Review and verify the input data for capacity and minimum submissions. Check for logical consistency in constraints and ensure that they do not conflict.