James McCool commited on
Commit
998e096
·
1 Parent(s): d8888d9

addressing a reoptimization issue

Browse files
Files changed (2) hide show
  1. app.py +1 -0
  2. global_func/optimize_lineup.py +33 -7
app.py CHANGED
@@ -7,6 +7,7 @@ from collections import Counter
7
  import io
8
 
9
  ## import global functions
 
10
  from global_func.clean_player_name import clean_player_name
11
  from global_func.load_file import load_file
12
  from global_func.load_ss_file import load_ss_file
 
7
  import io
8
 
9
  ## import global functions
10
+ ## Need to make sure that I take all functions from here and give them a home
11
  from global_func.clean_player_name import clean_player_name
12
  from global_func.load_file import load_file
13
  from global_func.load_ss_file import load_ss_file
global_func/optimize_lineup.py CHANGED
@@ -13,6 +13,22 @@ def get_effective_salary(player_name: str, column_name: str, map_dict: dict, typ
13
  return base_salary
14
 
15
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
16
  def optimize_single_lineup(
17
  row: pd.Series,
18
  player_columns: list,
@@ -46,6 +62,9 @@ def optimize_single_lineup(
46
  Returns:
47
  Tuple of (optimized_row, achieved_objective_value)
48
  """
 
 
 
49
  # Create a copy of the row to modify
50
  optimized_row = row.copy()
51
 
@@ -74,9 +93,9 @@ def optimize_single_lineup(
74
  # This position is open for optimization
75
  open_columns.append(col)
76
 
77
- # If no open columns, return with locked objective value
78
  if not open_columns:
79
- return optimized_row, locked_objective_value
80
 
81
  # Calculate remaining salary budget
82
  remaining_salary = salary_max - locked_salary
@@ -85,9 +104,9 @@ def optimize_single_lineup(
85
  remaining_objective_budget = None
86
  if max_objective_value is not None:
87
  remaining_objective_budget = max_objective_value - locked_objective_value
88
- # If we can't meet the constraint, return original row
89
  if remaining_objective_budget < 0:
90
- return optimized_row, locked_objective_value
91
 
92
  # Filter player pool: exclude locked teams and already-locked players
93
  available_players = player_pool[
@@ -99,13 +118,14 @@ def optimize_single_lineup(
99
  available_players = available_players.drop_duplicates(subset=['player_names'], keep='first')
100
 
101
  if available_players.empty:
102
- return optimized_row, locked_objective_value
 
103
 
104
  # Build the optimization model
105
  solver = pywraplp.Solver.CreateSolver('CBC')
106
  if not solver:
107
- # Fallback if solver not available
108
- return optimized_row, locked_objective_value
109
 
110
  # Create decision variables: x[player_idx, col_idx] = 1 if player is assigned to column
111
  player_list = available_players.to_dict('records')
@@ -179,6 +199,12 @@ def optimize_single_lineup(
179
  achieved_objective += player.get(optimize_by, player.get('median', 0))
180
  break
181
 
 
 
 
 
 
 
182
  return optimized_row, achieved_objective
183
 
184
 
 
13
  return base_salary
14
 
15
 
16
+ def calculate_lineup_objective(
17
+ row: pd.Series,
18
+ player_columns: list,
19
+ player_pool: pd.DataFrame,
20
+ optimize_by: str = 'median'
21
+ ) -> float:
22
+ """Calculate the total objective value of a lineup."""
23
+ total = 0.0
24
+ for col in player_columns:
25
+ player_name = row[col]
26
+ player_data = player_pool[player_pool['player_names'] == player_name]
27
+ if not player_data.empty:
28
+ total += player_data.iloc[0].get(optimize_by, player_data.iloc[0].get('median', 0))
29
+ return total
30
+
31
+
32
  def optimize_single_lineup(
33
  row: pd.Series,
34
  player_columns: list,
 
62
  Returns:
63
  Tuple of (optimized_row, achieved_objective_value)
64
  """
65
+ # Calculate the original lineup's objective value BEFORE any changes
66
+ original_objective = calculate_lineup_objective(row, player_columns, player_pool, optimize_by)
67
+
68
  # Create a copy of the row to modify
69
  optimized_row = row.copy()
70
 
 
93
  # This position is open for optimization
94
  open_columns.append(col)
95
 
96
+ # If no open columns, return with original objective value (keep original intact)
97
  if not open_columns:
98
+ return row.copy(), original_objective
99
 
100
  # Calculate remaining salary budget
101
  remaining_salary = salary_max - locked_salary
 
104
  remaining_objective_budget = None
105
  if max_objective_value is not None:
106
  remaining_objective_budget = max_objective_value - locked_objective_value
107
+ # If we can't meet the constraint, return original row unchanged
108
  if remaining_objective_budget < 0:
109
+ return row.copy(), original_objective
110
 
111
  # Filter player pool: exclude locked teams and already-locked players
112
  available_players = player_pool[
 
118
  available_players = available_players.drop_duplicates(subset=['player_names'], keep='first')
119
 
120
  if available_players.empty:
121
+ # No available players - keep original lineup
122
+ return row.copy(), original_objective
123
 
124
  # Build the optimization model
125
  solver = pywraplp.Solver.CreateSolver('CBC')
126
  if not solver:
127
+ # Fallback if solver not available - keep original lineup
128
+ return row.copy(), original_objective
129
 
130
  # Create decision variables: x[player_idx, col_idx] = 1 if player is assigned to column
131
  player_list = available_players.to_dict('records')
 
199
  achieved_objective += player.get(optimize_by, player.get('median', 0))
200
  break
201
 
202
+ # CRITICAL: Only return optimized lineup if it's actually better than original
203
+ # If optimization resulted in a worse lineup, keep the original
204
+ if achieved_objective < original_objective:
205
+ # Optimization made things worse - keep the original lineup
206
+ return row.copy(), original_objective
207
+
208
  return optimized_row, achieved_objective
209
 
210