That is the (and sure final) a part of a Linear Programming collection I’ve been writing. With the core ideas coated by the prior articles, this text focuses on purpose programming which is a much less frequent linear programming (LP) use case. Aim programming is a particular linear programming setup that may deal with the optimization of a number of targets in a single LP downside.
By the top of this text, you’ll perceive:
1. Definition of purpose programming and when it ought to be used
2. The weighted purpose programming method — illustrated with an instance
3. The preemptive purpose programming method — illustrated with an instance
Definition and Use Case of Aim Programming
Aim programming is a particular case of linear programming that enables for a number of — usually conflicting — targets to be balanced. With common LP issues, you decide a single metric to optimize (decrease or maximize) and set constraints to make sure that the optimum resolution is possible. Aim programming is a way that enables for a number of goal metrics to be focused on the identical time.
The ‘mindset’ of purpose programming is essentially completely different from plain vanilla LP issues. Primary LP searches for tactics to get as little or as a lot of a single metric as potential — e.g., maximize revenue or decrease waste — topic to constraints. Typically conflicting priorities will probably be discovered within the goal operate or the constraints. For instance, maximize revenue (goal) topic to a most quantity of waste (constraint). With purpose programming, we will transfer necessary constraint metrics into the target operate so we will optimize on them somewhat than simply constraining them. We are able to maximize revenue and decrease waste on the identical time!
Now is an efficient time to ascertain the instance we’ll probe for the remainder of the article:
Let’s think about that we handle a manufacturing unit that makes clothes. Our manufacturing unit could make pants, shirts, and attire. Every article of clothes has prices, revenue, and waste related to their manufacturing. We need to create a manufacturing plan that can make a sure degree of revenue and likewise waste under a sure amount on account of an environmental dedication. Let’s say that we need to make $150k a month in revenue and we additionally need to waste lower than 20k yards of cloth. Along with our objectives, we will’t spend greater than $50k in supplies and labor.
The instance above sounds quite a bit like a daily linear programming downside proper? Properly, the twist is that we will’t make $150k in revenue and waste lower than 20k of yards on the identical time. In different phrases, there could be no possible resolution if we had been to plug this into a daily linear programming downside. Usually, the objectives set within the issues can’t all be achieved with a single resolution, in any other case there wouldn’t be some extent in utilizing purpose programming. We might simply use common outdated linear programming with our objectives as constraints. The true worth of purpose programming is that it will possibly create a compromise between conflicting objectives when common linear programming would yield an infeasible resolution.
The true worth of purpose programming is that it will possibly create a compromise between conflicting objectives when common linear programming would yield an infeasible resolution.
How does purpose programming steadiness and compromise with conflicting objectives? There are two fashionable approaches: (1) weighted and (2) preemptive. We’ll cowl these intimately within the following sections.
The weights method
Right here, we’ll dive into the main points of the weights method. The weights technique has a single goal operate and runs a single Optimization based mostly on (you guessed it) weights! The truth that just one optimization is run underneath the weights technique could appear to be a given — however the preemptive technique truly runs a number of linear programming optimizations. We’ll get to that within the subsequent part…
The weights technique has particular targets or objectives for a number of metrics — e.g., make no less than $150k in revenue promoting garments or waste not more than 20k yards of cloth. For normal LP, we need to absolutely optimize. For the weights technique of purpose programming, we need to get as near hitting objectives as potential — after we attain a purpose, the optimization doesn’t see extra profit in additional maximization or minimization, so it prioritizes hitting the following most necessary purpose. If this appears complicated now, don’t fear it can make extra sense as we get into the instance.
The goal operate for the weights method is specifically formulated to attenuate the weighted variations between a metric’s purpose and the precise worth of the metric. Let’s leap to our instance from above — i.e., we need to make $150k in revenue and waste lower than 20k yards of uncooked materials. Our goal is to attenuate how far off we’re from each of those objectives.
Right here is the mathematical formulation for this goal:

With our goal operate arrange, we have to outline our constraints. We may have two sorts of constraints (1) purpose associated constraints and (2) common linear programming constraints (the identical form of constraints you’ll discover in plain vanilla LP). Let’s discuss in regards to the purpose associated constraints first.
We might want to create two issues to arrange our purpose associated constraints, (1) revenue and waste capabilities and (2) a number of slack variables. Let’s undergo these one after the other.
The revenue and waste capabilities are very straight ahead. They mix our choice variables collectively to calculate whole revenue and whole waste give a particular resolution. Under are the formulation that tie revenue and waste to the variety of pants, shirts and attire we produce:

With our revenue and waste capabilities established, let’s begin speaking about our slack variables. In purpose programming, slack variables are used to measure how far an answer is from hitting a purpose. In our instance, the variables P and W are each slack variables — they symbolize how a lot decrease our revenue is in comparison with our revenue purpose and the way a lot increased our waste is in comparison with our waste purpose. Slack variables are embedded in constraints. Under are the constraint capabilities for our revenue and waste objectives — once more, the P’s and the W’s are our slack variables:

Be aware that we have now plus and minus slack variables — this enables us to overlook the purpose on both finish. We solely need to penalize the slack variable that goes in the wrong way of our purpose (e.g., we don’t need to penalize extra revenue than our purpose, we solely need to penalize much less revenue) — that’s the reason just one slack variable per purpose is within the goal operate. With this new notation, let’s rewrite our goal operate:

We now have now achieved the entire particular work for purpose programming. The very last thing we have to do is rapidly add our plain vanilla finances constraint. We’re utilizing a daily constraint for our finances as a result of, in our instance, it’s a arduous constraint. Not like with revenue and waste, we can’t violate the finances.

Now, we have now a totally specified purpose programming downside. Let’s set it up in Python and resolve!
# $150,000 in revenue
downside += revenue + profit_deviation_neg - profit_deviation_pos == 150000, "Profit_Goal"
# Waste purpose: Not more than 20,000 yards of waste
downside += waste + waste_deviation_neg - waste_deviation_pos == 20000, "Cost_Goal"
# Price range constraint
downside += price <= 50000
# Remedy the issue
downside.resolve()
# Show the outcomes
print("Standing:", pulp.LpStatus[problem.status])
print("Pants produced:", pulp.worth(pants))
print("Shirts produced:", pulp.worth(shirts))
print("Attire produced:", pulp.worth(attire))
print("Value :", pulp.worth(price))
print("Revenue :", pulp.worth(revenue))
print("Revenue deviation (optimistic):", pulp.worth(profit_deviation_pos))
print("Revenue deviation (detrimental):", pulp.worth(profit_deviation_neg))
print("Waste :", pulp.worth(waste))
print("Waste deviation (optimistic):", pulp.worth(waste_deviation_pos))
print("Waste deviation (detrimental):", pulp.worth(waste_deviation_neg))
This optimization recommends we make 0 pants, 5,000 shirts and 0 attire. We make $150k in revenue which matches our purpose precisely and we waste 50k yards of cloth which exceeds our max waste by 30k yards. The complete outcomes are printed by the code and proven under:

Now that we’ve obtained the essential construction of the weights method down, let’s truly discuss in regards to the weights! In our first instance, we gave equal weights to a greenback of revenue and to a yard of waste. This most likely doesn’t make a number of sense as a result of they’re completely different items. Setting the weights is a subjective choice to be made by the practitioner. For our instance, we’ll resolve that losing 1.5 yards of cloth is as dangerous as making $1 of revenue is sweet. In different phrases, we’ll enhance the burden of cloth waste to 1.5 in our goal operate.
downside += profit_deviation_neg + 1.5*waste_deviation_pos
The optimization with the up to date charges recommends we make about 8,572 pants, 7,143 shirts and 0 attire. With this resolution, we generate $107k in revenue (which is a purpose miss of $43k) and we waste 20,000 yards of cloth which matches our purpose precisely. The complete outcomes are printed by the code and proven under:

Clearly, shifting the weights of the objectives can have massive influence on the optimization outcomes. We have to rigorously set our weights to adequately steadiness the relative significance of our objectives!
Now that we have now a strong understanding of how the weighted method works, let’s shift to speaking in regards to the purpose programming with the preemptive method.
Preemptive Strategy
Whereas the weights technique balances objectives utilizing weights within the goal operate, the preemptive technique provides hierarchical precedence to objectives by means of iterative optimizations. That’s a number of phrases, don’t fear, we’ll break it down!
Listed below are the steps to the preemptive method:
1. Run a daily linear programming optimization in your first purpose — e.g., maximize revenue
2. Save the target worth from that run
3. Run one other common linear programming on the following most necessary purpose — e.g., decrease waste — however, add the target worth from the final run as a constraint
4. Repeat the method till you’ve gotten gone by means of all purpose metrics
Two necessary options of the preemptive technique are (1) it prioritizes objectives by rank and (2) the target worth of a better significance purpose can’t be decreased (due to the arduous constraint) when optimizing decrease precedence objectives. Let’s go over an instance to construct instinct.
For our instance, let’s say that revenue is a very powerful purpose and minimizing waste is the second. We’ll begin out by operating a plain vanilla optimization that maximizes revenue:
# Outline the issue
downside = pulp.LpProblem("Clothing_Company_Goal_Programming", pulp.LpMaximize)
# Choice variables: variety of pants, shirts, and attire produced
pants = pulp.LpVariable('pants', lowBound=0, cat='Steady')
shirts = pulp.LpVariable('shirts', lowBound=0, cat='Steady')
attire = pulp.LpVariable('attire', lowBound=0, cat='Steady')
# Revenue and value coefficients
revenue = 10 * pants + 3 * shirts + 15 * attire
price = 5 * pants + 1 * shirts + 10 * attire
waste = 1.5 * pants + 1 * shirts + 3 * attire
# Goal operate: Maximize revenue
downside += revenue
# Constraints
# Price range constraint
downside += price <= 50000
# Remedy the issue
downside.resolve()
# Show the outcomes
print("Standing:", pulp.LpStatus[problem.status])
print("Pants produced:", pulp.worth(pants))
print("Shirts produced:", pulp.worth(shirts))
print("Attire produced:", pulp.worth(attire))
print("Value :", pulp.worth(price))
print("Revenue :", pulp.worth(revenue))
The outcomes of the revenue maximizing LP downside are under:

So, our goal operate says to make 50k shirts and gather a revenue of $150k. This was solely the primary optimization we’re going to run although! Following the algorithm outlined above, we’ll now run one other LP that minimizes waste however, we’ll add a constraint of revenue ≥ $150k to make sure we don’t get a worse revenue.
# Outline the issue
downside = pulp.LpProblem("Clothing_Company_Goal_Programming", pulp.LpMinimize)
# Choice variables: variety of pants, shirts, and attire produced
pants = pulp.LpVariable('pants', lowBound=0, cat='Steady')
shirts = pulp.LpVariable('shirts', lowBound=0, cat='Steady')
attire = pulp.LpVariable('attire', lowBound=0, cat='Steady')
# Revenue and value coefficients
revenue = 10 * pants + 3 * shirts + 15 * attire
price = 5 * pants + 1 * shirts + 10 * attire
waste = 1.5 * pants + 1 * shirts + 3 * attire
# Goal operate: Decrease the material waste
downside += waste
# Price range constraint
downside += price <= 50000
downside += revenue >= 150000
# Remedy the issue
downside.resolve()
# Show the outcomes
print("Standing:", pulp.LpStatus[problem.status])
print("Pants produced:", pulp.worth(pants))
print("Shirts produced:", pulp.worth(shirts))
print("Attire produced:", pulp.worth(attire))
print("Value :", pulp.worth(price))
print("Revenue :", pulp.worth(revenue))
And listed below are the outcomes of this ultimate optimization:

The astute observer will discover that the optimization is the very same 😅. This will usually be the case with the preemptive technique. The constraint of beforehand optimized objectives could be very restrictive. The one time when iterative optimizations are completely different is that if there are a number of methods to get the optimum values for earlier objectives. For instance, if there have been two methods to get $150k in revenue; one had extra waste and the opposite had much less, our second iteration would return the outcomes of the answer with the decrease waste. Within the preemptive technique, there isn’t a commerce off between the objectives. Even when there was an answer that made $149k in revenue with 0 yards of waste, the preemptive technique would all the time select $150k in revenue with 50k yards of waste. The additional $1000 of revenue is infinitely extra necessary than any quantity of wasted material.
The preemptive technique ought to be used when objectives are clearly prioritized, and there’s no substitution between them — which means no quantity of success in decrease precedence objectives can compensate for diminished optimization in increased precedence ones. When used appropriately, the preemptive technique may help optimize a main purpose whereas looking for good options for decrease precedence objectives very successfully.
Conclusion
Aim programming offers a framework that extends conventional linear programming to optimize a number of metrics on the identical time. The weighted method balances priorities through weights within the goal operate and is suitable when goal metrics have relative significance that may be quantified. The preemptive technique is an iterative method that provides precedence to metrics based mostly on hierarchy. It’s acceptable when some targets are wholly extra necessary than others. Each approaches could be highly effective optimization methods when utilized within the right context!
Joyful optimizing!