What are does the gray squares represent in MiniZinc? - visualization

In Minizinc while visualising the execution tree (created via Profile search) I obtain a tree containing gray square.
What do they represent ?

The gray squares are back-jumps. They are parts of the tree for which the solver was able to prove no solution would be present.
In a general constraint programming solver, the solver performs a tree search. Whenever you find that one branch doesn't contain any solutions, you go to another branch. Traditionally, there are two branches for every search decision. For example, a value assignment and its negation. But it is also possible to create a branch for every possible value that the variable can take.
In Lazy Clause Generation solvers, search works a bit differently. Whenever you find that search failed, you let the SAT backend generate a reason, generally referred to as a "no-good". This no-good explains why this branch didn't contain any solutions, and can from then on be enforced as a new constraint. If you just revisit your last decision, then this new constraint might still be violated. Instead, these LCG solvers use a back-jump mechanism to jump up to the last decision where the no-good was not yet violated.

Related

Implementating spell drawing/casting mechanism in Luau (Roblox)

I am coding a spell-casting system where you draw a symbol with your wand (mouse), and it can recognize said symbol.
There are two methods I believe might work; neural networking and an "invisible grid system"
The problem with the neural networking system is that It would be (likely) suboptimal in Roblox Luau, and not be able to match the performance nor speed I wish for. (Although, I may just be lacking in neural networking knowledge. Please let me know whether I should continue to try implementing it this way)
For the invisible grid system, I thought of converting the drawing into 1s and 0s (1 = drawn, 0 = blank), then seeing if it is similar to one of the symbols. I create the symbols by making a dictionary like:
local Symbol = { -- "Answer Key" shape, looks like a tilted square
00100,
01010,
10001,
01010,
00100,
}
The problem is that user error will likely cause it to be inaccurate, like this "spell"'s blue boxes, showing user error/inaccuracy. I'm also sure that if I have multiple Symbols, comparing every value in every symbol will surely not be quick.
Do you know an algorithm that could help me do this? Or just some alternative way of doing this I am missing? Thank you for reading my post.
I'm sorry if the format on this is incorrect, this is my first stack-overflow post. I will gladly delete this post if it doesn't abide to one of the rules. ( Let me know if there are any tags I should add )
One possible approach to solving this problem is to use a template matching algorithm. In this approach, you would create a "template" for each symbol that you want to recognize, which would be a grid of 1s and 0s similar to what you described in your question. Then, when the user draws a symbol, you would convert their drawing into a grid of 1s and 0s in the same way.
Next, you would compare the user's drawing to each of the templates using a similarity metric, such as the sum of absolute differences (SAD) or normalized cross-correlation (NCC). The template with the lowest SAD or highest NCC value would be considered the "best match" for the user's drawing, and therefore the recognized symbol.
There are a few advantages to using this approach:
It is relatively simple to implement, compared to a neural network.
It is fast, since you only need to compare the user's drawing to a small number of templates.
It can tolerate some user error, since the templates can be designed to be tolerant of slight variations in the user's drawing.
There are also some potential disadvantages to consider:
It may not be as accurate as a neural network, especially for complex or highly variable symbols.
The templates must be carefully designed to be representative of the expected variations in the user's drawings, which can be time-consuming.
Overall, whether this approach is suitable for your use case will depend on the specific requirements of your spell-casting system, including the number and complexity of the symbols you want to recognize, the accuracy and speed you need, and the resources (e.g. time, compute power) that are available to you.

Rare question about interaction terms, main effects, and mean-centering - mix & match?

This question is not about the longstanding discussion of 'to mean-center, or not mean-center' interaction terms, or what mean-centering the variables in an interaction gets you (or doesn't get you).
The question is if it is reasonable to have a model that includes an uncentered predictor serving to model a main effect (e.g. Education's effect on income), and an interaction term that is computed by multiplying a mean-centered version of that variable with another term (say, gender, to see if the education effect on income is conditional on gender), while leaving the 'standalone' education variable on its original scale.
For the sake of keeping the focus on this rare combination of an uncentered version of a variable with an interaction that is based on a centered version of the same variable in the same model, let's ignore the reasons for doing this (i.e. interpretability vs. collinearity).
Everything I can find about these issues seems to always assume that either all versions of the variables (as an individual variable/main effect, and as a part of the interaction/product term) are either centered or uncentered. Hence the labeling of this as a 'rare question' about mean-centering and interactions.
My instinct is that this (mixing and matching centered and uncentered) is problematic because, despite the linear similarities between the centered and uncentered versions, you end up with a model where one of the components of the interaction is technically absent. But this may also be just because I am not a fan of arguments - still common in a lot of places - that collinearity is the reason to mean-center.
What do people here think?

What does the impact search annotation do in MiniZinc?

In MiniZinc it is possible to use the search annotation impact, it is explained as follows on the official website:
annotation impact
Choose the variable with the highest impact so far during the search
What does this mean in practice? What is the highest impact? How is this calculated?
To understand the impact based variable selection, you have to understand first_fail. In constraint programming we generally want to solve the hardest sub-problem first, failing quickly if no solution can be found. The problem with first_fail is that it doesn't take into account the number of constraints that a variable is involved in, more would indicate that the a decision for the variable "harder", or the effect that choices on the variable had in other parts of the search-tree.
As a sidenote, dom_w_deg is can be seen as compromise between first_fail and impact, where the constraints are taken into account, but the past decision are not.
impact variable selection is supposed to be an improvement on first_fail where not just domain sizes are considered, but also the constraints it's involved in and how much "impact" historical choices had. The variable with the highest impact is the one that is expected to be the hardest to assign the right value, taking all of this information into account.
As you've seen, MiniZinc does not provide an exact specification of how the variable choice has to made. It is up to solver implementer to select a heuristic that fit the solver. Note that it would be hard to provide an exact heuristic guideline as it would heavily depend on how the solver tracks its variables and constraints.
For ideas on possible implementations of impact based heuristics, I would suggest reading the paper "On the Efficiency of Impact Based Heuristics" by Marco Correia and Pedro Barahona. You can also check your specific MiniZinc/FlatZinc solver for their implementation of the heuristic.

Sampling search domain

In Minizinc, is it possible to sample the domain ? lets say my domain has many solutions, running --all-solutions will initially return very similar solutions.
1) is there a way to sample the domain ? perhaps BFS ? the purpose is for follow up solutions analysis.
2) Is there any methods to estimate search domain size in CP?
my domain is a Staff Rostering Problem
Regards,
H
It is not possible to choose BFS in MiniZinc but there is search annotations. With the search annotations you can choose in which order the variables should be branched on. You can also choose which value will be branched on. Unfortunately, MiniZinc does not support random variable search.
In your case I would branch on a dom_w_deg with a random value but any other variable selection can work, try them.
solve::seq_search([int_search(some_array, dom_w_deg, indomain_random,complete)]) satisfy;
Do note that not all solvers support the usage of search annotations.
Other alternatives are to add constraints that remove the similar results.
You can always calculate the number of permutations you can have in your solution, the number of variables multiplied with their domain. This will not consider any constraints and the real search space can be much smaller.
Another way of visualizing the search is by using gist or other programs to visualize the search.
(source: marco at www.imada.sdu.dk)
You can expand and retract parts of the search tree and see which variables have been branched on.

Does heuristics in constraint satisfaction problems ensure no backtracking? (when there exists a solution)

I'm doing a map-coloring problem with Scheme, and I used minimum remaining values (Select the vertex with the fewest legal colors) and degree heuristics select the vertex that has the largest number of neighbors). If there exists a solution for a certain configuration, will these heuristics ensures that it won't need to backtrack?
Let's do a simple theoretical analysis.
Graph coloring is NP-complete for general graphs (if not asking for a coloring with less than 4 colors). This means there exists no known polynomial time algorithm.
Your heuristic is computable in polynomial time.
Assuming you need no backtracking, then you need to make n steps, each of which requires polynomial time (n is number of vertices). Thus you can solve the problem in polynomial time.
Either you have proven P=NP or your assumption is wrong.
I leave it up to you to decide upon which option in point (4) is more plausible.
In general: no, MRV and your other heuristic will not guarantee a straight walk to the goal. (I imagine they might if your problem has some very specific structure, but don't count on it until you've seen the theorem.)
Heuristics prune the search space, or change the order of the search to make an early termination more likely. This is not the same thing as backtracking.
But it's a related concept.
We prune some spaces because we are confident that the solution does not lie in those branches of the search tree, or change the order because we have some reason to believe that it will be quicker if we look in some subtrees before others.
We also cut ourselves off from backtracking because we are confident that the solution is in the branch of the space we are in now (so that if we don't find it in this subtree, we can declare failure and don't bother).
Both kinds of strategies are ultimately about searching less of the space somehow and getting to the answer (positive or negative) without searching everything.
MRV and the degrees heuristic are about reordering the sub-searches, not about avoiding backtracking. Heuristics can be right and make a short search but that's not the same
thing as eliminating backtracking (e.g. the "cut" operator in Prolog). When you find what you're looking for, you can declare success, and of course that eliminates further backtracking. But real backtracking elimination means making a decision not to backtrack no matter what, before the search completes.
E.g. if you're doing a depth-first search, and you find what you're looking for by dumb luck without backtracking, we cannot say that dumb luck is a fence operation that eliminates backtracking. :)