How to prove that admissible/consistent heuristics in A* searching method would lead to optimal solution? - graph-algorithm

we have proved in class that if A* in Tree-Search is optimal, then h(n) is admissible(Admissible Heuristics). If using A* in Graph-Search finds the optimal solution, then h(n) is consistent. We proved the properties of admissible and consistent if we assume that A* can find the optimal solution. This indicates that consistent /admissible are necessary conditions for optimality in Graph/Tree Searching.
However, I am not too sure how to prove that they are also both sufficient conditions as well. I tried to figure it out, but I still could not find a good way to prove it. For example, I am not too sure how to prove that being admissible can lead to optimality in Tree-Searching using A*? And similarly, how to prove that being consistent can lead to optimality in Graph-Searching using A*? Thank you in advance!
This is my first time asking on StackOverflow, sorry if I am not phrasing my question well. : )Thank you in advance!

This indicates that consistent /admissible are necessary conditions for optimality in Graph/Tree Searching.
No, it implies they're sufficient conditions. In fact, the converse is not true - it is possible to find cases where a given non-admissible heuristic returns the optimal result for a specific graph (simple counter-example: a tree with only one path will return the optimal path for any heuristic). Thus they are not necessary conditions.
As a side note, 'consistent' implies 'admissible', and trees are a type of graph, so it is enough to prove the "admissible + graph" case, and all four cases (admissible/consistent, tree/graph) are immediately implied.

Related

z3 alternative for Gecode branch() function?

In constraint solver like Gecode , We can control the exploration of search space with help of branching function. for e.g. branch(home , x , INT_VAL_MIN ) This will start exploring the search space from the minimum possible value of variable x in its domain and try to find solution.(There are many such alternatives .)
For z3, do we have this kind of flexibility in-built ?? Any alternative possible??
SMT solvers usually do not allow for these sorts of "hints" to be given, they act more as black-boxes.
Having said that, each solver uses a ton of internal heuristics, and z3 itself has a number of settings that you can play with to give it hints. If you run:
z3 -pd
it will display all the options you can provide, and there are literally over 600 of them! Unfortunately, these options are not really well documented, and how they impact the solver is rather cryptic. The only reliable way to find out would be to study the source code and see what they do, which isn't for the faint of heart. But in any case, it will not be as obvious as the branch feature you cite for gecode.
There are, however, other tricks one can use to speed up solving for SMT-solvers, unfortunately, these things are usually very problem-specific. If you post specific instances, you might get better suggestions.

How to understand what z3 is doing when it loops?

I'm having trouble figuring out how to debug z3. Is there a way to see what the SMT engine is "trying" to make it easier to understand why it's failing to see a solution that seems obvious and where it's devoting it's time instead?
As an example in my particular circumstance, I'm working with a recursive function and setting z3 to find inputs where the function has a certain result. SMT was timing out, yadda yadda yadda, turns out the thing I was recursing on had a base case of 0, but if it ever went negative, it'd recurse forever. Z3 didn't know not to pick a negative number, so it'd get stuck. I figured that out by staring at the code, but if I had some output somewhere that said "trying i == -10, trying i == -11, etc" it'd be very obvious what was going wrong.
I'm continuing to have less obvious issues, and I suspect Z3 is still getting stuck in loops. How can I see the loop it's getting stuck in?
It is unfortunately very difficult to find out why exactly Z3 is running forever, but typical culprits are matching loops due to bad patterns (a quantifier instantiations yields new ground terms that trigger another instantiations, and so on) and non-linear arithmetic.
The Z3 axiom profiler, described in this paper can help with identifying problems due to too many quantifier instantiations.

What is pb.conflict in Z3?

I am trying to find an optimal solution using the Z3 API for python. I have used set_option("verbose", 1) to print statements that Z3 generates while checking for sat. One of the statements it prints is pb.conflict statements. The statements look something like this -
pb.conflict statements.
I want to know what exactly is pb.conflict. What do these statements signify? Also, what are the two numbers that get printed along with it?
pb stands for Pseudo-boolean. A pseudo-boolean function is a function from booleans to some other domain, usually Real. A conflict happens when the choice of a variable leads to an unsatisfiable clause set, at which point the solver has to backtrack. Keeping the backtracking to a minimum is essential for efficiency, and many of the SAT engines carefully track that number. While the details are entirely solver specific (i.e., those two numbers you're asking about), in general the higher the numbers, the more conflict cases the solver met, and hence might decide to reset the state completely or take some other action. Often, there are parameters that users can set to specify when such actions are taken and exactly what those are. But again, this is entirely solver and implementation specific.
A google search on pseudo-boolean optimization will result in a bunch of scholarly articles that you might want to peruse.
If you really want to find Z3's treatment of pseudo-booleans, then your best bet is probably to look at the implementation itself: https://github.com/Z3Prover/z3/blob/master/src/smt/theory_pb.cpp

Performance issues with z3py using modulo and optimization

I'm experimenting with Z3 (using the python api) where I'm building up a scheduling model for a class assignment, where I have to use modulo quite often (because its periodic). Modulo seems already to slow down z3 by a lot, but if I try do some optimization on top (minimize a cost function which is a sum), then it takes quite some time for fairly small problems.
Without optimization it works okayish (few seconds for a smaller problem). So that being said, I have now 2 questions:
1) Is there any trick with the modulo function of how to use it? I already assign the modulo value to a function. Or is there any other way to express periodic/ring behavior?
2) I am not interested in finding THE best solution. A good one, will be good enough. Is there a way to set some bounds for the cost function. Like, if know the upper and lower bound of it? Any other tricks, where I could use domain knowledge to find solutions fast.
Furthermore, I thought that if I ll use timeout option solver.set("timeout" 10000), then the solver would time out with the best solution so far. That doesnt seem to be the case. It just times out.
Impossible to comment on the mod function without seeing some code. But as a rule of thumb, division is difficult. Are you using Int values, or bit-vectors? If you are using unbounded integers, you might want to try bit-vectors which might benefit from better internal heuristics. Or try Real values, and then do a proper reduction.
Regarding how to get the "best so far" optimal value, see this answer: Finding suboptimal solution (best solution so far) with Z3 command line tool and timeout
Instead of using the built-in modulo and division, you could introduce uninterpreted functions mymod and mydiv, for which you only provide the necessary axioms of division and modulo that your problem requires. If I remember correctly, Microsoft's Ironclad and/or Ironfleet team did that when they had modulo/division-related performance problems (using the pipeline Dafny -> Boogie -> Z3).

Quicksort vs Mergesort in terms of comparisons

First of all, I have done searching before posting this question. I've looked at the question at Why is quicksort better than mergesort? but it has a few contradictory answers.
Depending on where I look, people say quicksort is "faster" than mergesort due to its locality of reference, cache hits etc. Now, I accept this is important in practice but my question is purely about analysis - I'm not interested in recursion overhead, cache issues and the like. In addition answers are often vague as to what they mean when they say faster, I'm not sure if they're referring to time taken to execute and as such if cache issues are relevant to their answers.
Anyway, my question is simple. Purely in terms of the number of comparisons performed, is mergesort always more efficient than quicksort? Wikipedia tells me yes, which is what I've always thought, but as I said, other people say different things.
Basic Quicksort, in the worst case, will run in O(n^2) time. Consider if the the pivot chosen is always the next smallest element, it is equivalent to Insertion sort. Mergesort doesn't have this difficulty.
Further, Mergesort is also stable, which means it preserves the order of equally valued elements (so it's good for sorting "first by this, then by that"), where's Quicksort is not.
The biggest drawback to Mergesort is that most implementations must be done with 2n space, whereas Quicksort can be done in-place (in case space is a problem in your application).
The individual wikipedias on both Quicksort and Mergesort are excellent, I recommend reading them.

Resources