That is the (and certain final) a part of a Linear Programming collection I’ve been writing. With the core ideas lined by the prior articles, this text focuses on objective programming which is a much less frequent linear programming (LP) use case. Objective 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 objective programming and when it needs to be used
2. The weighted objective programming method — illustrated with an instance
3. The preemptive objective programming method — illustrated with an instance
Definition and Use Case of Objective Programming
Objective 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 choose a single metric to optimize (reduce or maximize) and set constraints to make sure that the optimum answer is possible. Objective programming is a way that enables for a number of goal metrics to be focused on the similar time.
The ‘mindset’ of objective programming is basically completely different from plain vanilla LP issues. Primary LP searches for methods to get as little or as a lot of a single metric as attainable — e.g., maximize revenue or reduce waste — topic to constraints. Usually conflicting priorities shall be discovered within the goal perform or the constraints. For instance, maximize revenue (goal) topic to a most quantity of waste (constraint). With objective programming, we will transfer necessary constraint metrics into the target perform so we will optimize on them slightly than simply constraining them. We will maximize revenue and reduce waste on the similar time!
Now is an efficient time to ascertain the instance we are going to probe for the remainder of the article:
Let’s think about that we handle a manufacturing facility that makes clothes. Our manufacturing facility could make pants, shirts, and clothes. Every article of clothes has prices, revenue, and waste related to their manufacturing. We wish to create a manufacturing plan that may make a sure degree of revenue and likewise waste under a sure amount resulting from an environmental dedication. Let’s say that we wish to make $150k a month in revenue and we additionally wish to waste lower than 20k yards of material. Along with our targets, we will’t spend greater than $50k in supplies and labor.
The instance above sounds so much like an everyday 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 similar time. In different phrases, there can be no possible answer if we had been to plug this into an everyday linear programming downside. Usually, the targets set within the issues can’t all be achieved with a single answer, in any other case there wouldn’t be some extent in utilizing objective programming. We’d simply use common previous linear programming with our targets as constraints. The true worth of objective programming is that it could actually create a compromise between conflicting targets when common linear programming would yield an infeasible answer.
The true worth of objective programming is that it could actually create a compromise between conflicting targets when common linear programming would yield an infeasible answer.
How does objective programming stability and compromise with conflicting targets? There are two widespread 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 perform and runs a single Optimization based mostly on (you guessed it) weights! The truth that just one optimization is run underneath the weights technique might look like 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 targets for a number of metrics — e.g., make a minimum of $150k in revenue promoting garments or waste not more than 20k yards of material. For normal LP, we wish to totally optimize. For the weights technique of objective programming, we wish to get as near hitting targets as attainable — after we attain a objective, the optimization doesn’t see extra profit in additional maximization or minimization, so it prioritizes hitting the following most necessary objective. If this appears complicated now, don’t fear it would make extra sense as we get into the instance.
The goal perform for the weights method is specifically formulated to reduce the weighted variations between a metric’s objective and the precise worth of the metric. Let’s leap to our instance from above — i.e., we wish to make $150k in revenue and waste lower than 20k yards of uncooked materials. Our goal is to reduce how far off we’re from each of those targets.
Right here is the mathematical formulation for this goal:
With our goal perform arrange, we have to outline our constraints. We can have two sorts of constraints (1) objective associated constraints and (2) common linear programming constraints (the identical form of constraints you’d discover in plain vanilla LP). Let’s discuss in regards to the objective associated constraints first.
We might want to create two issues to arrange our objective associated constraints, (1) revenue and waste capabilities and (2) a number of slack variables. Let’s undergo these one by one.
The revenue and waste capabilities are very straight ahead. They mix our choice variables collectively to calculate complete revenue and complete waste give a particular answer. Under are the formulation that tie revenue and waste to the variety of pants, shirts and clothes we produce:

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

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

We have now now completed all the particular work for objective programming. The very last thing we have to do is shortly add our plain vanilla funds constraint. We’re utilizing an everyday constraint for our funds as a result of, in our instance, it’s a laborious constraint. In contrast to with revenue and waste, we can’t violate the funds.

Now, we have now a totally specified objective programming downside. Let’s set it up in Python and remedy!
# $150,000 in revenue
downside += revenue + profit_deviation_neg - profit_deviation_pos == 150000, "Profit_Goal"
# Waste objective: 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
# Clear up the issue
downside.remedy()
# Show the outcomes
print("Standing:", pulp.LpStatus[problem.status])
print("Pants produced:", pulp.worth(pants))
print("Shirts produced:", pulp.worth(shirts))
print("Clothes produced:", pulp.worth(clothes))
print("Price :", pulp.worth(price))
print("Revenue :", pulp.worth(revenue))
print("Revenue deviation (optimistic):", pulp.worth(profit_deviation_pos))
print("Revenue deviation (damaging):", pulp.worth(profit_deviation_neg))
print("Waste :", pulp.worth(waste))
print("Waste deviation (optimistic):", pulp.worth(waste_deviation_pos))
print("Waste deviation (damaging):", pulp.worth(waste_deviation_neg))
This optimization recommends we make 0 pants, 5,000 shirts and 0 clothes. We make $150k in revenue which matches our objective precisely and we waste 50k yards of material which exceeds our max waste by 30k yards. The complete outcomes are printed by the code and proven under:

Now that we’ve received 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 in all probability doesn’t make a whole lot 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 material is as dangerous as making $1 of revenue is sweet. In different phrases, we’ll improve the load of material waste to 1.5 in our goal perform.
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 clothes. With this answer, we generate $107k in revenue (which is a objective miss of $43k) and we waste 20,000 yards of material which matches our objective precisely. The complete outcomes are printed by the code and proven under:

Clearly, shifting the weights of the targets can have giant influence on the optimization outcomes. We have to fastidiously set our weights to adequately stability the relative significance of our targets!
Now that we have now a stable understanding of how the weighted method works, let’s shift to speaking in regards to the objective programming with the preemptive method.
Preemptive Strategy
Whereas the weights technique balances targets utilizing weights within the goal perform, the preemptive technique provides hierarchical precedence to targets by iterative optimizations. That’s a whole lot of phrases, don’t fear, we’ll break it down!
Listed here are the steps to the preemptive method:
1. Run an everyday linear programming optimization in your first objective — e.g., maximize revenue
2. Save the target worth from that run
3. Run one other common linear programming on the following most necessary objective — e.g., reduce waste — however, add the target worth from the final run as a constraint
4. Repeat the method till you could have gone by all objective metrics
Two necessary options of the preemptive technique are (1) it prioritizes targets by rank and (2) the target worth of a better significance objective can’t be decreased (due to the laborious constraint) when optimizing decrease precedence targets. Let’s go over an instance to construct instinct.
For our instance, let’s say that revenue is crucial objective 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 clothes produced
pants = pulp.LpVariable('pants', lowBound=0, cat='Steady')
shirts = pulp.LpVariable('shirts', lowBound=0, cat='Steady')
clothes = pulp.LpVariable('clothes', lowBound=0, cat='Steady')
# Revenue and price coefficients
revenue = 10 * pants + 3 * shirts + 15 * clothes
price = 5 * pants + 1 * shirts + 10 * clothes
waste = 1.5 * pants + 1 * shirts + 3 * clothes
# Goal perform: Maximize revenue
downside += revenue
# Constraints
# Price range constraint
downside += price <= 50000
# Clear up the issue
downside.remedy()
# Show the outcomes
print("Standing:", pulp.LpStatus[problem.status])
print("Pants produced:", pulp.worth(pants))
print("Shirts produced:", pulp.worth(shirts))
print("Clothes produced:", pulp.worth(clothes))
print("Price :", pulp.worth(price))
print("Revenue :", pulp.worth(revenue))
The outcomes of the revenue maximizing LP downside are under:

So, our goal perform says to make 50k shirts and accumulate a revenue of $150k. This was solely the primary optimization we’re going to run although! Following the algorithm outlined above, we are going to now run one other LP that minimizes waste however, we are going to 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 clothes produced
pants = pulp.LpVariable('pants', lowBound=0, cat='Steady')
shirts = pulp.LpVariable('shirts', lowBound=0, cat='Steady')
clothes = pulp.LpVariable('clothes', lowBound=0, cat='Steady')
# Revenue and price coefficients
revenue = 10 * pants + 3 * shirts + 15 * clothes
price = 5 * pants + 1 * shirts + 10 * clothes
waste = 1.5 * pants + 1 * shirts + 3 * clothes
# Goal perform: Decrease the material waste
downside += waste
# Price range constraint
downside += price <= 50000
downside += revenue >= 150000
# Clear up the issue
downside.remedy()
# Show the outcomes
print("Standing:", pulp.LpStatus[problem.status])
print("Pants produced:", pulp.worth(pants))
print("Shirts produced:", pulp.worth(shirts))
print("Clothes produced:", pulp.worth(clothes))
print("Price :", pulp.worth(price))
print("Revenue :", pulp.worth(revenue))
And listed here are the outcomes of this closing 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 targets might 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 targets. 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 any commerce off between the targets. Even when there was an answer that made $149k in revenue with 0 yards of waste, the preemptive technique would at all times 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 needs to be used when targets are clearly prioritized, and there’s no substitution between them — which means no quantity of success in decrease precedence targets can compensate for lowered optimization in larger precedence ones. When used appropriately, the preemptive technique may help optimize a main objective whereas looking for good options for decrease precedence targets very successfully.
Conclusion
Objective programming gives a framework that extends conventional linear programming to optimize a number of metrics on the similar time. The weighted method balances priorities by way of weights within the goal perform and is acceptable when goal metrics have relative significance that may be quantified. The preemptive technique is an iterative method that offers precedence to metrics based mostly on hierarchy. It’s applicable when some targets are wholly extra necessary than others. Each approaches might be highly effective optimization strategies when utilized within the appropriate context!
Joyful optimizing!