I have quite a strange question on my hands.
I have a list (~500 entries) of lengths of wooden beams in different sizes, such as 3400mm, 1245mm, 900mm, etc.
The maximum length of a wooden beam is 5400mm and in order to reduce the amount of wood being wasted I want to find an algorithm that tries every possible way to combine the smaller sizes to fit into 5400mm beams or as close as possible.
So let's say I have five different lengths: 3000, 1000, 300, 2000, 900 I would end up with:
3000+2000+300 = 5300 // The closest combination to 5400, meaning the amount of wood being wasted is only 100mm on this beam.
1000+900 = 1900 // The rest
I'm not sure if this qualifies for the traveling salesman problem and I have only begun to imagine what the algorithm might look like. But since there are so many smart people with combinatory skills here I just wanted to throw it out there before I bang my head bloody.
To make things even worse
Let's say we do find a solution to the problem above. The guys over at the wood shop rarely delivers 5400mm beams but it can range from 3000 to 5000 in 100mm intervals.
So I'll get a list of beam lengths from them on delivery.
Would it be possible to match the list "this is the beams I got" with the list "find out the best combination of the required beam lengths"?
I'm not sure if it's worth it in the end but any help is appreciated.
Kind regards
Richard
This is the Cutting Stock Problem in 1 dimension. It's reducible to the Knapsack problem so it is in fact NP-complete, but it's generally tractable and in cases where it isn't many good approximate solutions exist, because this is an insanely important problem in industry.
It's typically solved exactly using dynamic programming, which is kind of a mindfuck, but you can find plenty of example implementations to help you out. Approximate polynomial time solutions typically call the dynamic programming code (which has pseudo-polynomial complexity) at various points, and the surrounding code is simpler. I guess the take home message here is don't try to write it yourself, find someone else's code and port it to your language and application environment.
Related
I recently came across the above puzzle game. The objective is to form a large triangle in such a way that the shapes and colors of the parts of the figures on neighboring triangles match.
One way to solve this problem is to apply an exhaustive search and to test every possible combination (roughly 7.1e9). I wrote a simple script to solve it (github).
Since this puzzle is quite old, brute-forcing this problem may not have been feasible back then. So, what's a more efficient way (algorithm/mathematical theory) to solve this?
This is equivalent to the Edge-matching problem (with some regular polygons), which is of course np-complete (and there are more negative results i assume about approximations). This means, that there exists puzzles which are very hard to solve (at least if P != NP).
One interesting side-note: there is a very popular (commercial) edge-matching puzzle called Eternity II which had a prize value of two million dollars. It's still unsoved to my knowledge.
This problem resulted in many attempts and blog-writings, which should offer you much about solving these kind of problems.
Failed (in terms of: did not solve the full-size E2 puzzle; but other hard ones) approaches, which should work much better than exhaustive-search (without heuristics) are:
SAT-solving (in my opinion most powerful complete approach)
Constraint-programming
Common Metaheuristics (a lot of potential when tuned to some problem-statistics)
Some interesting resources:
Complexity-theory: Demaine, Erik D., and Martin L. Demaine. "Jigsaw puzzles, edge matching, and polyomino packing: Connections and complexity." Graphs and Combinatorics 23.1 (2007): 195-208.
General hardness analysis (practical): Ansótegui, Carlos, et al. "How Hard is a Commercial Puzzle: the Eternity II Challenge." CCIA. 2008.
SAT-solving approach: Heule, Marijn JH. "Solving edge-matching problems with satisfiability solvers." SAT (2009): 69-82.
Edge-matching as benchmarks (because of hardness): Ansótegui, Carlos, et al. "Edge matching puzzles as hard sat/csp benchmarks." International Conference on Principles and Practice of Constraint Programming. Springer Berlin Heidelberg, 2008.
One common approach to solving this sort of problem is with backtracking.
You choose a starting place, put down one of the tiles and then try to find matches for it in the neighboring places. When you get stuck, you back up one, and try an alternative there.
Eventually you have tried every possibility, without bothering with a huge number of dead ends. Once you get stuck, there is no point in filling in the rest in any way, because you'll still be stuck at that one point.
More recently, Knuth has applied his Dancing Links algorithm to problems of this nature, with even greater efficiencies gained thereby.
For a problem the size of your example, with just 9 pieces and two "colors", all solutions would be found in a matter of seconds at the most.
I'm working on an app that's going to estimate building material for my business. The part I'm working on right now deals specifically with trim that goes around windows.
The best way to explain this is to give an example:
Window trim is purchased in lengths of 14 feet (168 inches). Let say I have 5 rectangular windows of various sizes, all of which consist of 4 pieces of trim each (the top and bottom, and right and left). I'm trying to build an algorithm that will determine the best way to cut these pieces with the least amount of waste.
I've looked into using permutations to calculate every possibly outcome and keep track of waste, but the number of permutations where beyond the trillions once I got past 5 windows (20 different pieces of trim).
Does anyone have any insight on how I might do this.
Thanks.
You are looking at a typical case of the cutting stock problem.
I find this lecture from the University of North Carolina (pdf) is rather clear. More oriented towards implementing, with an example throughout, and few requirements -- maybe just looking up a few acronyms. But there are also 2 hours of video lectures from the university of Madras on the topic, if you want more details and at a reasonably slow pace.
It relies on solving the knapsack problem several times, which you can grab directly from Rosetta Code if you don't want to go through a second linear optimization problem.
In short, you want to select some ways (how many pieces of each length) in which to cut stock (in your case the window trim), and how many times to use each way.
You start with a trivial set : for each length you need, make a way of cutting with just that size. You then iterate : the knapsack problem gives the least favourable way to cut stock from your current configuration, and the simplex method then "removes" this combination from your set of ways to cut stock, by pivoting.
To optimize the casements on windows and bi-fold doors for the company i worked for, i used this simple matrix - i simply took the most common openings and decided what would be the most reasonable and optimal cut lengths.
for example a 3050 window could be trimmed with waste by using one 8' cut and one 12'cut.
Some firm is supplied with large wooden panels. These panels are cut to required pieces. To make for example bookshelf, they have to cut pieces from the large panel. In most cases, the pig panel is not used from 100%, there will be some loss, some remainder pieces, which can not be used. So to minimize the loss, they have to find optimal layout of separate pieces on big panel/panels. I think this is called "two dimensional rectangle bin packing problem".
Now it is getting more interesting.
Not all panels are the same, they can have slightly different tone. Ideal bookshelf is made from pieces all cut from one panels or multiple panels with same color tone. But bookshelf can be produced in different qualities (ideal one; one piece with different tone; two pieces..., three different color plates used; etc...). Each quality has its own price. (the superior in quality the more expensive).
Now we have some wooden panels in stock and request to some furnitures (e.g. 100 bookshelves). The goal is to maximize the profit (e.g. create some ones in ideal quality and some in less quality to keep material loss low).
How to solve this problem? How to combine it with bin packing problem? And hints, papers/articles would be appreciated. I know I can minimize/maximize some function and inequalities with integer linear programming, but I really do not know how to solve this.
(please, do not consider the real scenerio, when for example would be the best to create only ideal ones... imagine, that loss from remaining material is X money per cm^2 and Y is the price for specific product quality and that X and Y can be "arbitrary")
I can give an idea of how these problems are solved and why yours is particularly difficult.
In a typical optimization problem, you want to maximize or minimize a function (e.g. energy) with respect to a set number of variables (e.g. length). For example, how long should a spring be in order to minimize the stored energy. The answer is just a number, the equilibrium length of the spring. Another example would be "what price should we set our product to maximize profit?" (Too expensive and no-one will buy anything; too cheap and you won't cover your costs.) Again, the answer is just a number, the optimal price. Optimizations like that are handled with ordinary calculus.
A much more difficult optimization problem is where the answer isn't a number, but a function, like a shape. An example is: what shape will a hanging chain make in order to minimize its gravitational potential energy. Or: what shape should we cut out of these boards in order to maximize profit? This type of problem is solved using variational calculus, which is very difficult.
In any case, when solving optimization problems numerically, there are a few basic steps to follow. First you have to define a function, for example profit(cuts,params) that you want to maximize with respect to some variables 'cuts', with other parameters 'params' fixed. 'params' stores information like the amount and type of wood that you have, and the amount of money different type of furniture is worth.
The second step is to come up with a guess for the best set of cuts, we'll call it cuts_guess. In order to do this you need to come up with an algorithm that will suggest a set of furniture you could actually make using the supplies that you have. For example, if you can make at least one bookshelf from each board, then that could be your initial guess for the best way to use the wood.
The third phase is the optimization. For the initialization, set cuts_best=cuts_guess and profit_best=profit_guess=profit(cuts_guess, params). Then you need (an algorithm) to make small pseudo-random changes to 'cuts', and check if profit increases or decreases. Record the best set of cuts that you find, and the corresponding profit. Usually it's best if there some randomness involved, in order to explore the largest number of possibilities and not get 'stuck' on a poor choice. You'll find examples of this if you look up 'Monte Carlo algorithm'.
Anyway, all of this will be very difficult for your problem. It's easy how to come up with a guess for a variable (e.g. length), and then how to change that guess (e.g. increase or decrease the length a bit). It's not at all obvious how to make a 'guess' for how to place a cut-out on a board, or how to make a small change.
I'm designing a city building game and got into a problem.
Imagine Sierra's Caesar III game mechanics: you have many city districts with one market each. There are several granaries over the distance connected with a directed weighted graph. The difference: people (here cars) are units that form traffic jams (here goes the graph weights).
Note: in Ceasar game series, people harvested food and stockpiled it in several big granaries, whereas many markets (small shops) took food from the granaries and delivered it to the citizens.
The task: tell each district where they should be getting their food from while taking least time and minimizing congestions on the city's roads.
Map example
Suppose that yellow districts need 7, 7 and 4 apples accordingly.
Bluish granaries have 7 and 11 apples accordingly.
Suppose edges weights to be proportional to their length. Then, the solution should be something like the gray numbers indicated on the edges. Eg, first district gets 4 apples from the 1st and 3 apples from the 2nd granary, while the last district gets 4 apples from only the 2nd granary.
Here, vertical roads are first occupied to the max, and then the remaining workers are sent to the diagonal paths.
Question
What practical and very fast algorithm should I use? I was looking at some papers (Congestion Games: Optimization in Competition etc.) describing congestion games, but could not get the big picture.
You want to look into the Max-flow problem. Seems like in this case it is a bipartite graph, which should make things easier to visualize.
This is a Multi-source Multi-sink Maximum Flow Problem which can easily be converted into a simple Maximum Flow Problem by creating a super source and a super sink as described in the link. There are many efficient solutions to Maximum Flow Problems.
One thing you could do, which would address the incremental update problem discussed in another answer and which might also be cheaper to computer, is forget about a globally optimal solution. Let each villager participate in something like ant colony optimization.
Consider preventing the people on the bottom-right-hand yellow node in your example from squeezing out those on the far-right-hand yellow node by allowing the people at the far-right-hand yellow node to bid up the "price" of buying resources from the right-hand blue node, which would encourage some of those from the bottom-right-hand yellow node to take the slightly longer walk to the left-hand blue node.
I agree with Larry and mathmike, it certainly seems like this problem is a specialization of network flow.
On another note, the problem may get easier if your final algorithm finds a spanning tree for each market to its resources (granaries), consumes those resources greedily based on shortest path first, then moves onto the next resource pile.
It may help to think about it in terms of using a road to max capacity first (maximizing road efficiency), rather than trying to minimize congestion.
This goes to the root of the problem - in general, it's easier to find close to optimal solutions in graph problems and in terms of game dev, close to optimal is probably good enough.
Edit: Wanted to also point out that mathmike's link to Wikipedia also talks about Maximum Flow Problem with Vertex Capacities where each of your granaries can be thought of as vertices with finite capacity.
Something you have to note, is that your game is continuous. If you have a solution X at time t, and some small change occurs (e.g: the player builds another road, or one of the cities gain more population), the solution that the Max Flow algorithms give you may change drastically, but you'd probably want the solution at t+1 to be similar to X. A totally different solution at each time step is unrealistic (1 new road is built at the southern end of the map, and all routes are automatically re-calculated).
I would use some algorithm to calculate initial solution (or when a major change happens, like an earthquake destroys 25% of the roads), but most of the time only update it incrementally: meaning, define some form of valid transformation on a solution (e.g. 1 city tries to get 1 food unit from a different granary than it does now) - you try the update (simulate the expected congestion), and keep the updated solution if its better than the existing solution. Run this step N times after each game turn or some unit of time.
Its both efficient computationally (don't need to run full Max Flow every second) and will get you more realistic, smooth changes in behavior.
It might be more fun to have a dynamic that models a behavior resulting in a good reasonable solution, rather than finding an ideal solution to drive the behavior. Suppose you plan each trip individually. If you're a driver and you need to get from point A to point B, how would you get there? You might consider a few things:
I know about typical traffic conditions at this hour and I'll try to find ways around roads that are usually busy. You might model this as an averaged traffic value at different times, as the motorists don't necessarily have perfect information about the current traffic, but may learn and identify trends over time.
I don't like long, confusing routes with a lot of turns. When planning a trip, you might penalize those with many edges.
If speed limits and traffic lights are included in your model, I'd want to avoid long stretches with low speed limits and/or a lot of traffic lights. I'd prefer freeways or highways for longer trips, even if they have more traffic.
There may be other interesting dynamics that evolve from considering the problem behaviorally rather than as a pure optimization. In real life, traffic rarely converges on optimal solutions, so a big part of the challenge in transportation engineering is coming up with incentives, penalties and designs that encourage a better solution from the natural dynamics playing out in the drivers' decisions.
I am looking for a pseudo-code solution to what is effectively the Multiple Knapsack Problem (optimisation statement is halfway down the page). I think this problem is NP Complete so the solution doesn't need to be optimal, rather if it is fairly efficient and easily implemented that would be good.
The problem is this:
I have many work items, with each taking a different (but fixed and known) amount of time to complete.
I need to divide these work items into groups so as to have the smallest number of groups (ideally), with each group of work items taking no longer than a given total threshold - say 1 hour.
I am flexible about the threshold - it doesnt need to be rigidly applied, though should be close. My idea was to allocate work items into bins where each bin represents 90% of the threshold, 80%, 70% and so on. I could then match items that take 90% to those that take 10%, and so on.
Any better ideas?
You need http://www.or.deis.unibo.it/knapsack.html, chapter 6.6 "Multiple knapscack problem - Approximate algorithms". There is pseudo-code (Pascal style) in the text and Fortran implementations (yes, it's an old book) as a ZIP file.
As far as I know, the problem is NP complete (Wikipedia confirms), so there's probably not much sense in attempting to solve it exactly.
However, any number of approaches might be good enough for you: greedy, genetic algorithms, simulate annealing...greedy is probably the easiest to implement:
while (time available in block greater than smallest task duration)
find the longest fitting task
add it
...you get the idea.