The motivation for this post comes from a sequence of questions posted on OR Stack Exchange (including this one), having to do with a mixed integer programming model for routing an electronic vehicle (EV) serving various customers. One difference from the basic single vehicle routing models with which I'm familiar is that the EV has to visit a charging station periodically during the route. That is easy to accommodate. Where it gets funky is that the modeler needs to know within the model which customer was last on the route, because the EV is required to go to the nearest charging station after its last stop. I'll take that a step further and require the model to provide (via variables) the position of each node (first, second, third) in the route sequence. This might be useful if, for example, the model had to enforce a rule that customer X must be among the first three customers served. Identifying just the last customer node is easier, as I'll describe at the end.
Attempts by the author of the original question followed the usual pattern for vehicle routing. Assume that there is a single vehicle, each customer must be visited once, and there are no time windows complicating things. You have a digraph containing nodes for each customer and each charging station. You typically start by assigning a binary variable xij to each arc (i,j), taking value 1 if and only if the vehicle crosses that arc, and proceed from there.
To collect sequencing information, I would normally employ the Miller-Tucker-Zemlin formulation of subtour elimination constraints. The MTZ approach adds a nonnegative auxiliary variable ui for each node i together with the constraints uj≥ui+xij−M(1−xij) for each pair of distinct nodes i≠j. This says that if we cross arc (i,j), the value of uj must be at least one higher than the value of ui, preventing any loops. If n is the number of nodes and we are willing to start numbering with us=0 (s being the starting node for the tour), we can choose M=n−1. The MTZ constraints are intended to prevent subtours, but as a side effect the u variables number the stops in the order they occur.
This would work for the EV problem if there were a rule that the EV cannot use the same charging station twice during a tour. If the vehicle can stop more than once at the same charging station (which I assume would normally be the case), we cannot use the MTZ constraints because a repeat visit to a charging station would create a subtour. This also complicates (I think) the use of subtour elimination constraints to prevent disjoint subtours. Fortunately, there are at least two "reasonable" (in my opinion) workarounds, both using the MTZ constraints. Unfortunately both are clunky.
The first workaround is to create multiple clones of each charging station node. So if node s represents a charging station, we introduce additional nodes s′,s″,s‴… that are all charging stations, all in the same location (meaning time / distance / charge consumption between node i and any of the clones is the same). For any arcs (i,s) and (s,j) we add arcs (i,s′),(s′,j),(i,s″),(s″,j) etc. We do not require that every charging node be entered (unlike customer nodes, which must all be visited), but we do limit each charging node to at most one entry. That removes the threat of loops and let us use the MTZ approach. Besides making the digraph larger, this forces the modeler to guess how many clones of each charging node will be needed.
The other approach is change to a multigraph, with fewer nodes but more arcs. We include only customer nodes, plus dummy start and end nodes. Arcs from the start node to each customer (within EV range) are the same as before. The end node is a stand-in for the closest charging station to the last customer visited. The arc from any customer node to the end node has the time / distance / charge consumption required to reach the closest charging station. (The closest charging station to each customer node is computed before building the model.)
For each pair of customer nodes i≠j, the arc (i,j) (if it exists) represents moving directly from i to j. For select charging nodes s we add another arc from i to j, which I will denote <i,s,j>, that represents going from i to s, recharging, and then proceeding from s to j. Each of those arcs produces another MTZ constraint. As usual, every customer node should be entered/exited exactly once.
If the number of charging stations is small, we can create extra arcs <i,s,j> for every combination of two customers and a charging station, weeding out those that are infeasible (meaning an EV with a full charge could not get from i to s or from s to j). To get a smaller model, we can throw out arcs that are dominated by other arcs. For <i,s,j> to dominate <i,s′,j>, you would need power consumption from i to s to be no greater than power consumption from i to s′ and power consumption from s to j to be no greater than power consumption from s′ to j. (If other criteria, such as mileage or transit time, appear in the objective function then they would also factor into the determination of dominance.)
One advantage of this approach is that it would let us dispense with the u variables and the MTZ constraints if the only reason for them was to enable constraints forcing the EV to end at the charging station closest to the last customer, since that is baked into the arcs leading to the dummy end node. If we want to use the cloned charging station approach, we can also use a dummy end node linked to each customer by an arc representing the link to that customer's nearest charging station to enforce the desired ending rule for the tour.
No comments:
Post a Comment
Due to intermittent spamming, comments are being moderated. If this is your first time commenting on the blog, please read the Ground Rules for Comments. In particular, if you want to ask an operations research-related question not relevant to this post, consider asking it on Operations Research Stack Exchange.