If a tree has k arcs, how many nodes does it have?
Base case:
If k=0 => n=(k+1)=1
Inductive hypothesis: For every k, n=(k+1) is true
Proof:
Is it true for k=1?
k=n-1
1=n-1
1=(k+1)-1
k=1,so:
1=1+1-1
1=1
Proved?
Am I missing something?
You never want to use 0 or 1 as your base case for proof by induction
If k=0 => n=(k+1)=1
You can prove anything you want if you use 0 (or often 1) as your base case. The classic example of this being that all horses are the same color. This is your mistake.
In addition, you can make graphs with the same number of arcs have different numbers of nodes, which immediately shows that you are not going to be able to use proof by induction to solve your problem.
Good luck!
Related
I am trying to understand Bellman Equation and facing with some confusing moments.
1) In different sources I met different definitions of Bellman Equation.
Sometimes it is defined as value-state function
v(s) = R + y*V(s')
Sometimes it is defined as action-state function
q(s, a) = r + max(q(s', a'))
Are both of these definitions correct? How Bellman equation was introduced in the original paper?
Bellman equation gives a definite form to dynamic programming solutions and using that we can generalise the solutions to optimisations problems which are recursive in nature and follow the optimal substructure property.
Optimal substructure in simpler terms means that the given problem can be broken down into smaller sub problems which require the same solution with smaller data. If an optimal solution to the smaller problem can be computed then it means the given problem (larger one) can also be computed.
Let's denote the problem solution for given state S by value V(S), S is the state or the subproblem. Let's denote the cost that would incur by choosing action a(i) at state S be R. R will be a function f(S, a(i)), where a is the set of all possible actions that can be performed on state S.
V(S) = max{ f(S, a(i)) + y * V(S') } where max is taken by iterating over all possible i. y is a fixed constant that taxes the subproblem to bigger problem transition, for most problems y = 1, so you can ignore it for now.
So basically at any given sub-problem S, V(S) will give us the most optimal solution by choosing all combinations of actions a(i) that can be performed and the next state that will be created with that action. If you think recursively and are habitual to such stuff then it's easy to see why the above equation is correct.
I would suggest to solve dynamic programming problems and look at some standard problems and their solutions to get an idea how those problems are broken down into smaller similar problems and solved recursively. After that, the above equation will make more sense. Also, you will realise that two equations you have written above are almost the same thing, just they are written in a bit different manner.
Here is a list of more commonly known DP problems and their solutions.
I understand the target approach for both the methods where Optimal Substructure calculates the optimal solution based on an input n while Overlapping Subproblems targets all the solutions for the range of input say from 1 to n.
For a problem like the Rod Cutting Problem. In this case while finding the optimal cut, do we consider each cut hence it can be considered as Overlapping Subproblem and work bottom-up. Or do we consider the optimal cut for a given input n and work top-down.
Hence, while they do deal with the optimality in the end, what are the exact differences between the two approaches.
I tried referring to this Overlapping Subproblem, Optimal Substructure and this page as well.
On a side note as well, does this relate to the solving approaches of Tabulation(top-down) and Memoization(bottom-up)?
This thread makes a valid point but I'm hoping if it could be broken down easier.
To answer your main question: overlapping subproblems and optimal substructure are both different concepts/properties, a problem that has both these properties or conditions being met can be solved via Dynamic Programming. To understand the difference between them, you actually need to understand what each of these term means in regards to Dynamic Programming.
I understand the target approach for both the methods where Optimal Substructure calculates the optimal solution based on an input n while Overlapping Subproblems targets all the solutions for the range of input say from 1 to n.
This is a poorly worded statement. You need to familiarize yourself with the basics of Dynamic Programming. Hopefully following explanation will help you get started.
Let's start with defining what each of these terms, Optimal Substructure & Overlapping Subproblems, mean.
Optimal Substructure: If optimal solution to a problem, S, of size n can be calculated by JUST looking at optimal solution of a subproblem, s, with size < n and NOT ALL solutions to subproblem, AND it will also result in an optimal solution for problem S, then this problem S is considered to have optimal substructure.
Example (Shortest Path Problem): consider a undirected graph with vertices a,b,c,d,e and edges (a,b), (a,e), (b,c), (c,d), (d,a) & (e,b) then shortest path between a & c is a -- b -- c and this problem can be broken down into finding shortest path between a & b and then shortest path between b & c and this will give us a valid solution. Note that we have two ways of reaching b from a:
a -- b (Shortest path)
a -- e -- b
Longest Path Problem does not have optimal substructure. Longest path between a & d is a -- e -- b -- c -- d, but sum of longest paths between a & c (a -- e -- b -- c) and c & d (c -- b -- e -- a -- d) won't give us a valid (non-repeating vertices) longest path between a & d.
Overlapping Subproblems: If you look at this diagram from the link you shared:
You can see that subproblem fib(1) is 'overlapping' across multiple branches and thus fib(5) has overlapping subproblems (fib(1), fib(2), etc).
On a side note as well, does this relate to the solving approaches of Tabulation(top-down) and Memoization(bottom-up)?
This again is a poorly worded question. Top-down(recursive) and bottom-up(iterative) approaches are different ways of solving a DP problem using memoization. From the Wikipedia article of Memoization:
In computing, memoization or memoisation is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again.
For the given fibonacci example, if we store fib(1) in a table after it was encountered the first time, we don't need to recompute it again when we see it next time. We can reuse the stored result and hence saving us lot of computations.
When we implement an iterative solution, "table" is usually an array (or array of arrays) and when we implement a recursive solution, "table" is usually a dynamic data structure, a hashmap (dictionary).
You can further read this link for better understanding of these two approaches.
I'm trying to model Conway's game of life rules using integer linear programming, however I'm stuck with one of the rules.
I consider a finite n x n grid. Each cell in the grid is associated with a variable X(i,j) whose value is 0 if the cell is dead and 1 if it is alive.
I'm particularly interested in still lifes, i.e. configurations that, according to the rules, don't change from an instant to the next.
To find them I'm imposing the constraints on the number of neighbours for each cell. So, for an alive cell to remain still it must have 2 or 3 neighbours, and this is easily expressible:
2(1-X(i,j)) + Σ(i,j) >= 2
-5(1 - X(i,j)) + Σ(i,j) <= 3
Where Σ(i, j) is the sum over the neighbours of (i, j) (assume outside of the grid the values are all 0s).
If X(i,j) == 0 then the first addend guarantees that the the constraints are trivially satisfied. When X(i, j) == 1 the constraints guarantee that we have a still life.
The problem is the other rule: for a dead cell to remain dead it must have any number of neighbours different from 3.
However, AFAIK you cannot use != in a constraint.
The closest I've come is:
X(i, j) + |Σ(i, j) - 3| > 0
Which does express what I want, but the problem is that I don't think the absolute value can be used in that way (only absolute values of single variables can be expressed. Or is there a way to express this particular situation?).
I wonder, is there a standard way to express the !=?
I was thinking that maybe I should use multiple inequalities instead of a single one (e.g. for every possible triple/quadruple of neighbours...), but I cannot think of any sensible way to achieve that.
Or maybe there is some way of abusing the optimization function to penalize this situation and thus, obtaining an optimum would yield a correct solution (or state that it's impossible, depending on the value).
Is anyone able to express that constraint using a linear inequality and the variables X(i, j) (plus, eventually, some new variables)?
The standard way to express
is to express it as
by introducing a new binary variable that indicates which inequality holds true.
This is explained here, at section 7.4.
In a nutshell, if we define y such that
then we need to add the constraints
Where
This is the standard way to model this, but in specific applications there might be better ways. Usually, the tighter the bounds on the sum are, the best the solver performance.
I am having tough time in understanding the logic behind this problem,
This is classical Dynamic Programming Problem
Coin Change is the problem of finding the number
of ways of making changes for a particular amount of cents, n,
using a given set of denominations d1,d2,..dm;
I know how the recursion works,Like taking the mth coin or not.But I don't understand what does '+' do between the two states.
For eg
C(N,m)=C(N,m-1)+C(N-dm,m)
^
|
Question might be stupid but I still would like to know so that I can have better understanding.Thanks
Well , you haven't written your state right!
Coin Change:
Let C(i,j) represents the number of ways to form j as a sum using only i coins (from i to 1).
Now to get a recursive function you have to define transitions or change in state or may be just expressing the given expression in the terms of lower values!!
There are 2 independent ways in which I can represent this state that are
1) Lets pick up the i th coin , Then what happens ? I need denomination j-Denomination[i] with i-1 coins if repetition is not allowed .
i.e. C(i,j)= C(i-1,j-Denominations[i])
But wait , we are missing some ways i.e. when we do not take the current coin
2) C(i,j)=C(i-1,j)
Now as both of them are independent and exhaustive , These both of these state makes up the total number of ways!!!
C(i,j)=C(i-1,j)+C(i-1,j-Denominations[i])
I will leave the recurrence when repetition allowed for you!
I am using HASKELL for graph games. I am willing to get a suitable method for reach ability from a node to a particular node in the graph apart from using bfs or trees etc.
As I asked for code in haskell for reach ability from one node to a particular node, it is necessary to tell you that I am totally new to haskell. I have been reading the tutorials and simple examples, but when it come to implementation then I am lost. My graph is a directed graph, and say I want to check whether I can reach from node v to node w in graph.
From Data.Graph:
reachable :: Graph -> Vertex -> [Vertex]
To search the Haskell API and libraries:
http://www.haskell.org/hoogle/
http://holumbus.fh-wedel.de/hayoo/hayoo.html
Try representing your graph as a matrix where a 1 represents an edge.
E.g.:
Node/Node A B C D
A 0 0 1 1
B 0 0 1 1
C 0 0 1 0
D 1 0 1 0
For directed graphs the order of the matrix indices matters, for undirected graphs they don't. The above being a directed graph where there is an edge from D->C but not from C->D.
There are several All pair shortest path algorithms in hand. For small graphs, wikipedia says:
Floyd-Warshall algorithm is an
elegant, quickly implementable O(n3)
algorithm (Assumes absence of
negatively-weighed cycles).
EDIT: Are you looking for a ready-made Haskell code?
Not entirely sure what your question is, in the context of Haskell.
Are you asking for readymade implementations of the required algorithms + data structures?
Looking for libraries for graphs in Haskell?
Either way, check http://hackage.haskell.org for graph-related packages:
http://hackage.haskell.org/package/fgl
http://hackage.haskell.org/package/graphviz
http://hackage.haskell.org/package/Graphalyze
http://hackage.haskell.org/package/GraphSCC
http://hackage.haskell.org/package/hgal