That is the (and sure final) a part of a Linear Programming sequence 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. Aim programming is a particular linear programming setup that may deal with the optimization of a number of aims 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 strategy — illustrated with an instance
3. The preemptive objective programming strategy — illustrated with an instance
Definition and Use Case of Aim Programming
Aim programming is a particular case of linear programming that permits for a number of — usually conflicting — aims 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 resolution is possible. Aim programming is a method that permits 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. Fundamental LP searches for methods to get as little or as a lot of a single metric as potential — e.g., maximize revenue or reduce waste — topic to constraints. Typically conflicting priorities might 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 are able to transfer essential constraint metrics into the target perform so we are able to optimize on them slightly than simply constraining them. We will maximize revenue and reduce waste on the similar time!
Now is an effective time to ascertain the instance we’ll 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 can make a sure stage of revenue and likewise waste under a sure amount because of 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 objectives, we are able to’t spend greater than $50k in supplies and labor.
The instance above sounds loads like a daily linear programming downside proper? Nicely, the twist is that we are able to’t make $150k in revenue and waste lower than 20k of yards on the similar time. In different phrases, there can 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 not all be achieved with a single resolution, in any other case there wouldn’t be some extent in utilizing objective programming. We might simply use common previous linear programming with our objectives as constraints. The actual worth of objective programming is that it might create a compromise between conflicting objectives when common linear programming would yield an infeasible resolution.
The actual worth of objective programming is that it might create a compromise between conflicting objectives when common linear programming would yield an infeasible resolution.
How does objective programming stability and compromise with conflicting objectives? There are two widespread approaches: (1) weighted and (2) preemptive. We’ll cowl these intimately within the following sections.
The weights strategy
Right here, we’ll dive into the main points of the weights strategy. 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 could look like a given — however the preemptive technique really 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 at the least $150k in revenue promoting garments or waste not more than 20k yards of material. For normal LP, we wish to absolutely optimize. For the weights technique of objective programming, we wish to get as near hitting objectives as potential — after we attain a objective, the optimization doesn’t see extra profit in additional maximization or minimization, so it prioritizes hitting the following most essential objective. If this appears complicated now, don’t fear it’ll make extra sense as we get into the instance.
The goal perform for the weights strategy 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 objectives.
Right here is the mathematical formulation for this goal:

With our goal perform arrange, we have to outline our constraints. We can have two kinds of constraints (1) objective associated constraints and (2) common linear programming constraints (the identical sort of constraints you’d discover in plain vanilla LP). Let’s speak concerning the objective associated constraints first.
We might want to create two issues to arrange our objective associated constraints, (1) revenue and waste features and (2) a number of slack variables. Let’s undergo these one after the other.
The revenue and waste features are very straight ahead. They mix our determination variables collectively to calculate complete revenue and complete waste give a particular resolution. Beneath are the formulation that tie revenue and waste to the variety of pants, shirts and clothes we produce:

With our revenue and waste features 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 symbolize how a lot decrease our revenue is in comparison with our revenue objective and the way a lot increased our waste is in comparison with our waste objective. Slack variables are embedded in constraints. Beneath are the constraint features for our revenue and waste objectives — once more, the P’s and the W’s are our slack variables:

Notice that now we have plus and minus slack variables — this enables us to overlook the objective on both finish. We solely wish to penalize the slack variable that goes in the wrong 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’ve got now finished 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 a daily constraint for our funds as a result of, in our instance, it’s a arduous constraint. In contrast to with revenue and waste, we can not violate the funds.

Now, now we have a totally specified objective programming downside. Let’s set it up in Python and clear up!
# $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"
# Finances constraint
downside += price <= 50000
# Resolve the issue
downside.clear up()
# 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(clothes))
print("Price :", 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 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 total outcomes are printed by the code and proven under:

Now that we’ve received the fundamental construction of the weights strategy down, let’s really speak concerning 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 loads of sense as a result of they’re completely different models. Setting the weights is a subjective determination 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 enhance the burden 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 resolution, 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 total outcomes are printed by the code and proven under:

Clearly, shifting the weights of the objectives can have massive impression on the optimization outcomes. We have to fastidiously set our weights to adequately stability the relative significance of our objectives!
Now that now we have a stable understanding of how the weighted strategy works, let’s shift to speaking concerning the objective programming with the preemptive strategy.
Preemptive Method
Whereas the weights technique balances objectives utilizing weights within the goal perform, the preemptive technique offers hierarchical precedence to objectives by way of iterative optimizations. That’s loads of phrases, don’t fear, we’ll break it down!
Listed below are the steps to the preemptive strategy:
1. Run a daily 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 essential objective — e.g., reduce waste — however, add the target worth from the final run as a constraint
4. Repeat the method till you will have gone by way of all objective metrics
Two essential options of the preemptive technique are (1) it prioritizes objectives by rank and (2) the target worth of a better significance objective 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 crucial objective and minimizing waste is the second. We’ll begin out by working 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
# Finances constraint
downside += price <= 50000
# Resolve the issue
downside.clear up()
# 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(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’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 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
# Finances constraint
downside += price <= 50000
downside += revenue >= 150000
# Resolve the issue
downside.clear up()
# 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(clothes))
print("Price :", pulp.worth(price))
print("Revenue :", pulp.worth(revenue))
And listed here are the outcomes of this remaining 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 will 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 at all times select $150k in revenue with 50k yards of waste. The additional $1000 of revenue is infinitely extra essential than any quantity of wasted cloth.
The preemptive technique needs to be used when objectives are clearly prioritized, and there’s no substitution between them — that means no quantity of success in decrease precedence objectives can compensate for decreased optimization in increased precedence ones. When used appropriately, the preemptive technique might help optimize a main objective whereas looking for good options for decrease precedence objectives very successfully.
Conclusion
Aim programming gives a framework that extends conventional linear programming to optimize a number of metrics on the similar time. The weighted strategy balances priorities through weights within the goal perform and is acceptable when goal metrics have relative significance that may be quantified. The preemptive technique is an iterative strategy that provides precedence to metrics based mostly on hierarchy. It’s applicable when some aims are wholly extra essential than others. Each approaches will be highly effective optimization strategies when utilized within the appropriate context!
Completely satisfied optimizing!