Push down automata for a language - computation-theory

I want to design a pushdown automata for the language
L = { a^i b^j c^k | i = j or k <= j <= 2k}
The solution proposed by the instructor is as pictured in the following diagram.
But my concern here is, that it does not handle string of the form when |2c| > |b|. That is when in the q8 state, what if the all the B's are stacked out, but the input C is not finished yet. That transition is not captured here.
Is my concern correct?
Or the proposed solution is a correct PDA.

Remember that j >= k, so that means |b| >= |c|.
If all the "b"s in input were read, then the number of B's stacked is greater than (or equal to) the number of "c"'s to be read in the input.
If j = k, then it will use the transiction from q8 to q8 until the input is finished.
If j = 2k, it will read a "c" (q8 -> q9) and take two B's out of the stack (q9 -> q8), so only strings with |b| = 2|c| can be accepted.
If j < 2k, it will use q8 -> q9 and q9-> q8 until the number of B's stacked is equal to the number of "c"s to be read in the input. Then it will use q 8-> q8 until the input is finished.

Related

Maximum the result from multiple functions which share an input amount

I have multiple functions as shown in the image. For a fixed x value, I need to distribute it into f, g, and h functions for getting the maximum output (y). In other words, having a fixed x value, find a, b, and c in which these conditions are satisfied:
a + b + c = x
a >= 0 and b >= 0 and c >= 0
f(a) + g(b) + h(c) has max value.
Given the functions are continuous and monotonic. How should I write code to find out a, b, and c? Thanks in advance!
Under appropriate assumptions, if the maximum has a > 0 and b > 0 and c > 0, then a necessary condition is f'(a) = g'(b) = h'(c). Intuitively, if one of these derivatives was greater than the others, then we could effect an improvement by increasing the corresponding variable a little bit and decreasing another variable by the same amount. Otherwise, the maximum has a = 0 or b = 0 or c = 0, and we have a lower dimensional problem of the same type.
The algorithm is to loop over all seven possibilities for whether a, b, c are zero (assuming x > 0 to avoid the trivial case), then solve the equations a + b + c = x and f'(a) = g'(b) = h'(c) (omitting the variables that are zero) to find the candidate solutions, then return the maximum.
Even if you only had 2 functions f and g, you would be looking for the x that maximises the maximum of a :-> f(a) + g(x-a) on [0,x], which is a sum of an increasing and a decreasing function, so you can't have any guarantee about it.
Still if these functions are given to you as closed form expressions, you can compute u(a)=f(a)+g(x-a) and try to find the maximum (under sufficient assumptions, you will have u'(a) = 0 and u''(a) <= 0 for instance).
Going back to the 3 functions case, if it's possible you can compute for every a, v(a) = max_{b in [0, x-a]} ( g(b)+h(x-a-b) ), and then compute the max of (f+v)(a), or do with b or c first if it works better, but in the general case there is no efficient algorithm.

How can I intercept this approximation error in my matlab script?

I am trying to find the minimum of a function using this algorithm.
It's not an optimal algorithm, but I don't care at the moment.
Also, you don't have to know how the algorithm works in order to reply, but if you're curious, I talk about it at the end of this post. It's really not that difficult.
Incriminated Algorithm
function result = fmin(f,a,b,max_error)
if abs(b-a) < max_error
result = (a+b)/2;
else
r1 = a+(b-a)*rand(1,1); r2 = a+(b-a)*rand(1,1);
c = min([r1,r2]); d = max([r1,r2]);
fc = f(c); fd = f(d);
if fc <= fd
b = d;
else
a = c;
end
result = fmin(f,a,b,max_error);
end
Now, the problem is this algorithm returns a minimum that is far from the actual minimum (computed via the matlab predefined function fminbnd) for more than max_error, if I use it with values of max_error <= 1e-10. This situation, form a theoretical standpoint is not possible.
Being recursive, the algorithm would never return if the condition abs(b-a) < max_error is never satisfied.
So, I think there is some error arising form the approximation of the numbers. At first, I thought that r1 or r2 where not computed properly. At some point, the two numbers would go out of the [a,b] interval, thus invalidating the hypothesis on which the algorithm is working.
To prove this, I modified the algorithm above to include a check on the interval that's computed at every iteration:
Incriminated Algorithm 2 [Check on the extremes]
function result = fmin(f,a,b,max_error)
if abs(b-a) < max_error
result = (a+b)/2;
else
r1 = a+(b-a)*rand(1,1); r2 = a+(b-a)*rand(1,1);
c = min([r1,r2]); d=max([r1,r2]);
% check that c and d are actually inside [a,b]
if ((c < a)||(d > b))
disp('Max precision reached');
result = (a+b)/2;
return;
end
fc = f(c); fd = f(d);
if fc <= fd
b = d;
else
a = c;
end
result = fmin(f,a,b,max_error);
end
But I don't get any additional output from the console.
So, I am thinking there is some error in the computation of f(c) or f(d), but I don't know how to prove it.
Question
Finally, my questions are
Do we, at this point, can be sure that the error is committed in the computation of either one of f(c) or f(d)?
Can we prove it with some line of code? Or better, can we write the algorithm so that it returns when it is supposed to?
How the algorithm works (not strictly inherent to the question)
It's an iterative algorithm. Basically, the idea is to generate a sequence of intervals containing the solution, starting from an initial interval [a,b] in which a given function f is unimodal.
At every step, we randomly choose two number c and d so that a <= c <= d <= b. Now, if we find that f(c) > f(d) it means we are sure that we can discard the values the function assumes before c as valid candidates for a minimum, because of the unimodality. So we restrict the interval and repeat the procedure in the interval [c,b]. On the contrary, if it's f(c) < f(d), we can discard the values from d to b, so we repeat the procedure in the interval [a,d].
At every iteration, the interval gets shorter. When its length is minor than the specified max_error value, the algorithm returns the medium point of the last interval as an approximation of the minimum value.
EDIT
I see there is one person that wants to close this question because it is too broad.
Please sir, can you elaborate in the comments?
This subdivision method only works in the special case that your function is (quasi-)convex (one local minimum, monotonically falling on the left, raising on the right). In the case of several local minima it will often converge to one of them, but it is by no means guaranteed that the algorithm finds the global minimum. The reduction from a to c resp. from b to d can jump over several local minima.

Ukkonen's suffix tree algorithm: procedure 'test and split' unclear

ukkonen's on line construction algorithm
i got a problem trying to understand the 'test and split' procedure,which is as follows:
procedure test–and–split(s, (k, p), t):
>1. if k ≤ p then
>2. let g'(s,(k',p'))=s' be the tk-transition from s
>3. if t=t(k'+p-k+1) then return (true,s)
my problem is that what exactly does the 2nd line mean,how can g'(s,(k',p'))be still a tk-transition if it starts from s and followed by t(k') instead of t(k)??
Probably you already figured it out and you don't need an answer anymore, but since I had the same problem in trying to understand it, and maybe it'll be useful for someone else in the future, the answer I think is the following one.
In Ukkonen's on line construction algorithm, on page 7 you can read that:
...
The string w spelled out by the transition path in STrie(T) between two explicit states s and r is represented in STree(T) as generalized transition g′(s,w) = r. To save space the string w is actually represented as a pair (k,p) of pointers (the left pointer k and the right pointer p) to T such that tk . . . tp = w. In this way the generalized transition gets form g′(s, (k, p)) = r.
Such pointers exist because there must be a suffix Ti such that the transition path for Ti in STrie(T) goes through s and r. We could select the smallest such i, and let k and p point to the substring of this Ti that is spelled out by the transition path from s to r. A transition g′(s, (k, p)) = r is called an a–transition if tk = a. Each s can have at most one a–transition for each a ∈ Σ.
...
This means that we are looking for the smallest indexes k and p such that tk . . . tp = w in T
=> if there is more than one occurrence of w in T, with k and p we always reference the first one.
Now, procedure test–and–split(s,(k,p),t) tests whether or not a state with canonical reference pair (s,(k,p)) is the endpoint, that is, a state that in STrie(T i−1) would have a ti –transition. Symbol ti is given as input parameter t.
The first lines of the algorithm are the following:
procedure test–and–split(s,(k,p),t):
1. if k ≤ p then
2. let g′(s,(k′,p′)) = s′ be the t(k)–transition from s;
3. if t = t(k′+p−k+1) then return(true,s)
4. else ...
On line 1 we check if the state is implicit (that is when k <= p).
If so, then on line 2 we want to find the transition from s that starts with the character we find in pos k of T (that is tk). Note that tk must be equal to tk' but indexes k and k' can be different because we always point to the first occurrence of a string w in T (remember also that from one state there can be at most one transition that starts with character tk => so that's the correct and the only one).
Then on line 3 we check if the state referenced by the canonical reference pair (s,(k,p)) is the endpoint, that is if it has a ti -transition. The state (s,(k,p)) is the one (implicit or not) that we can reach from state s, following the tk' -transition (that is the tk-transition because k' = k) for (p - k) characters. This explains the tk′+p−k+1, where the +1 is for the next character, the one that we are checking if it is equal to t (where t = ti). In that case we reached the endpoint and we return true.
Else, starting from line 4, we split the transition g′(s,(k′,p′)) = s′ to make explicit the state (s,(k,p)) and return the new explicit state.

find the maximum number of courses i can participate in

I'm trying to find an optimal (in means of complexity) algo to get the maximum number of courses i can participate in. I don't care about the total length of the courses nor the courses itself. It's all about being present at as many courses as possible.
Given are two arrays S and E. S[i] contains the starting time of the course, E[i] contains the corresponding ending time. Arrays are already sorted by E. Since I'm not The Flash I can't join a course where the ending time of the first equals the starting time of the following.
Here's an example:
S = [
"2014-11-06 01:00:00",
"2014-11-06 03:00:00",
"2014-11-06 07:00:00",
"2014-11-06 09:00:00",
"2014-11-06 09:00:00"
]
E = [
"2014-11-06 05:00:00",
"2014-11-06 06:00:00",
"2014-11-06 08:00:00",
"2014-11-06 09:00:00",
"2014-11-06 10:00:00"
]
For those values the correct answer would be 3 since I can participate in course 1, 3 and 5 (other combinations are possible too)
Thanks in advance
The Core Idea
The idea is to use a recursion to check all of the courses. The basic solution is explained in Timothy Ha's answer. For the sake of clarity, I recall it :
Sort courses by S
Begin at S1 :
Find k = min(j, E1 < Sj). If it exists, find the best fit for Sk, ..., Sn
If k > 2 (= current course + 1), find the best fit for S2, ..., Sn
Return the best fit between Step 3 and Step 4.
Time optimization with dynamic programming
But you could optimize it by storing the intermediate values. To do so, instead of starting the recursion from the beginning, we will start from the end !
Let b be an array of n integers initialized to 0. Let bn = 1. Finally, let i = n-1
While i > 0, perform the following :
Consider we take the course i. We must find k = min(j, Ei < Sj). If such a k exists, it enforces i+1 ≤ k.
If k exists, then bi = max(1 + bk, bi+1).
Otherwise, bi = bi+1 (We don't have to explicitly state "max(1, bi+1)", since 1 ≤ bi+1 )
Decrement i and proceed to Step 1.
When the loop is over, the solution is b1.
Here is the solution in a C fashion
// I suppose S[] is sorted by increasing order
// E[] are the end times associated with S :
// (the course that starts at S[i] ends at E[i]
int findBestNumber(ADateType S[], ADateType E[], int n) {
int i = n-1, k, res;
int *sol = NULL;
if(!(sol = malloc(n*sizeof (int))))
return -1;
memset(sol, 0, sizeof (*sol));
sol[n-1] = 1;
while(i-- > 0) {
k = findMinIndex(E[i], S);
if(k >= 0) // k exists
sol[i] = max(1 + sol[k], sol[i+1]);
else // k does not exist, we return a value like -1
sol[i] = sol[i+1];
}
res = sol[0];
free(sol);
return res;
}
findMinIndex(after, S) search the minimum index k such that after ≤ Sk. Since S is sorted when this function is called, it is a simple binary search. In the above, I supposed we returned a negative value from findMinIndex() if we could not find such an index.
Space and Time Complexity for the DP version
In the Dynamic Programming version, we just compute step by step the intermediate results and we do so only once. Thus, this is O(n). The Space complexity is also O(n) since we need to store n intermediate values.
But remember we had to sort the courses by starting time ! This operation, using an appropriate sorting algorithm (eg. merge sort), is O(n. log(n)). The final time complexity is thus O(n. log(n)).
Bonus : A working C implementation
On Ideone
Note : After reading the question again, I noticed I can't select courses that starts at the same time than the ending time of the previously taken course ... To exclude these, just turn the >=s in findMinIndex() into >s
Since you commented that each course needs to be participated in full, I think algorithm can be like this:
sort courses by S
If you join S1, find list of courses with S > E1; if that list starts with Sk, then use recursion for (Sk, ..., Sn), total result will be (result from recursion) + 1.
If you skip S1, use recursion for (S2, S3, ..., Sn) and the value that comes from it.
Choose maximum of values coming from steps 2 and 3.
UPD (from comments) We should check more than just at first step, or recursion should store results for [K-N] sets, so as not to calculate again. I can imagine a case like this: S1, S2, E1, E2, S3, E3, .... SN, EN The part [3-N] can be calculated twice in recursion (with or without S1) if we don't check

Pumping Lemma's Condition 3 concept

I'm following one of the examples from my textbook on the Pumping Lemma:
Let C = {w | w has an equal number of 0s and 1s}
Condition 3 stipulates: |xy| <= p
If |xy| <= p, then y must consist only of 0s, so xyyz is not in C.
Therefore s cannot be pumped
I'm having trouble understanding how condition 3 leads to the conclusion that "y must only consist of 0s, so xyyz is not in C"
I guess the string chosen is 0p1p.
Since |xy| <= p, and xyz = 0p1p, the string xy will be 0k where k <= p since the first p symbols of 0p1p are all 0's. Since xy consists of only 0's, y must also consist of only 0's
And learn to put your question in a proper manner. You cannot expect others to "predict" your question while you put half of the information

Resources