def _calculate_bound_(self,all_items,constraints,generic_constraint): weight = self.weights[generic_constraint] value = self.value remaining_items_sorted = sort_items_by_efficiency(all_items,self.included_item_ids,self.excluded_item_ids,constraints,generic_constraint) for item in remaining_items_sorted: if item[generic_constraint] + weight <= constraints[generic_constraint]: value = value + item['value'] weight = weight + item[generic_constraint] else: leftover_weight = constraints[generic_constraint] - weight bound = value + ((leftover_weight/item[generic_constraint]) * item['value']) break return bound
def get_best_lineup(self, table, game_date): # Use any table as long as the required columns are present self.mysql.execute(""" select player_name,DFS_target,DFS_pred,salary,position, if(position='PG',1,0) as PG, if(position='SG',1,0) as SG, if(position='SF',1,0) as SF, if(position='PF',1,0) as PF, if(position='C',1,0) as C from {table} where game_date = '{game_date}' """.format(table=table, game_date=game_date)) items = {} for row_index, row in enumerate(self.mysql.fetchall()): items[row_index] = { 'full_name': row['player_name'], 'value': row['DFS_pred'], 'DFS_target': row['DFS_target'], 'salary': row['salary'], 'position': row['position'], 'PG': row['PG'], 'SG': row['SG'], 'SF': row['SF'], 'PF': row['PF'], 'C': row['C'] } def n(index): node = nodes[index] print( 'id:{id} max:{value}, w:{weight} b:{bound} parent:{parent} children:{children}' .format(id=node.id, value=max_value, weight=node.weights, bound=node.bound, children=node.child_ids, parent=node.parent_id)) for item_id, item in items.items(): items[item_id]['value-ratio'] = item['value'] / item['salary'] constraints = { 'salary': 60000, 'PG': 2, 'SG': 2, 'SF': 2, 'PF': 2, 'C': 1 } nodes = {} origin = Node(own_id=0, parent_id=None, all_items=items, included_item_ids=[], excluded_item_ids=[], constraints=constraints, generic_constraint="salary") nodes[0] = origin max_value = 0 node = origin node_count = 0 move_counter = 0 while origin.bound is not max_value: move_counter = move_counter + 1 if move_counter % 1000 == 0: print('{max_value}, {move_counter}'.format( max_value=max_value, move_counter=move_counter)) if move_counter % self.max_iterations == 0: print('Optimization taking too long') break if len(node.child_ids) > 0: # Explore existing nodes # Check if all constraints are met if (nodes[node.child_ids[0]].bound <= max_value or any( nodes[node.child_ids[0]].weights[constraint_name] > constraint_value for constraint_name, constraint_value in constraints.items())) and ( nodes[node.child_ids[1]].bound <= max_value or any(nodes[node.child_ids[1]]. weights[constraint_name] > constraint_value for constraint_name, constraint_value in constraints.items())): possible_bounds = [] if all(nodes[node.child_ids[1]].weights[constraint_name] <= constraint_value for constraint_name, constraint_value in constraints.items()): possible_bounds.append(nodes[node.child_ids[1]].bound) if all(nodes[node.child_ids[0]].weights[constraint_name] <= constraint_value for constraint_name, constraint_value in constraints.items()): possible_bounds.append(nodes[node.child_ids[0]].bound) nodes[node.id].bound = max(possible_bounds) if node.id > 0: node = nodes[node.parent_id] else: # Searched has finished and you have arrived at origin, which has no parent continue elif nodes[node.child_ids[0]].bound > max_value and all( nodes[node.child_ids[0]].weights[constraint_name] <= constraint_value for constraint_name, constraint_value in constraints.items()): node = nodes[node.child_ids[0]] elif nodes[node.child_ids[1]].bound > max_value and all( nodes[node.child_ids[1]].weights[constraint_name] <= constraint_value for constraint_name, constraint_value in constraints.items()): node = nodes[node.child_ids[1]] else: # Create new nodes because this split hasn't been explored yet included_item_ids = node.included_item_ids excluded_item_ids = node.excluded_item_ids remaining_items_sorted = sort_items_by_efficiency( items, included_item_ids, excluded_item_ids, constraints, 'salary') most_efficient_item = remaining_items_sorted[0] candidate_included_items = included_item_ids[:] candidate_included_items.append(most_efficient_item['item_id']) node_count = node_count + 1 included_item_node = Node( own_id=node_count, parent_id=node.id, all_items=items, included_item_ids=candidate_included_items, excluded_item_ids=excluded_item_ids, constraints=constraints, generic_constraint='salary') nodes[included_item_node.id] = included_item_node candidate_excluded_items = excluded_item_ids[:] candidate_excluded_items.append(most_efficient_item['item_id']) node_count = node_count + 1 excluded_item_node = Node( own_id=node_count, parent_id=node.id, all_items=items, included_item_ids=included_item_ids, excluded_item_ids=candidate_excluded_items, constraints=constraints, generic_constraint='salary') nodes[excluded_item_node.id] = excluded_item_node nodes[node.id].set_child_ids( [included_item_node.id, excluded_item_node.id]) better_node = None if all(included_item_node.weights[constraint_name] <= constraint_value for constraint_name, constraint_value in constraints.items()) and all( excluded_item_node.weights[constraint_name] <= constraint_value for constraint_name, constraint_value in constraints.items()): if included_item_node.bound > excluded_item_node.bound: if included_item_node.bound > max_value: better_node = included_item_node worse_node = excluded_item_node max_value = max(better_node.value, max_value) #print("Include: "+str(most_efficient_item['item_id'])+": profit "+str(included_item_node.value)+" weight "+str(included_item_node.weights['weight'])+" Exclude: profit "+str(excluded_item_node.value)+" weight "+str(excluded_item_node.weights['weight'])) else: node = nodes[node.parent_id] continue else: better_node = excluded_item_node worse_node = included_item_node max_value = max(better_node.value, max_value) #print("Exclude: "+str(most_efficient_item['item_id'])+" profit "+str(excluded_item_node.value)+" weight "+str(excluded_item_node.weights['weight'])+" bound: "+str(excluded_item_node.bound)+" Include: profit "+str(included_item_node.value)+" weight "+str(included_item_node.weights['weight'])+" bound: "+str(included_item_node.bound)) elif any(included_item_node.weights[constraint_name] > constraint_value for constraint_name, constraint_value in constraints.items()): nodes[node.id].bound = node.value # nodes[ included_item_node.id].bound = included_item_node.value node = nodes[node.parent_id] continue if better_node is not None: node = better_node print('Best node:') best_node = None for node_id, node in nodes.items(): if node.value == max_value and len(node.child_ids) > 0: #n(node_id) best_node = node best_node.actual_value = calculate_target_value( items, node.included_item_ids) print( 'actual value: ' + str(calculate_target_value(items, node.included_item_ids)), ' max: ' + str(max_value)) print('finished') return best_node
possible_bounds.append(nodes[node.child_ids[1]].bound) if all(nodes[node.child_ids[0]].weights[constraint_name] <= constraint_value for constraint_name,constraint_value in constraints.items()): possible_bounds.append(nodes[node.child_ids[0]].bound) nodes[node.id].bound = max(possible_bounds) if node.id > 0: node = nodes[node.parent_id] else: # Searched has finished and you have arrived at origin, which has no parent continue elif nodes[node.child_ids[0]].bound > max_value and all(nodes[node.child_ids[0]].weights[constraint_name] <= constraint_value for constraint_name,constraint_value in constraints.items()): node = nodes[node.child_ids[0]] elif nodes[node.child_ids[1]].bound > max_value and all(nodes[node.child_ids[1]].weights[constraint_name] <= constraint_value for constraint_name,constraint_value in constraints.items()): node = nodes[node.child_ids[1]] else: # Create new nodes because this split hasn't been explored yet included_item_ids = node.included_item_ids excluded_item_ids = node.excluded_item_ids remaining_items_sorted = sort_items_by_efficiency(items,included_item_ids,excluded_item_ids,constraints,'salary') most_efficient_item = remaining_items_sorted[0] candidate_included_items = included_item_ids[:] candidate_included_items.append(most_efficient_item['item_id']) node_count = node_count + 1 included_item_node = Node(own_id=node_count,parent_id=node.id,all_items=items, included_item_ids=candidate_included_items, excluded_item_ids=excluded_item_ids, constraints=constraints,generic_constraint='salary') nodes[included_item_node.id]=included_item_node candidate_excluded_items = excluded_item_ids[:] candidate_excluded_items.append(most_efficient_item['item_id']) node_count = node_count + 1 excluded_item_node = Node(own_id=node_count,parent_id=node.id,all_items=items, included_item_ids=included_item_ids, excluded_item_ids=candidate_excluded_items,
def get_best_lineup(self,table,game_date): # Use any table as long as the required columns are present self.mysql.execute(""" select player_name,DFS_target,DFS_pred,salary,position, if(position='PG',1,0) as PG, if(position='SG',1,0) as SG, if(position='SF',1,0) as SF, if(position='PF',1,0) as PF, if(position='C',1,0) as C from {table} where game_date = '{game_date}' """.format(table=table,game_date=game_date)) items = {} for row_index,row in enumerate(self.mysql.fetchall()): items[row_index]={'full_name':row['player_name'],'value':row['DFS_pred'],'DFS_target':row['DFS_target'], 'salary':row['salary'],'position':row['position'],'PG':row['PG'], 'SG':row['SG'],'SF':row['SF'],'PF':row['PF'],'C':row['C']} def n(index): node = nodes[index] print('id:{id} max:{value}, w:{weight} b:{bound} parent:{parent} children:{children}'.format(id=node.id,value=max_value,weight=node.weights,bound=node.bound,children=node.child_ids,parent=node.parent_id)) for item_id,item in items.items(): items[item_id]['value-ratio'] = item['value']/item['salary'] constraints = {'salary':60000,'PG':2,'SG':2,'SF':2,'PF':2,'C':1} nodes = {} origin = Node(own_id=0,parent_id=None,all_items=items,included_item_ids=[], excluded_item_ids=[],constraints=constraints,generic_constraint="salary") nodes[0]=origin max_value = 0 node = origin node_count = 0 move_counter = 0 while origin.bound is not max_value: move_counter = move_counter + 1 if move_counter % 1000 == 0: print('{max_value}, {move_counter}'.format(max_value=max_value,move_counter=move_counter)) if move_counter % self.max_iterations == 0: print('Optimization taking too long') break if len(node.child_ids) > 0: # Explore existing nodes # Check if all constraints are met if (nodes[node.child_ids[0]].bound <= max_value or any(nodes[node.child_ids[0]].weights[constraint_name] > constraint_value for constraint_name,constraint_value in constraints.items())) and (nodes[node.child_ids[1]].bound <= max_value or any(nodes[node.child_ids[1]].weights[constraint_name] > constraint_value for constraint_name,constraint_value in constraints.items())): possible_bounds = [] if all(nodes[node.child_ids[1]].weights[constraint_name] <= constraint_value for constraint_name,constraint_value in constraints.items()): possible_bounds.append(nodes[node.child_ids[1]].bound) if all(nodes[node.child_ids[0]].weights[constraint_name] <= constraint_value for constraint_name,constraint_value in constraints.items()): possible_bounds.append(nodes[node.child_ids[0]].bound) nodes[node.id].bound = max(possible_bounds) if node.id > 0: node = nodes[node.parent_id] else: # Searched has finished and you have arrived at origin, which has no parent continue elif nodes[node.child_ids[0]].bound > max_value and all(nodes[node.child_ids[0]].weights[constraint_name] <= constraint_value for constraint_name,constraint_value in constraints.items()): node = nodes[node.child_ids[0]] elif nodes[node.child_ids[1]].bound > max_value and all(nodes[node.child_ids[1]].weights[constraint_name] <= constraint_value for constraint_name,constraint_value in constraints.items()): node = nodes[node.child_ids[1]] else: # Create new nodes because this split hasn't been explored yet included_item_ids = node.included_item_ids excluded_item_ids = node.excluded_item_ids remaining_items_sorted = sort_items_by_efficiency(items,included_item_ids,excluded_item_ids,constraints,'salary') most_efficient_item = remaining_items_sorted[0] candidate_included_items = included_item_ids[:] candidate_included_items.append(most_efficient_item['item_id']) node_count = node_count + 1 included_item_node = Node(own_id=node_count,parent_id=node.id,all_items=items, included_item_ids=candidate_included_items, excluded_item_ids=excluded_item_ids, constraints=constraints,generic_constraint='salary') nodes[included_item_node.id]=included_item_node candidate_excluded_items = excluded_item_ids[:] candidate_excluded_items.append(most_efficient_item['item_id']) node_count = node_count + 1 excluded_item_node = Node(own_id=node_count,parent_id=node.id,all_items=items, included_item_ids=included_item_ids, excluded_item_ids=candidate_excluded_items, constraints=constraints,generic_constraint='salary') nodes[excluded_item_node.id]=excluded_item_node nodes[node.id].set_child_ids([included_item_node.id,excluded_item_node.id]) better_node = None if all(included_item_node.weights[constraint_name] <= constraint_value for constraint_name,constraint_value in constraints.items()) and all(excluded_item_node.weights[constraint_name] <= constraint_value for constraint_name,constraint_value in constraints.items()): if included_item_node.bound > excluded_item_node.bound: if included_item_node.bound > max_value: better_node = included_item_node worse_node = excluded_item_node max_value = max(better_node.value,max_value) #print("Include: "+str(most_efficient_item['item_id'])+": profit "+str(included_item_node.value)+" weight "+str(included_item_node.weights['weight'])+" Exclude: profit "+str(excluded_item_node.value)+" weight "+str(excluded_item_node.weights['weight'])) else: node = nodes[node.parent_id] continue else: better_node = excluded_item_node worse_node = included_item_node max_value = max(better_node.value,max_value) #print("Exclude: "+str(most_efficient_item['item_id'])+" profit "+str(excluded_item_node.value)+" weight "+str(excluded_item_node.weights['weight'])+" bound: "+str(excluded_item_node.bound)+" Include: profit "+str(included_item_node.value)+" weight "+str(included_item_node.weights['weight'])+" bound: "+str(included_item_node.bound)) elif any(included_item_node.weights[constraint_name] > constraint_value for constraint_name,constraint_value in constraints.items()): nodes[node.id].bound = node.value # nodes[included_item_node.id].bound = included_item_node.value node = nodes[node.parent_id] continue if better_node is not None: node = better_node print('Best node:') best_node = None for node_id, node in nodes.items(): if node.value == max_value and len(node.child_ids) > 0: #n(node_id) best_node = node best_node.actual_value = calculate_target_value(items,node.included_item_ids) print('actual value: '+str(calculate_target_value(items,node.included_item_ids)),' max: '+str(max_value)) print('finished') return best_node
else: # Searched has finished and you have arrived at origin, which has no parent continue elif nodes[node.child_ids[0]].bound > max_value and all( nodes[node.child_ids[0]].weights[constraint_name] <= constraint_value for constraint_name, constraint_value in constraints.items()): node = nodes[node.child_ids[0]] elif nodes[node.child_ids[1]].bound > max_value and all( nodes[node.child_ids[1]].weights[constraint_name] <= constraint_value for constraint_name, constraint_value in constraints.items()): node = nodes[node.child_ids[1]] else: # Create new nodes because this split hasn't been explored yet included_item_ids = node.included_item_ids excluded_item_ids = node.excluded_item_ids remaining_items_sorted = sort_items_by_efficiency( items, included_item_ids, excluded_item_ids, constraints, 'salary') most_efficient_item = remaining_items_sorted[0] candidate_included_items = included_item_ids[:] candidate_included_items.append(most_efficient_item['item_id']) node_count = node_count + 1 included_item_node = Node(own_id=node_count, parent_id=node.id, all_items=items, included_item_ids=candidate_included_items, excluded_item_ids=excluded_item_ids, constraints=constraints, generic_constraint='salary') nodes[included_item_node.id] = included_item_node candidate_excluded_items = excluded_item_ids[:] candidate_excluded_items.append(most_efficient_item['item_id']) node_count = node_count + 1