Construct a DFA for the following language: all strings that have at least three 0s and at most two 1s - finite-automata

I am to construct a DFA from the intersection of two simpler DFAs. The first simpler DFA recognizes languages of all strings that have at least three 0s, and the second simpler language DFA recognizes languages of strings of at most two 1s. The alphabet is (0,1). I'm not sure how to construct a larger DFA combining the two. Thanks!

Here's a general idea:
The most straightforward way to do this is to have different paths for counting your 0s that are based on the number of 1s you've seen, such that they are "parallel" to each other. Move from one layer of the path to the next any time you see a 1, and then move from the last layer to a trap state if you see a third 1. Depending on the exact nature of the assignment you might be able to condense this, but once you have a basic layout you can determine that. Typically you can combine states from the first DFA with states in the second DFA to produce a smaller end result.
Here's a more mathematical explanation:
Constructing automata for the
intersection operation.
Assume we are
given two DFA M1 = (S1, q(1) 0 , T1,
F1) and M2 = (S2, q(2) 0 , T2, F2).
These two DFA recognize languages L1 =
L(M1) and L2 = L(M2). We want to
design a DFA M= (S, q0, T, F) that
recognizes the intersection L1 ∩L2. We
use the idea of constructing the DFA
for the union of languages. Given an
input w, we run M1 and M2 on w
simultaneously as we explained for the
union operation. Once we finish the
runs of M1 and of M2 on w, we look at
the resulting end states of these two
runs. If both end states are accepting
then we accept w, otherwise we reject
w.
When constructing the new transition function, the easy way to think of it is by using pairs of states. For example, consider the following DFAs:
Now, we can start combining these by traversing both DFAs at the same time. For example, both start at state 1. Now what happens if we see an a as input? Well, DFA1 will go from 1->2, and DFA2 will go from 1->3. When combining, then, we can say that the intersection will go from state "1,1" (both DFAs are in state 1) to state "2,3". State 2 is an accept state in DFA1 and state 3 is an accept state in DFA2, so state "2,3" is an accept state in our new DFA3. We can repeat this for all states/transitions and end up with:
Does that make sense?
Reference: Images found in this assignment from Cornell University.

The simplest way would be using the 2DFA model: from the end state of the first DFA(the one testing for at least 3 zeros) jump to the start state of the second one, and reverse to the beginning of the input. Then let the second DFA test the string.

Related

If a DFA is minimized, is it guaranteed that it's complement is also minimized?

Consider there is a minimized DFA that accepts the language L. The problem is to find the minimum number of states in its complement.
Now if I take the complement of this DFA i;e if I make the non-final states as final and final states as non-final, do I also need to worry about minimizing this complemented DFA?
DFA - Deterministic Finite Automata
Lets start with that is accepted by a minimum DFA . Then we can retrieve the DFA of the complement (as you have mentioned). So let's derive a DFA which accepts which has the same amount of states as .
Now Lets assume that is not a minimum DFA of
we should be able to reduce the number of states in it further to get a DFA . But getting the complement of should give us a new DFA which accepts which is but has less states than making it not a minimum DFA of .
So our assumption that not being the miniumum of is wrong.

Definition of the "DFA for a language"

I just started learning Theory of Computation this semester and a bit confused by the phrase "DFA for a language". If it is asked to construct a DFA for some collection of binary strings L, does it mean to find DFA M with L(M)=L or just $L(M)\supset L$?
Most compiler/theory courses tend to have different styles surrounding teaching definitions of deterministic finite automata and formal languages, but I'll try to make this description as agnostic as possible.
The phrase "DFA for a language" loosely means: a DFA which accepts every word in the language and rejects every word not in the language.
The way I was taught DFAs is to have final/accepting states and regular states which removes the necessity for an implicit error state.
This means that a DFA accepts a word if the state it is in at the end of input is accepting and it rejects the word if the state is not accepting.
Ex:
Let's define L as the language which contains an even number of 1s. These will be binary strings so the symbols are just 0 and 1.
00, 110, 111, 1111, etc are examples of words in this language. Notice that the empty string is in this language.
We can have two states in our DFA. The starting state, let's call it even 1s, is also an accepting state because 0 ones is even. The other state is odd 1s, this is not accepting.
As for transitions, when even 1s receives a 1, it transitions to odd 1s. And when odd 1s receives a 1, it transitions to even 1s.
Now, the number of 0s doesn't matter, so in either state, it transitions to itself.
Apologies for the double arrow, this website is great but I couldn't figure out how to separate the transitions between even 1s and odd 1s
Deterministic Finite Automaton (DFA)
In DFA, for each input symbol, one can determine the state to which the machine will move. Hence, it is called Deterministic Automaton. As it has a finite number of states, the machine is called a Deterministic Finite Machine or Deterministic Finite Automaton.
Formal Definition of a DFA
A DFA can be represented by a 5-tuple (Q, ∑, δ, q0, F) where −
-> Q is a finite set of states.
-> ∑ is a finite set of symbols called the alphabet.
-> δ is the transition function where δ: Q × ∑ → Q
-> q0 is the initial state from where any input is processed (q0 ∈ Q).
-> F is a set of final state/states of Q (F ⊆ Q).
Write your question in precise way. here DFA for a language means that you need to construct machine for particular language only not it's subset or superset. construct DFA maachine for which L(M)= L.

Determine the running time of an algorithm with two parameters

I have implemented an algorithm that uses two other algorithms for calculating the shortest path in a graph: Dijkstra and Bellman-Ford. Based on the time complexity of the these algorithms, I can calculate the running time of my implementation, which is easy giving the code.
Now, I want to experimentally verify my calculation. Specifically, I want to plot the running time as a function of the size of the input (I am following the method described here). The problem is that I have two parameters - number of edges and number of vertices.
I have tried to fix one parameter and change the other, but this approach results in two plots - one for varying number of edges and the other for varying number of vertices.
This leads me to my question - how can I determine the order of growth based on two plots? In general, how can one experimentally determine the running time complexity of an algorithm that has more than one parameter?
It's very difficult in general.
The usual way you would experimentally gauge the running time in the single variable case is, insert a counter that increments when your data structure does a fundamental (putatively O(1)) operation, then take data for many different input sizes, and plot it on a log-log plot. That is, log T vs. log N. If the running time is of the form n^k you should see a straight line of slope k, or something approaching this. If the running time is like T(n) = n^{k log n} or something, then you should see a parabola. And if T is exponential in n you should still see exponential growth.
You can only hope to get information about the highest order term when you do this -- the low order terms get filtered out, in the sense of having less and less impact as n gets larger.
In the two variable case, you could try to do a similar approach -- essentially, take 3 dimensional data, do a log-log-log plot, and try to fit a plane to that.
However this will only really work if there's really only one leading term that dominates in most regimes.
Suppose my actual function is T(n, m) = n^4 + n^3 * m^3 + m^4.
When m = O(1), then T(n) = O(n^4).
When n = O(1), then T(n) = O(m^4).
When n = m, then T(n) = O(n^6).
In each of these regimes, "slices" along the plane of possible n,m values, a different one of the terms is the dominant term.
So there's no way to determine the function just from taking some points with fixed m, and some points with fixed n. If you did that, you wouldn't get the right answer for n = m -- you wouldn't be able to discover "middle" leading terms like that.
I would recommend that the best way to predict asymptotic growth when you have lots of variables / complicated data structures, is with a pencil and piece of paper, and do traditional algorithmic analysis. Or possibly, a hybrid approach. Try to break the question of efficiency into different parts -- if you can split the question up into a sum or product of a few different functions, maybe some of them you can determine in the abstract, and some you can estimate experimentally.
Luckily two input parameters is still easy to visualize in a 3D scatter plot (3rd dimension is the measured running time), and you can check if it looks like a plane (in log-log-log scale) or if it is curved. Naturally random variations in measurements plays a role here as well.
In Matlab I typically calculate a least-squares solution to two-variable function like this (just concatenates different powers and combinations of x and y horizontally, .* is an element-wise product):
x = log(parameter_x);
y = log(parameter_y);
% Find a least-squares fit
p = [x.^2, x.*y, y.^2, x, y, ones(length(x),1)] \ log(time)
Then this can be used to estimate running times for larger problem instances, ideally those would be confirmed experimentally to know that the fitted model works.
This approach works also for higher dimensions but gets tedious to generate, maybe there is a more general way to achieve that and this is just a work-around for my lack of knowledge.
I was going to write my own explanation but it wouldn't be any better than this.

Can a DFA have epsilon/lambda transitions?

Can´t find anything affirmative about it. And a NFA with any epsilon transition is a epsilon-NFA ?
Thanks.
DFA doesn't have epsilon transitions.If it had it, it could transit from current state to other state without any input i.e. with nothing , not even {} or phi. And as definition , we know that the input must be from the input set.
Hope this cleared your doubt ...
From the definition of DFA ,"Deterministic Finite Automata is a machine that can't move on other state without getting any input".And since epsilon means nothing.Hence DFA can't move on epsilon moves.
Whereas from the definition of NFA,"Non deterministic Finite Automata is a machine that may move on other state without getting any input".So NFA can move on epsilon moves.
DFA must have a definite input symbol to move from one state to another state. Epsilon move isn't allow in DFA, because it'll change DFA into NFA. For e.g., suppose you are in state Q1, and you have a transition (Q1, e) = Q2, in this case you can directly go to Q2 without apply any input or you can stay in Q1 state, so you have two choosing opportunity at state Q1. In case of DFA you mustn't have any choosing criteria. That's why DFA don't have epsilon moves.
If the start state is also an end state then the fa accepts lamda. Also, if the fa specifically shows a transition from one state to the next with lamda then lamda can be considered an input.

How to make a start on the "crackless wall" problem

Here's the problem statement:
Consider the problem of building a wall out of 2x1 and 3x1 bricks (horizontal×vertical dimensions) such that, for extra strength, the gaps between horizontally-adjacent bricks never line up in consecutive layers, i.e. never form a "running crack".
There are eight ways of forming a crack-free 9x3 wall, written W(9,3) = 8.
Calculate W(32,10). < Generalize it to W(x,y) >
http://www.careercup.com/question?id=67814&form=comments
The above link gives a few solutions, but I'm unable to understand the logic behind them. I'm trying to code this in Perl and have done so far:
input : W(x,y)
find all possible i's and j's such that x == 3(i) + 2(j);
for each pair (i,j) ,
find n = (i+j)C(j) # C:combinations
Adding all these n's should give the count of all possible combinations. But I have no idea on how to find the real combinations for one row and how to proceed further.
Based on the claim that W(9,3)=8, I'm inferring that a "running crack" means any continuous vertical crack of height two or more. Before addressing the two-dimensional problem as posed, I want to discuss an analogous one-dimensional problem and its solution. I hope this will make it more clear how the two-dimensional problem is thought of as one-dimensional and eventually solved.
Suppose you want to count the number of lists of length, say, 40, whose symbols come from a reasonably small set of, say, the five symbols {a,b,c,d,e}. Certainly there are 5^40 such lists. If we add an additional constraint that no letter can appear twice in a row, the mathematical solution is still easy: There are 5*4^39 lists without repeated characters. If, however, we instead wish to outlaw consonant combinations such as bc, cb, bd, etc., then things are more difficult. Of course we would like to count the number of ways to choose the first character, the second, etc., and multiply, but the number of ways to choose the second character depends on the choice of the first, and so on. This new problem is difficult enough to illustrate the right technique. (though not difficult enough to make it completely resistant to mathematical methods!)
To solve the problem of lists of length 40 without consonant combinations (let's call this f(40)), we might imagine using recursion. Can you calculate f(40) in terms of f(39)? No, because some of the lists of length 39 end with consonants and some end with vowels, and we don't know how many of each type we have. So instead of computing, for each length n<=40, f(n), we compute, for each n and for each character k, f(n,k), the number of lists of length n ending with k. Although f(40) cannot be
calculated from f(39) alone, f(40,a) can be calculated in terms of f(30,a), f(39,b), etc.
The strategy described above can be used to solve your two-dimensional problem. Instead of characters, you have entire horizontal brick-rows of length 32 (or x). Instead of 40, you have 10 (or y). Instead of a no-consonant-combinations constraint, you have the no-adjacent-cracks constraint.
You specifically ask how to enumerate all the brick-rows of a given length, and you're right that this is necessary, at least for this approach. First, decide how a row will be represented. Clearly it suffices to specify the locations of the 3-bricks, and since each has a well-defined center, it seems natural to give a list of locations of the centers of the 3-bricks. For example, with a wall length of 15, the sequence (1,8,11) would describe a row like this: (ooo|oo|oo|ooo|ooo|oo). This list must satisfy some natural constraints:
The initial and final positions cannot be the centers of a 3-brick. Above, 0 and 14 are invalid entries.
Consecutive differences between numbers in the sequence must be odd, and at least three.
The position of the first entry must be odd.
The difference between the last entry and the length of the list must also be odd.
There are various ways to compute and store all such lists, but the conceptually easiest is a recursion on the length of the wall, ignoring condition 4 until you're done. Generate a table of all lists for walls of length 2, 3, and 4 manually, then for each n, deduce a table of all lists describing walls of length n from the previous values. Impose condition 4 when you're finished, because it doesn't play nice with recursion.
You'll also need a way, given any brick-row S, to quickly describe all brick-rows S' which can legally lie beneath it. For simplicity, let's assume the length of the wall is 32. A little thought should convince you that
S' must satisfy the same constraints as S, above.
1 is in S' if and only if 1 is not in S.
30 is in S' if and only if 30 is not in S.
For each entry q in S, S' must have a corresponding entry q+1 or q-1, and conversely every element of S' must be q-1 or q+1 for some element q in S.
For example, the list (1,8,11) can legally be placed on top of (7,10,30), (7,12,30), or (9,12,30), but not (9,10,30) since this doesn't satisfy the "at least three" condition. Based on this description, it's not hard to write a loop which calculates the possible successors of a given row.
Now we put everything together:
First, for fixed x, make a table of all legal rows of length x. Next, write a function W(y,S), which is to calculate (recursively) the number of walls of width x, height y, and top row S. For y=1, W(y,S)=1. Otherwise, W(y,S) is the sum over all S' which can be related to S as above, of the values W(y-1,S').
This solution is efficient enough to solve the problem W(32,10), but would fail for large x. For example, W(100,10) would almost certainly be infeasible to calculate as I've described. If x were large but y were small, we would break all sensible brick-laying conventions and consider the wall as being built up from left-to-right instead of bottom-to-top. This would require a description of a valid column of the wall. For example, a column description could be a list whose length is the height of the wall and whose entries are among five symbols, representing "first square of a 2x1 brick", "second square of a 2x1 brick", "first square of a 3x1 brick", etc. Of course there would be constraints on each column description and constraints describing the relationship between consecutive columns, but the same approach as above would work this way as well, and would be more appropriate for long, short walls.
I found this python code online here and it works fast and correctly. I do not understand how it all works though. I could get my C++ to the last step (count the total number of solutions) and could not get it to work correctly.
def brickwall(w,h):
# generate single brick layer of width w (by recursion)
def gen_layers(w):
if w in (0,1,2,3):
return {0:[], 1:[], 2:[[2]], 3:[[3]]}[w]
return [(layer + [2]) for layer in gen_layers(w-2)] + \
[(layer + [3]) for layer in gen_layers(w-3)]
# precompute info about whether pairs of layers are compatible
def gen_conflict_mat(layers, nlayers, w):
# precompute internal brick positions for easy comparison
def get_internal_positions(layer, w):
acc = 0; intpos = set()
for brick in layer:
acc += brick; intpos.add(acc)
intpos.remove(w)
return intpos
intpos = [get_internal_positions(layer, w) for layer in layers]
mat = []
for i in range(nlayers):
mat.append([j for j in range(nlayers) \
if intpos[i].isdisjoint(intpos[j])])
return mat
layers = gen_layers(w)
nlayers = len(layers)
mat = gen_conflict_mat(layers, nlayers, w)
# dynamic programming to recursively compute wall counts
nwalls = nlayers*[1]
for i in range(1,h):
nwalls = [sum(nwalls[k] for k in mat[j]) for j in range(nlayers)]
return sum(nwalls)
print(brickwall(9,3)) #8
print(brickwall(9,4)) #10
print(brickwall(18,5)) #7958
print(brickwall(32,10)) #806844323190414