I'm looking for alternative viewpoints to solve sudoku problems using constraint programming.
The classical viewpoint is to use a finite domain (row, column) variables who can take values from 1 to 9. This is a good viewpoint and it's easy to define constraints for it. For example: (1,2) variable with as value 4 means 4 is in row 1 in column 2.
But it's hard to come up with other viewpoints. I tried and came up with the viewpoint of a 3-dimensional matrix that takes binary values. For example variable (1,2,7) with 1 as value means there is a 7 in row 1 in column 2. But using binary values should be your go to if all other viewpoints fail to deliver good constraints.
Are there any other good viewpoints out there?
EDIT: A good viewpoint should allow the constraints to be concisely expressed. I prefer viewpoints that allow the problem to be described using as few constraints as possible, as long as those constraints have efficient algorithms.
Definition viewpoint: A viewpoint is a pair X,D, where X = {x1, . . . , xn} is a set of variables,
and D is a set of domains; for each xi ∈ X, the associated domain Di is the set of
possible values for x. It must be possible to ascribe a meaning to the variables and values
of the CSP in terms of the problem P, and so to say what an assignment in the viewpoint
X,D is intended to represent in terms of P.
The viewpoints you gave are a homomorphical mapping of the positional encoding of the relation a sudoku is build from (row,column, digit).
Another approach would be encoding the restriction sets (rows[1-9], columns[1-9], squares[ul,um,ur,ml,mm,mr,ll,lm,lr], or whatever restrictions apply) and whether a certain digit is placed in it. This likely will be
horrible with respect to defining constraints. (So I'd guess it is to be considered as not good). It requires encoding the relation among the restriction sets to be "known" separately.
E.g. a (2,5,7) in classical viewpoint would imply (row2,7),(col5,7) and (um,7) in this alternative.
As you can see, the problem is with the encoding of the relation between a logical position and the various constraints.
The classical vieport is building upon encoding the positional data and applies constraints on possible placings. (The way a sudoko is explained and approached for solving.) The alternative is using the constraint sets as viewpoints and needs to address the positioning as constraints.
Normal people might get a knot into their brains from such representation, though. (And I'd not volunteer for figuring out the constraints...)
One possible other viewpoint is the following:
Let's first associate a number to each 3x3 region (top-left is 1, top is 2, etc.) and inside each of these regions a number to all of the 9 squares in it (top-left is 1, top is 2, etc.).
X={Xi,j | i ∈ 1..9, j ∈ 1..9 } where Xi,j has domain 1..9 and designate the place of number i in region j. The region constraint is already encoded with this model, the remaining two are the row and column constraints.
Here is the line constraint:
for each number i ∈ 1..9
for each (a,b,c) ∈ {(1,2,3),(4,5,6),(7,8,9)}
(Xi,a,Xi,b,Xi,c) ∈ {(1,4,7),(1,4,8),(1,4,9),(1,5,7),(1,5,8),(1,5,9),(1,6,7),(1,6,8),(1,6,9),(2,4,7),(2,4,8),(2,4,9),(2,5,7),(2,5,8),(2,5,9),(2,6,7),(2,6,8),(2,6,9),(3,4,7),(3,4,8),(3,4,9),(3,5,7),(3,5,8),(3,5,9),(3,6,7),(3,6,8),(3,6,9)}
The column constraint is similar but with (a,b,c) ∈ {(1,4,7),(2,5,8),(3,6,9)}.
This view is region-based, but two other similar views exist based on row and columns.
Other views exist, you could for example have X={Xi,j | i ∈ 1..9, j ∈ 1..9 } ∪ {Yi,j | i ∈ 1..9, j ∈ 1..9 } where Xi,j is the row (from 1 to 3) of number i in region j and Yi,j its column. All you need to do is figure out how to express the constraints.
Related
I'm trying to find an algorithm to the following problem.
Say I have a number of objects A, B, C,...
I have a list of valid combinations of these objects. Each combination is of length 2 or 4.
For eg. AF, CE, CEGH, ADFG,... and so on.
For combinations of two objects, eg. AF, the length of the combination is 2. For combination of four objects, eg CEGH, the length of the combination.
I can only pick non-overlapping combinations, i.e. I cannot pick AF and ADFG because both require objects 'A' and 'F'. I can pick combinations AF and CEGH because they do not require common objects.
If my solution consists of only the two combinations AF and CEGH, then my objective is the sum of the length of the combinations, which is 2 + 4 = 6.
Given a list of objects and their valid combinations, how do I pick the most valid combinations that don't overlap with each other so that I maximize the sum of the lengths of the combinations? I do not want to formulate it as an IP as I am working with a problem instance with 180 objects and 10 million valid combinations and solving an IP using CPLEX is prohibitively slow. Looking for some other elegant way to solve it. Can I perhaps convert this to a network? And solve it using a max-flow algorithm? Or a Dynamic program? Stuck as to how to go about solving this problem.
My first attempt at showing this problem to be NP-hard was wrong, as it did not take into account the fact that only combinations of size 2 or 4 were allowed. However, using Jim D.'s suggestion to reduce from 3-dimensional matching (3DM), we can show that the problem is nevertheless NP-hard.
I'll show that the natural decision problem form of your problem ("Given a set O of objects, and a set C of combinations of either 2 or 4 objects from O, and an integer m, does there exist a subset D of C such that all sets in D are pairwise disjoint, and the union of all sets in D has size at least m?") is NP-hard. Clearly the optimisation problem (i.e., your original problem, where we seek an actual subset of combinations that maximises m above) is at least as hard as this problem. (To see that the optimisation problem is not "much" harder than the decision problem, notice that you could first find the maximum m value for which a solution exists using a binary search on m in which you solve a decision problem at each step, and then, once this maximal m value has been found, solving a series of decision problems in which each combination in turn is removed: if the solution after removing some particular combination is still "YES", then it may also be left out of all future problem instances, while if the solution becomes "NO", then it is necessary to keep this combination in the solution.)
Given an instance (X, Y, Z, T, k) of 3DM, where X, Y and Z are sets that are pairwise disjoint from each other, T is a subset of X*Y*Z (i.e., a set of ordered triples with first, second and third components from X, Y and Z, respectively) and k is an integer, our task is to determine whether there is any subset U of T such that |U| >= k and all triples in U are pairwise disjoint (i.e., to answer the question, "Are there at least k non-overlapping triples in T?"). To turn any such instance of 3DM into an instance of your problem, all we need to do is create a fresh 4-combination from each triple in T, by adding a distinct dummy value to each. The set of objects in the constructed instance of your problem will consist of the union of X, Y, Z, and the |T| dummy values we created. Finally, set m to k.
Suppose that the answer to the original 3DM instance is "YES", i.e., there are at least k non-overlapping triples in T. Then each of the k triples in such a solution corresponds to a 4-combination in the input C to your problem, and no two of these 4-combinations overlap, since by construction, their 4th elements are all distinct, and by assumption of the. Thus there are at least m = k non-overlapping 4-combinations in the instance of your problem, so the solution for that problem must also be "YES".
In the other direction, suppose that the solution to the constructed instance of your problem is "YES", i.e., there are at least m non-overlapping 4-combinations in C. We can simply take the first 3 elements of each of the 4-combinations (throwing away the fourth) to produce a set of k = m non-overlapping triples in T, so the answer to the original 3DM instance must also be "YES".
We have shown that a YES-answer to one problem implies a YES-answer to the other, thus a NO-answer to one problem implies a NO-answer to the other. Thus the problems are equivalent. The instance of your problem can clearly be constructed in polynomial time and space. It follows that your problem is NP-hard.
You can reduce this problem to the maximum weighted clique problem, which is, unfortunately, NP-hard.
Build a graph such that every combination is a vertex with weight equal to the length of the combination, and connect vertices if the corresponding combinations do not share any object (i.e. if you can pick both them at the same time). Then, a solution is valid if and only if it is a clique in that graph.
A simple search on google brings up a lot of approximation algorithms for this problem, such as this one.
Edit: Now I think this is a sweep line problem. (see update2 at the bottom)
In this problem we are given N objects and M constraints. (N can be 200k, M can be 100k). Each object is either black, or white. Each constraint is in the form (x, y) and means that in the range of objects x..y, there is exactly one white object; the rest are black. We would like to determine the maximum number of white objects that can exist, or if it isn't possible to satisfy the constraints.
I observe that if a constraint is fully contained in another, the inner constraint will dictate where a white object can be placed. Also, if there are several non-intersecting constraints contained within another, it should be impossible since it violates the fact that there can only be one white object per constraint. The algorithm should be fast enough to run under 2-3 seconds.
Update: One of the answers mentions the exact cover problem; is this a specialized instance that isn't NP-complete?
Update2: If we change each constraint into a begin and end event, and sort these events, could we just systematically sweep across these events and assign white objects?
You problem can be expressed as an exact cover problem: the constraint intervals form the set to be covered, and each white object covers those constraint intervals which it falls inside of. Your problem, then, is to find a subset of the white objects which covers each constraint interval exactly once.
Exact cover problems in general are NP-complete, although that obviously doesn't necessarily mean that any specific subset of them are. However, there nonetheless exist algorithms, such as Knuth's Algorithm X (as implemented by dancing links) that can solve most such problems quite efficiently.
It's possible that the one-dimensional structure of your problem might also allow more straightforward specialized solution methods. However, Algorithm X is a very good general tool for attacking such problems. (For example, the fastest sudoku solvers typically use something like it.)
Yes, there's a (point)-sweep algorithm. This one is sort of inelegant, but I think it works.
First, sweep for nested intervals. Process begin and end events in sorted order (tiebreakers left to you) and keep a list of active intervals not known to contain another interval. To handle a begin event, append the corresponding interval. To handle an end event, check whether the corresponding interval I has been removed. If not, remove I and all of the remaining intervals J before I from the list. For each such J, append two intervals whose union is the set difference J \ I to a list of blacked out intervals.
Second, sweep to contract the blacked out intervals. In other words, delete the objects known to be black, renumber, and adjust the constraints accordingly. If an entire constraint is blacked out, then there is no solution.
Third, sweep to solve the problem on what are now non-nested intervals. The greedy solution is provably optimal.
Example: suppose I have half-open constraints [0, 4), [1, 3), [2, 5). The first sweep creates blackouts [0, 1) and [3, 4). The second sweep leaves constraints [a, c), [a, c), [b, d).* The greedy sweep places white objects at new locations a, c, d (old locations 1, 4, 5).
Illustration of the second sweep:
0 1 2 3 4 5 old coordinates
[ )
[ )
[ )
** ** blackouts
a b c d new coordinates
[ )
[ )
[ )
I need to write something like a minesweeper in prolog. I am able to do that in "normal" language but when i try to start coding with prolog i totally don't know how to start.
I need some sort of tips.
Input specification:
Board size: m × n (m, n ∈ {1,...,16}), list of triples (i, j, k), where i ∈ {1,...,m}, j ∈ {1,...,n}, k ∈ {1,...,8}) describing fields with numbers.
For example:
5
5
[(1,1,1), (2,3,3), (2,5,2), (3,2,2), (3,4,4), (4,1,1), (4,3,1), (5,5,2)].
Output: list of digits and the atoms * (for treasure) and (for blank fields). It is a representation of puzzle solution.
Rules of this puzzle:
In 20 fields of a board there are hidden treasures. A digit in a field represents how many neighbour-fields have a treasure. There are no treasures in fields with a digit. Mark all fields with a treasure.
You need to guess how many treasures are hidden in diagonals.
I would be grateful for any tips. I don't want full solution, I want to write it by my own, but without clues I am not able to do that.
A matrix is usually handled as a list of list, you can build using length/2 and findall/3. A matrix of empty variables (where you will place values while guessing....)
build_matrix(NRows, NCols, Mat) :-
findall(Row, (between(1, NRows, _), length(Row, NCols)), Mat).
Accessing elements via coordinates can be done using nth1 (see here for another answer where you can find some detail: see cell/3).
Then you place all your triples constraints: there is finite number of ways of consuming the 'hidden treasure' counters, let Prolog search all the ways, enumerating adjacents.
Process the list of triples, placing each counter in compatible cells, with a recursive predicate. When the list ends, you have a guess.
To keep your code simpler, don't worry about indexes out of matrix bounds, remember that failures are 'normal' when searching...
I have a set of n real numbers. I also have a set of functions,
f_1, f_2, ..., f_m.
Each of these functions takes a list of numbers as its argument. I also have a set of m ranges,
[l_1, u_1], [l_2, u_2], ..., [l_m, u_m].
I want to repeatedly choose a subset {r_1, r_2, ..., r_k} of k elements such that
l_i <= f_i({r_1, r_2, ..., r_k}) <= u_i for 1 <= i <= m.
Note that the functions are smooth. Changing one element in {r_1, r_2, ..., r_k} will not change f_i({r_1, r_2, ..., r_k}) by much. average and variance are two f_i that are commonly used.
These are the m constraints that I need to satisfy.
Moreover I want to do this so that the set of subsets I choose is uniformly distributed over the set of all subsets of size k that satisfy these m constraints. Not only that, but I want to do this in an efficient manner. How quickly it runs will depend on the density of solutions within the space of all possible solutions (if this is 0.0, then the algorithm can run forever). (Assume that f_i (for any i) can be computed in a constant amount of time.)
Note that n is large enough that I cannot brute-force the problem. That is, I cannot just iterate through all k-element subsets and find which ones satisfy the m constraints.
Is there a way to do this?
What sorts of techniques are commonly used for a CSP like this? Can someone point me in the direction of good books or articles that talk about problems like this (not just CSPs in general, but CSPs involving continuous, as opposed to discrete values)?
Assuming you're looking to write your own application and use existing libraries to do this, there are choices in many languages, like Python-constraint, or Cream or Choco for Java, or CSP for C++. The way you've described the problem it sound like you're looking for a general purpose CSP solver. Are there any properties of your functions that may help reduce the complexity, such as being monotonic?
Given the problem as you've described it, you can pick from each range r_i uniformly and throw away any m-dimensional point that fails to meet the criterion. It will be uniformly distributed because the original is uniformly distributed and the set of subsets is a binary mask over the original.
Without knowing more about the shape of f, you can't make any guarantees about whether time is polynomial or not (or even have any idea of how to hit a spot that meets the constraint). After all, if f_1 = (x^2 + y^2 - 1) and f_2 = (1 - x^2 - y^2) and the constraints are f_1 < 0 and f_2 < 0, you can't satisfy this at all (and without access to the analytic form of the functions, you could never know for sure).
Given the information in your message, I'm not sure it can be done at all...
Consider:
numbers = {1....100}
m = 1 (keep it simple)
F1 = Average
L1 = 10
U1 = 50
Now, how many subset of {1...100} can you come up with that produces an average between 10 & 50?
This looks like a very hard problem. For the simplest case with linear functions you could take a look at linear programming.
I'm looking for a way to transform a set, and having trouble. This is because the requirements are rather rigorous.
Set A contains a bunch of integers, the details are really irrelevant.
Set B contains a bunch of integers, such that:
Each value in A directly maps to one and only one value in B.
Each bit is true in one, and only one, value in B.
The sum of any N values in B has a strict relation to (the sum of) it's original values in A. This relation may not depend on knowing the actual N values in question, although other things like knowing the number of values summed is fine.
It's mainly a thought exercise rather than an actual implementation, so detailing the realities of, for example, the memory constraints which would grow hugely with the size of A.
For example, you could satisfy the first two requirements by simply saying that B[i] = 2^A[i]. But that's not useful, because if you did 2^x = 2^A[i] + 2^A[j], you can't infer that the sum of A[i] and A[j] is x or some other expression which does not involve A[i] or A[j].
I'm tending towards such a transformation being impossible, but thought I'd throw it out there just in case.
Edit: I've been unclear. Sorry. This idea exists mainly in my head.
I already know the sum of the B values. The problem is that I start with the sum of the B values and find the values in B which sum to it, which is trivial due to the unique-bits restriction. The trouble is that the sum is initially expressed in A values, so I have to be able to transform the sum from a sum of A values to a sum of B values. This is useless to me if I have to transform it separately for every possible sum because the transformation depends on the values I'm summing.
More edit: Also, my reverse mechanism from B[i] to A[i] is a lookup table. Don't need an actual existent mathematical function. Any A[i] is unique from any other A[j].
I think your third constraint poses a problem. When you say A is one-to-one onto B, that means there exists an invertible mapping F: A->B and its inverse F': B->A such that F'(F(x))=x. Now, "the sum of any N values in B has a strict relation to the sum of the original values in A". This means that there exists some G such that G(A_1+A_2+...+A_n)=B_1+B_2+...+B_n; the sum of the B-values are related to the A-values. But, because of the first clause, we've established that A_1=F'(B_1), so "knowing the actual N values in question" (A_1 through A_n, although your original question leaves it ambiguous to which values you refer) is the same as "knowing" the B-values, due to the one-to-one correspondence. Thus it is not possible to satisfy constraints one and three simultaneously for a finite set of integers; if you are instructed to "sum these n B-values", you must already know the A-values - just apply the inverse transform.
Given (A_1 + ... + A_n), can we assume each A_i is unique? If not, the problem is impossible: adding A_1 to itself A_2 times gives the same result as adding A_2 to itself A_1 times. If each A_i IS unique, then what are we allowed to assume about the bijection between A and B? For example, if N is known, then A[i] = B[i] + d is trivially reversible for all d. Even if we can assume each A_i in the sum is unique, the problem of recovering the B_i is possible if (and only if) no two subsets of A sum to the same value. How easily the B_i can be recovered depends on the nature of the bijection.
The trouble is that the sum is
initially expressed in A values, so I
have to be able to transform the sum
from a sum of A values to a sum of B
values.
That translates to finding the A values from a sum of A values, which I don't think is possible if the A values are arbitrary.
EDIT: The way you described it, this problem appears to be the subset sum problem, which is NP-complete. You can use dynamic programming to improve its performance, but I don't know if you can go much beyond that.