Can a DFA state have two arrows pointing to it with the same value? - dfa

I know that to be considered a DFA, each state cannot have more than one arrow with the same value pointing to another state. However, can a DFA have a state that has two arrows pointing to it with the same value?

Sure. As long as each response is deterministic, several states might go to the same state on the same next input. Since you can only be in one of the states, determinism isn't lost.
x
A ----> B
| |
|y |z
| |
V z V
C ----> D

Related

Why is this DFA not accepted?

So I am supposed to construct a DFA that accepts sets of all strings over {0,1} of length 2:
So sigma = {0,1}
L = {00, 01, 10, 11}
What I initially tried was :
Why is it wrong?
Assuming B is final state, it can even accept string of length 1. Thats why. Add one more state to mark length 2 and it should be good.
A 0,1 B 0,1 (C) 0,1 D
( ) - accepted state
Also make sure anything more than length 3 results in non terminal state by adding a D.
This is the DFA you want:
This way, if another input symbol is present after the second one - you go from C to D and can never go back to an accepting state.
By the way, and perhaps more importantly - I didn't draw this image myself. I used graphviz, which is a neet tool you might use to visualize your DFAs. The code is:
digraph G {
node [shape="circle"];
Start [shape="none" label=""];
C [shape="doublecircle"];
Start -> A;
A -> B [label="0,1"];
B -> C [label="0,1"];
C -> D [label="0,1"];
D -> D [label="0,1"];
}
and there are online renderers even, like this one.
The "Start" node is a hack to get an arrow to point at the initial state of the DFA (this is why the image is centered on B despite there being 4 states).

How does the epsilon conversion work for NFA to DFA conversion?

This is the NFA:
Here are two tables I made for DFA and then my attempt for the DFA equivalent:
(source: yimg.com)
The problem is that it doesn't account for the epsilon, because I don't know how to convert when there are epsilon arrows.
This is an epsilon-NFA, just transform the epsilon-NFA into an equivalent NFA without the epsilon transitions. Make a table as you would do while transforming an NFA to a DFA, and instead of just checking where that state goes with an input, first, check the where it can go with epsilon transitions then with the input then again with the epsilon transition (this is called the epsilon-closure ). This way you will have sets of states you will reach with your inputs. The only thing you need to do is to mark any state that can reach a final state using only epsilon transition as final states as well. Then you can build an NFA without epsilon transitions and then you can use your knowledge to transform it into a DFA. Just an example; In your table, you show B has an empty set for the input 0 but it can actually take an epsilon transition to C and take a 0 there so it is actually not an empty set.
To account for the epsilon transitions you can do any number of epsilon transitions before and after your read the next symbol. So you don't only consider where you can go when you read the symbol 0 (as an example) but also consider where you can go when you do epsilon transitions before and after, like ε* 0 ε*.
This means that when you start at the state {A} and read the symbol 0 you can go to the following states:
A --0--> B
A --0--> B --ε--> C
A --0--> C
A --ε--> B --ε--> C --0--> C
And for reading the symbol 1 you can go to the following states:
A --1--> A
A --1--> A --ε--> B
A --1--> A --ε--> B --ε--> C
A --ε--> B --1--> B
A --ε--> B --1--> B --ε--> C
A --ε--> B --ε--> C --1--> C
So in your resulting DFA, the transition will look as follow:
+-------+---------+---------+
| state | 0 | 1 |
+-------+---------+---------+
| {A} | {B,C} | {A,B,C} |
+-------+---------+---------+

#VALUES! while using IF and OR together

I have the File as following format
Name Number Position
A 1
B 2
C 3
D 4
Now on position A3 , I applied =IF(B2=1,"Goal Keeper",OR(IF(B2=2,"Defender",OR(IF(B2=3,"MidField","Striker"))))) But it giving me an error #value!
Looked up at google, and my formula is correct.
What i basically want it
1- Goalkeeper 2-Defender 3-Midfield 4-Striker
Yes the other way is to to just filter the number and copy paste the text
But I want to do it using formula and want to know where did I go wrong.
Your immediate problem lies with the expression (for example):
OR(IF(B2=3,"MidField","Striker"))
| \__/ \________/ \_______/ |
| bool string string |
\____________________________/
string
The OR function expects a series of boolean values (true or false) and you're giving it a string value from the inner IF.
You don't actually need the or bits in this specific case, the if is a full if-else. So you can just use:
=IF(B1=1,"Goal Keeper",IF(B2=2,"Defender",IF(B2=3,"MidField","Striker")))
This means that B1=1 will result in "Goal Keeper", otherwise it will evaluate IF(B2=2,"Defender",IF(B2=3,"MidField","Striker")).
Then that means that, if B2=2, it will result in "Defender", otherwise it will evaluate IF(B2=3,"MidField","Striker").
Finally, that means the B2=3 will result in "MidField", anything else will give "Striker".
The only situation I can envisage when OR would come in handy here would be when two different numbers were to generate the same string. Let's say both 1 and 4 should give "Goalie", you could use:
=IF(OR(B1=1,B1=4),"Goalie",IF(B2=2,"Defender","MidField"))
Keep in mind that a more general solution would be better implemented with the Excel lookup functions, ones that would search a table (on the spreadsheet somewhere) which mapped the integers to strings. Then, if the mapping needed to change, you would just update the table rather than going back and changing the formula in every single row.
If you are actually tasked with solving the problem by using the IF and OR function within the same equation, this is the only way I can see how:
=IF(OR(B1=1, B1 = 2, B1 = 3, B1 = 4),IF(B1 = 1, "Goal Keeper", IF(B1 = 2,"Defender",IF(B1 = 3,"MidField","Striker")))
If B1 does not equal 1-4, the OR function will return FALSE and completely bypass all of the nested IF statements.

Trying to pass MPI derived types between processors (and failing)

I am trying to parallelize a customer's Fortran code with MPI. f is an array of 4-byte reals dimensioned f(dimx,dimy,dimz,dimf). I need the various processes to work on different parts of the array's first dimension. (I would have rather started with the last, but it wasn't up to me.) So I define a derived type mpi_x_inteface like so
call mpi_type_vector(dimy*dimz*dimf, 1, dimx, MPI_REAL, &
mpi_x_interface, mpi_err)
call mpi_type_commit(mpi_x_interface, mpi_err)
My intent is that a single mpi_x_interface will contain all of the data in 'f' at some given first index "i". That is, for given i, it should contain f(i,:,:,:). (Note that at this stage of the game, all procs have a complete copy of f. I intend to eventually split f up between the procs, except I want proc 0 to have a full copy for the purpose of gathering.)
ptsinproc is an array containing the number of "i" indices handled by each proc. x_slab_displs is the displacement from the beginning of the array for each proc. For two procs, which is what I am testing on, they are ptsinproc=(/61,60/), x_slab_displs=(/0,61/). myminpt is a simple integer giving the minimum index handled in each proc.
So now I want to gather all of f into proc 0 and I run
if (myrank == 0) then
call mpi_gatherv(MPI_IN_PLACE, ptsinproc(myrank),
+ mpi_x_interface, f(1,1,1,1), ptsinproc,
+ x_slab_displs, mpi_x_interface, 0,
+ mpi_comm_world, mpi_err)
else
call mpi_gatherv(f(myminpt,1,1,1), ptsinproc(myrank),
+ mpi_x_interface, f(1,1,1,1), ptsinproc,
+ x_slab_displs, mpi_x_interface, 0,
+ mpi_comm_world, mpi_err)
endif
I can send at most one "slab" like this. If I try to send the entire 60 "slabs" from proc 1 to proc 0 I get a seg fault due to an "invalid memory reference". BTW, even when I send that single slab, the data winds up in the wrong places.
I've checked all the obvious stuff like maiking sure myrank and ptsinproc and x_slab_dislps are what they should be on all procs. I've looked into the difference between "size" and "extent" and so on, to no avail. I'm at my wit's end. I just don't see what I am doing wrong. And someone might remember that I asked a similar (but different!) question a few months back. I admit I'm just not getting it. Your patience is appreciated.
First off, I just want to say that the reason you're running into so many problems is because you are trying to split up the first (fastest) axis. This is not recommended at all because as-is packing your mpi_x_interface requires a lot of non-contiguous memory accesses. We're talking a huge loss in performance.
Splitting up the slowest axis across MPI processes is a much better strategy. I would highly recommend transposing your 4D matrix so that the x axis is last if you can.
Now to your actual problem(s)...
Derived datatypes
As you have deduced, one problem is that the size and extent of your derived datatype might be incorrect. Let's simplify your problem a bit so I can draw a picture. Say dimy*dimz*dimf=3, and dimx=4. As-is, your datatype mpi_x_interface describes the following data in memory:
| X | | | | X | | | | X | | | |
That is, every 4th MPI_REAL, and 3 of them total. Seeing as this is what you want, so far so good: the size of your variable is correct. However, if you try and send "the next" mpi_x_interface, you see that your implementation of MPI will start at the next point in memory (which in your case has not been allocated), and throw an "invalid memory access" at you:
tries to access and bombs
vvv
| X | | | | X | | | | X | | | | Y | | | | Y | ...
What you need to tell MPI as part of your datatype is that "the next" mpi_x_interface starts only 1 real into the array. This is accomplished by redefining the "extent" of your derived datatype by calling MPI_Type_create_resized(). In your case, you need to write
integer :: mpi_x_interface, mpi_x_interface_resized
integer, parameter :: SIZEOF_REAL = 4 ! or whatever f actually is
call mpi_type_vector(dimy*dimz*dimf, 1, dimx, MPI_REAL, &
mpi_x_interface, mpi_err)
call mpi_type_create_resized(mpi_x_interface, 0, 1*SIZEOF_REAL, &
mpi_x_interface_resized, mpi_err)
call mpi_type_commit(mpi_x_interface_resized, mpi_err)
Then, calling "the next" 3 mpi_x_interface_resized will result in:
| X | Y | Z | A | X | Y | Z | A | X | Y | Z | A |
as expected.
MPI_Gatherv
Note that now you have correctly defined the extent of your datatype, calling mpi_gatherv with an offset in terms of your datatype should now work as expected.
Personally, I wouldn't think there is a need to try some fancy logic with MPI_IN_PLACE for a collective operation. You can simply set myminpt=1 on myrank==0. Then you can call on every rank:
call mpi_gatherv(f(myminpt,1,1,1), ptsinproc(myrank),
+ mpi_x_interface_resized, f, ptsinproc,
+ x_slab_displs, mpi_x_interface_resized, 0,
+ mpi_comm_world, mpi_err)

Move/remove an element in one array into another

I'm doing a project in C involving arrays. What I have is an array of 7 chars, I need to populate an array with 4 random elements from the 7. Then I compare an array I fill myself to it. I don't want to allow repeats. I know how to compare each individual element to another to prevent it but obviously this isn't optimal. So if I remove the elements from the array as I randomly pick them I remove any chance of them being duplicated, or so I think. My question is how would I do this?
Example:
char name[2+1] = {'a','b'};
char guess[2+1] = {};
so when it randomly picks a or b and puts it in guess[],
but the next time it runs it might pick the same. Removing it will get rid of that chance.
In bigger arrays it would make it faster then doing all the comparing.
Guys it just hit me.
Couldn't I switch the element I took with the last element in the array and shrink it by one?
Then obviously change the rand() % x modulus by 1 each time?
I can give you steps to do what you intend to do. Code it yourself. Before that let's generalize the problem.
You've an array of 'm' elements and you've to fill another 'n' length
array by choosing random elements from first array such that there are
no repetition of number. Let's assume all numbers are unique in first
array.
Steps:
Keep a pointer or count to track the current position in array.
Initialize it to zeroth index initially. Let's call it current.
Generate a valid random number within the range of current and 'm'. Let's say its i. Keep generating until you find something in range.
Fill second_array with first_array[i].
Swap first_array[i] and first_array[current] and increment current but 1.
Repeat through step 2 'n' times.
Let's say your array is 2, 3, 7, 5, 8, 12, 4. Its length is 7. You've to fill a 5 length array out of it.
Initialize current to zero.
Generate random index. Let's say 4. Check if its between current(0) and m(7). It is.
Swap first_array[4] and first_array[0]. array becomes 8, 3, 7, 5, 2, 12, 4
Increment current by 1 and repeat.
Here are two possible ways of "removing" items from an array in C (there are other possible way too):
Replace the item in the array with another items which states that this item is not valid.
For example, if you have the char array
+---+---+---+---+---+---+
| F | o | o | b | a | r |
+---+---+---+---+---+---+
and you want to "remove" the b the it could look like
+---+---+---+------+---+---+
| F | o | o | \xff | a | r |
+---+---+---+------+---+---+
Shift the remaining content of the array one step up.
To use the same example from above, the array after shifting would look like
+---+---+---+---+---+---+
| F | o | o | a | r | |
+---+---+---+---+---+---+
This can be implemented by a simple memmove call.
The important thing to remember for this is that you need to keep track of the size, and decrease it every time you remove a character.
Of course both these methods can be combined: First use number one in a loop, and once done you can permanently remove the unused entries in the array with number two.
To don't forget that an array is just a pointer on the beginning of a set of items of the same type in C. So to remove an element, you simply have to replace the element at the given index with a value that shows that it is not a valid entry i.e. null.
As the entry is a simple number, there is no memory management issue (that I know of) but if it were an object, you would have to delete it if it is the last reference you have on it.
So let's keep it simple:
array2[index2] = array1[index1];
array1[index1] = null;
The other way is to change the size of the original array so that it contains one less element, as Joachim stated in his answer.

Resources