views:

233

answers:

6

I am trying to optimize how orders are filled at my work. Right now, an employee just grabs the latest 16 orders(sometimes 14 or 18) and fills them.

I am trying to change it so that instead of simply going by the latest list of orders, that it orders them so each batch has order in similar locations. But I can't figure out how I should go about sorting the list. Below is a simplified example of what I want to do.

Example Order List:

  • order 1: 2 products in location E, 5 products in location Q
  • order 2: 1 in location Z, 20 in location B
  • order 3: 1 in location Y, 1 in location N
  • order 4: 3 in location B
  • order 5: 1 in location A, 10 in location E
  • order 6: 1 in location A, 1 in location B, 5 in location Q

After sorting the list, I want order 2 and 4 next to each other, 1 and 6 next to each other, etc. Something like this:

  • order 1: 2 products in location E, 5 products in location Q
  • order 6: 1 in location A, 1 in location B, 5 in location Q
  • order 2: 1 in location Z, 20 in location B
  • order 4: 3 in location B
  • order 3: 1 in location Y, 1 in location N
  • order 5: 1 in location A, 10 in location E

I am using PHP, but any examples or hints in any language would be greatly helpfully.

Edit:

Let me try to explain this in better detail. Employees grab batches of orders and they they go fill the orders using a PDA with a barcode scanner. Our warehouse is set up so that location A is first, B is next and so on. There is no backtracking involved at all. Generally, they have to walk the whole warehouse to fill the batch of orders because on average, the 16 orders will have products from all of the locations.

If I change the sorting of which orders are being filled next from the date of the order to the location of the products of the order, then a batch of orders might only have locations A-G and wont have to walk the whole warehouse.


Another Edit(I really need to get better at posting good details)

Here is our current process:

  1. Picker grabs a cart with 16 buckets on it
  2. Picker scans the 16 unique bar codes from the buckets onto a webpage via a PDA(with scanner and wifi) and a 'picking ticket' is created
  3. The products are ordered by location (the picker only walks by any product once)
  4. The special webpage then tells the employee which product and how many to grab and they scan the bar code on the product
  5. Then it says which bucket to place the product in and they they scan the bar code on the bucket they are putting the product in
  6. After all the products are picked, Picker goes to the shipping station and scans in one of the buckets into a VB program (yes, eww I know. Someday that will get converted)
  7. Receipts are printed for all the orders in that 'picking ticket' and are placed into the correct bucket
  8. Each bucket is emptied and packaged up
  9. Picker now shipper places packaged order on a scale and scans the bar code on the receipt into a program.
  10. The correct postage is printed automatically and the order is marked as shipped and the customer is sent an email with tracking information
  11. Shipper puts postage label on the page, seals it up and puts it in the pile of finished packages
  12. At the end of the day, USPS and UPS pick up the shipments.

I should also note, that a lot/most of our products are small and a 16 order 'picking ticket' can have 500-800 individual pieces. Right now, we have about 28,000 different products in stock.

A: 

By using usort, you can custom define your sorting method. Such that, based on the array (list), you can compare the elements and put that array in the optimal order you wish, without being limited to simply the keys or values. You can use the objects in the array itself, and determine what the order should be.

drowe
Yup, I'm already using usort, but I can't figure out how to use it to sort it the way I want it. I've thought of sorting alphabetically by the location, but each order usually has products from multiple locations.
Echo
A: 

This is a complex problem, sounds like the traveling salesman.

What you can do is:
Create the list in all possible orders.
Calculate a score for each list based on how many connections there are between each row.

For example: if order2 is followed by order6 the score would be 1, because 1 location(B) is overlapping. if the next order is order3 the score would be increased with 0, because neither Y or N is in order6.

The list with the highest score is in the optimal order.

For 18 elements in the list there are 18! = 6402373710000000 possible ways to order the list. So I would create 10 a 20 lists in random order and pick the one with the best score.

Bob Fanger
+1  A: 

As I wrote in the comments on the question, I think you're just looking at the problem the wrong way.

Your description implies that they can go to all the locations before they have to "build"/finish the orders. The problem is that right now, things are grouped in terms of orders, so they try to fill Order #1 by going to all the locations that it requires, then they start looking at Order #2, etc.

Instead, you need to give them aggregated information in terms of the locations, and what they need to pick up at each one. Then they just go to all of the locations, in any order, and pick up everything they need from each one. When they've been to all locations, they go through the list and fill the orders from their big pile of stuff.

Let me know if I've made some incorrect assumptions here, and I'll try to come up with a different approach.


Just to try and clear up the difference, here's the employee's motion in each method (the first two are not definite, because they could have gone to locations in different orders, I just followed the exact order you listed in, as an employee probably would).

Original sort by date (12 moves):

E > Q > Z > B > Y > N > B > A > E > A > B > Q

Your re-sorted version (10 moves):

E > Q > A > B > Z > B > Y > N > A > E

By aggregating by location (7 moves):

A > B > E > N > Q > Y > Z

To further stress the difference, if I assume that all your locations are equidistant from the previous one (so moving from A to B has a cost of 1), and that you have one for each letter. Also assuming that you both want to start and end at location 0, you have:

Original sort by date: amount of movement = 138
Your re-sorted version: amount of movement = 138 (that's kind of surprising)
By aggregating by location: amount of movement = 52

Chad Birch
Not at all what I'm looking for, but that is an interesting way to do it. I'll have to look into it to see if something like that would work.
Echo
A: 

You may be lacking focus here: too many details like what programming language you use, what kind of PDA/scanner end users use, etc.

All you need is one thing: a transitive comparison (<) operator for two elements (transitive meaning if A<B and B<C then A<C always). If you have this operator, you have a sort.

Focus on this one thing and go back to your customer if necessary to discuss requirements. If defining operator < is too complicated, chances are the customer won't be happy with the solution anyway.

azheglov
Yes, there were a lot of details, but actually reading the question so that your answer is relevant to what he's trying to do would be a good idea. It's not just a simple sort, he's trying to determine a more efficient path.
Chad Birch
I can see why you may not like my remarks, but the point remains: the questioner is probably better off talking to his customers instead of talking to strangers on SO. If the customers don't understand how to compare two orders, how will they be able to use the solution?
azheglov
No, I don't think you do see. There's no "comparison" going on at all. It's not sorting, it's path optimization.
Chad Birch
+1  A: 

I think the best solution here would be to seperate the picking and packing stage.

Here's how it works at my workplace

  1. Batch of orders is allocated (generally based on delivery method and/or website order is from)
  2. Picker gets assigned, pick slip prints, containing list of products and quantities (not specific to order)
  3. Picker goes and picks, brings back to station.
  4. Items are scanned on PC, going through "checkout" process. This makes sure that the picker has picked everything correctly.
  5. Invoices are printed
  6. Batch goes to packing, each invoice is scanned, followed by the items for the order, packed, dropped in shipping bin
  7. Cycle through orders
  8. Complete batch, emails/SMS are sent to customers saying their order is being dispatched
  9. Royal Mail/Other shipping company come and take away the orders

We find that this works pretty well, espescially the confirmation at each stage.

We're currently re-implementing everything in PHP, and this is working pretty darn well for us.

My advice would be, rethink your workflow

Mez
Yeah, fits with my answer. I think the problem may be that, for whatever reason, employees currently need to finishing picking an entire order before they can start on the next one. A workflow change will definitely make the biggest difference.
Chad Birch
It's not even a significant workflow change, conceptually. Right now things go: "Look at each order, and go to each warehouse location to pick up what they need." This can easily be replaced with "Go get everything that all the orders need, then look at each order and fill them out of the things you collected."
Chad Birch
I just updated my post on what our current process is. Hopefully I made it more clear. Your way is very similar to how we used to do it. But going though all of the items more than once really slowed us down since we deal with small items and each order averages around 35-40 pieces, sometimes orders have a few hundred pieces.
Echo
From your current process, I'm unsure as to what you're trying to change?
Mez
Ah, actually, a change to your process that might be useful is something of a "stock re-allocator" - so it analyses what are the most popular products, and puts them on shelves in A, etc etc, so when you recieve them in, it'll start moving, and be able to pick from multiple locations. This is something we're currently working on in our warehouse.
Mez
+1  A: 

The question seems to contradict itself - the first part before the edit deals with the ordering of the orders, whereas the edit talks about getting the correct batch of orders to give to a user. I am going to assume your edit is more correct, and discuss batching more than ordering.

It sounds like that, at worst, the employee needs to walk all locations (A-Z, I'm assuming), then return back to A to begin their next batch of orders. Given this assumption, it seems that you're simply trying to create batches wherein the maximum location is less than Z. In other words, if you had six orders you were grouping into two batches, like this: [A, Y, B, G, Y, Z], you'd split them into [ABG] and [YYZ]. As such, I think the algorithm would be pretty simple:

  1. Run through each order and calculate the maximum distance item.
  2. Sort orders by maximum location.
  3. Return batches based on this sorting.

For example, suppose we have four orders that we want to make two batches from: (A, B), (A, Y), (F, G), (E, P). We would then calculate their maximum distance items as [B, Y, G, P]. After sorting, we end up with [B, G, P, Y]. And thus the first batch would contain #1 and #3, and the second would contain #2 and #4. The order that contains a Y was going to have to go all the way from A to Y anyways, so it makes no difference that it also requires an item from A; but by keeping #1 and #3 together, one of the employees walks a lot less.

Daniel Lew