Weekly Challenge

Solve the challenge, share your solution and summit the ranks of our Community!
IDEAS WANTED

We're actively looking for ideas on how to improve Weekly Challenges and would love to hear what you think!

Submit Feedback
We've recently made an accessibility improvement to the community and therefore posts without any content are no longer allowed. Please use the spoiler feature or add a short message in the message body in order to submit your weekly challenge.

Challenge #213: Optimized Flower Arrangements

Highlighted
7 - Meteor

So much work/ trial and error, for three tools. That took a while to figure out.

Highlighted
11 - Bolide

This was a great challenge - a simple problem to practice an infrequently-used tool. I have to spend quality time with Tool Mastery and help for some of these!

 

I solved this one with the Optimization tool (variables in rows) and with Python (PuLP). The output from the Python method is valid but slightly different (57 white daisies / 40 red roses, while the Optimization tool produced 40 white daisies / 57 red roses; still the same total of 417). I didn't want to mess with installing GLPK right now, so I used the PuLP default CBC solver.

Python version:

Spoiler
kelly_gilbert_0-1593354784324.png


Code:

Spoiler
#################################
from ayx import Alteryx
Alteryx.installPackages(['pulp'])

from pandas import concat, DataFrame, Series
from pulp import GLPK, LpMaximize, LpProblem, LpStatus, lpSum, LpVariable


#################################

# read in the flower costs from the workflow and update the name
df = Alteryx.read('#1')
df.index = df['Flower'].str.replace(' ', '_').str.lower()
df.index.name = 'index'


#################################

# create a dictionary of cost for each flower name
costs = Series(data=df['Price']).to_dict()
costs


#################################

# define the model
model = LpProblem(name="flower-arrangements", sense=LpMaximize)


#################################

# define the decision variables
# this creates a dictionary of LpVariables with the same keys as costs
counts = {}
for k in costs.keys():
    if k == 'filler_greens': 
        lb = 30
        ub = 40
    else:
        lb = 40
        ub = 80

    counts[k] = LpVariable(name=k, lowBound=lb, upBound=ub, cat='Integer')


#################################

# add constraints
model += lpSum(costs[i] * counts[i] for i in costs.keys()) <= 950, \
               'Total cost constraint'


#################################

# Set the objective (maximize the total number of flowers)
model += lpSum(counts[i] for i in counts.keys()), \
               'Total number of flowers'


#################################

# Solve the optimization problem
status = model.solve()

# Get the results
print('--- status ---')
print(f"status: {model.status}, {LpStatus[model.status]}")
print('\n--- objective value ---')
print(f"objective: {model.objective.value()}")

print('\n--- variable values ---')
for v in counts.values():
    print(f"{v.name}: {v.value()}")

print('\n--- constraints ---')
for name, constraint in model.constraints.items():
    print(f"{name}: {constraint.value()}")

model.solver


#################################

# add the variables to a dataframe for output
df_vars = DataFrame({ 'value': [v.value() for v in counts.values()] }, 
                     index = [v.name for v in counts.values()])
df_vars.index.name = 'index'


#################################

# format the dataframe for output to the workflow
# with the original flower name
df_out = df[['Flower']].merge(df_vars, on='index')
df_out.columns = ['name', 'value']


#################################

# add a row for the objective value
df_out = concat([df_out, DataFrame({ 'name' : 'Objective Value', 
                                    'value' : model.objective.value() },
                                    index=[0])] )


#################################
Alteryx.write(df_out, 1)

Alteryx version (variables in rows):

Spoiler
kelly_gilbert_0-1593385464474.png
Highlighted
12 - Quasar
12 - Quasar
Spoiler
The optimization tool always gets me. Little options here and there that throw me off. Once I looked at old challenges using this tool it all clicked again.
cplewis90_0-1593876372600.png