PuLP: Using only one item per group
<p>I have a Pandas dataframe that has following values:</p>

<pre><code>     Name    Age    City    Points
1    John    24     CHI     35
2    Mary    18     NY      25
.
.
80   Steve   30     CHI     32
</code></pre>

<p>I'm trying to form a 5 person group that maximizes the sum of points. I'd like to have two constraints: age and city. Maximum age must be under 110 years and there can't be two persons from the same city.</p>

<p>At the moment I have a script that maximizes the points and takes the age constraint into account:</p>

<pre><code>x = pulp.LpVariable.dicts("x", df.index, cat='Integer', lowBound=0)
mod = pulp.LpProblem("prog", pulp.LpMaximize)

objvals_p = {idx: (df['Points'][idx]) for idx in df.index}
mod += sum([x[idx]*objvals_p[idx] for idx in df.index])

objvals_a = {idx: (df['Age'][idx]) for idx in df.index}
mod += pulp.lpSum([x[idx]*objvals_a[idx] for idx in df.index]) &lt; 110
</code></pre>

<p>However I can't figure out how to add city constraint into my script.</p>

<p>Any advices for me?</p>

<p>Thanks!</p>

<p>You can do something like this:</p>

<pre><code>for city in df['City'].unique():
    sub_idx = df[df['City']==city].index
    mod += pulp.lpSum([x[idx] for idx in sub_idx]) &lt;= 1
</code></pre>

<p>For each city in the DataFrame, this sum is over a subset of DataFrame (indexed by sub_idx) and this sum should be smaller than or equal to 1 because 2 people from the same city cannot be in the team.</p>

<p>For this (and your other constraint) to work, you need to change the definition of your decision variable. It should be binary; integrality is not enough.</p>

<pre><code>x = pulp.LpVariable.dicts("x", df.index, 0, 1, pulp.LpInteger)
</code></pre>

python pandas constraints solver pulp