I have done some searching about how to detect a loop in topological sort, I also finish the coding for the finding a loop, and here is the code:
--print the sort message
IF Kn = 0 THEN
Put("The sorting is complete!!");
RETURN;
ELSE
Put("The Sorting is not complete, loops occur!!");
FOR K IN 1 .. NA LOOP
SortStructure(K).Count:= 0;
END LOOP;
END IF;
-- Find the loop
for K in 1 .. NA loop
P := SortStructure(K).Top;
SortStructure(K).Top := ITN(0);
--when count = 0 and top /= 0, the loop occur
while P /= ITN(0) and then SortStructure(SortElement'Pos(P.suc)).count= 0 loop
SortStructure(SortElement'Pos(P.suc)).count:= k;
IF P /= Itn(0) THEN
P := P.Next;
END IF;
END LOOP;
END LOOP;
--use K determine a part of the loop
K:=1;
WHILE Sortstructure(K).Count= 0 LOOP
K:= K+1;
END LOOP;
--Mark the loop
LOOP
Sortstructure(K).Top := ITN(1);
K:= Sortstructure(K).Count;
EXIT WHEN SortStructure(K).Top /= ITN(0);
END LOOP;
--Print the loop
Put_Line("The loop is: ");
WHILE SortStructure(K).Top /= ITN(0) LOOP
--SortElement'Val(K) will return the value of K, make this also work for Enumeration
Put(SortElement'Val(K));
Put(", ");
SortStructure(K).Top := ITN(0);
K:= SortStructure(K).Count;
END LOOP;
Put(SortElement'Val(K));
New_Line;
This code starts from printing the message if there is a loop occurred, then mark the beginning of the loop and the end of the loop then print it. It works well for detect single loop, but how to make this can detect multiple loops and print them?
For example:Given the relations (format "Pre < Suc"):
1<2, 2<3, 3<1 (one loop), 1<4, 4<3 (second loop).
Any ideas would be appreciated.
I am not sure if topological sorting will help you detecting all cycles. It definitely helps you in testing whether the graph is acyclic or not.
Why you do not simply run DFS over the graph and look for back edges. Every time you encounter a back edge, you print the cycle path. The printing task is kind of tricky but I believe is doable ( see this )
I would think , you would go like All path problem. If topological sort is what you want to do for detecting multiple cycles, whenever you detect a cycle, add the current stack to a list and continue with next available node , and go up the edge recursively.
Related
Is it possible to index an array in a loop with in a loop (Matlab)?
So I'm indexing a 3d matrix with 3 parameter:
For instance:
A(1,1,:)
A(1,2,:)
...
A(1,9,:)
then I want the code to jump to the next element of the first prameter:
A(2,1,:)
A(2,2,:)
...
A(2,9,:)
And so on until I finish with all the elements of the first parameter.
Now I have a :
for j=1:27
for i=1:9
X(j,i,:)= f(j,i,:)
end
end
But I'm only getting a row of results when it should be a matrix of 27x9x:
Do anyone know how to make the second loop (i) runs 9 times for the first value of j and then move to the second value of j and run 9 times i and so on?
Thanks!
use squeeze(); something like this:
for j=1:27
for i=1:9
tmp= squeeze(f(j,i,:));
X(j,i,:) = tmp;
end
end
I am working on MATLAB code right now, and I want to increament y by 3 then by 1 and so on.
Here is the code if anyone could help, it would be appreciated.
for y=1:2:9
for x=9:-1:1
A(x,y)=1
if x==1 && y~=9
%y=y+1
for x= 1:9
A(x,y)=1
end
end
end
end
You first make a vector of the indexes you want to visit and then loop over the vector.
idx = [1,2,5]; %and so on
for ct = 1:length(idx)
A(x,y(idx(ct)))=1
end
You can specify a predefined vector or even matrix to be used in for loop; not necessary to use range index.
I am not completely certain how your question is reflected in your code. However, if you want to alternately increment y with 1 and 3, I would make a standard for-loop and then update y inside. Something like:
n = 100;
for i = 1:n
y = y + 2*mod(i,2)+1;
display(y) %Do things
end
I'm working on a school homework and I'm finding difficulties in outputing an array with values of 1.I used this code,but the simulator keeps filling the signal bar with X
integer index = 0;
initial
begin
for(index=0;index<=7;index = index+1)
begin
data_out[index]<=1;
end
end
endmodule
data_out is declared as output reg [7:0]data_out
Can anyone suggest me anything?
It works now , as i've used wire[7:0] data_out_test and always block. Thank you for your answers
Ok,and next . I have a descending order counter by the posedge clock and another variable suma_de_1 whose value is 12.The counters stars from 31 to 0 and i have the following if condition
`integer index = 0;
always#(posedge clock) begin
for(index=0;index<=31;index = index+1)
begin
if(count > suma_de_1)
data_out[index]<=2'b00;
else data_out[index]<=1;
end end`
check this out to see the result waveform
at that point count becomes smaller than suma_de_1 but it creates another array . I want it to complete the previous array who was full of 0 until then.
Hope I'm clear enough. I want the output in one array,not two
I need to remove element from array. I have tried to use array.delete(n) function, but it deletes all elements from identifier n. How to just delete exact element n ?
For example if array is 1 2 3 4 5, and n = 3, after delete it should look like following 1 2 4 5.
My code so far :
DECLARE
/* declare type array */
TYPE number_index_by_number IS TABLE OF number INDEX BY binary_integer;
v_n NUMBER := &sv_n;
v_m NUMBER := &sv_m;
v_min Number;
v_tmp Number;
v_array number_index_by_number;
v_sorted_array number_index_by_number;
begin
for i in 1..v_n
loop
v_array(i) := dbms_random.value(1,1000);
end loop;
for j in v_array.first..v_array.last
loop
DBMS_OUTPUT.put_line('v_array('||j||') :'||v_array(j));
end loop;
<<i_loop>> for i in 1..v_m
loop
/*set first array value to variable min*/
v_min := v_array(1);
v_tmp := 1;
<<j_loop>> for j in v_array.first..v_array.last
loop
DBMS_OUTPUT.put_line('v_array('||j||') :'||v_array(j));
if (v_min > v_array(j)) THEN
begin
v_min := v_array(j);
v_tmp := j;
DBMS_OUTPUT.put_line(j);
end;
end if;
end loop;
/*problem is in at this line*/
v_array.delete(v_tmp);
v_sorted_array(i) := v_min;
end loop;
for i in v_sorted_array.first..v_sorted_array.last
loop
DBMS_OUTPUT.put_line('v_sorted_array('||i||') :'||v_sorted_array(i));
end loop;
end;
I cannot reproduce any of the behaviour you describe. I could not get the delete collection method to do anything other than what it is documented to do.
However, there are a few errors in your code that could do with being tidied up.
Firstly, I should point out if you delete an element with key 3 from a PL/SQL associative array, there is then nothing with key 3 in the array. The remaining values don't 'shuffle' down to fill the gap. If there was an element with key 4 before the delete, the same element will still have key 4 afterwards. As a result, if you delete element j from a PL/SQL associative array v_array and then attempt to get v_array(j), you will get a 'no data found' error. You should check to see whether the element exists, using v_array.exists(j), before attempting to get a nonexistent element.
Secondly, the element with index 1 may get deleted before the last iteration of the outer loop. If this happens, v_array(1) will fail with a 'no data found' error. It would be better to assign NULL to v_min and v_tmp at the start of the loop, and assign to them during the loop if v_min is NULL or greater than v_array(j).
Finally, it seems your code returns the v_m smallest numbers from v_n. It would be worth verifying that v_m is less than or equal to v_n, as otherwise this doesn't make sense.
I'm affraid you cannot use a built-in method like this.
Instead of you shoud create a temp array to collect the elements prior to and afterwards the selected one from the original array, and return the temp array.
Below is a piece of code shown and doubts are regarding the implementation of loops
C := character'last; --'// SO code colorizer hack
I := 1;
K : loop
Done := C = character'first; --'
Count2 := I;
Exit K when Done;
C := character'pred(c); --'
I := I + 1;
end loop K;
Can anyone please tell me what does 'K' stands for.I guess its not a variable.How does 'K' control the execution of the loop?
K is the name of the loop. The end loop and Exit statements refer to that name, to make it clear what loop is being exited.
The Ada Reference Manual calls it a "loop_statement_identifier".
As noted, K is the loop's label. It allows you to identify a particular loop to aid readability, and also to selectively exit a specific loop from a set of nested enclosing ones (i.e. being a "goto"...shhh! :-)
Here's a contrived example (not compiled checked):
S : Unbounded_String;
F : File_Type;
Done_With_Line : Boolean := False;
All_Done : Boolean := False;
begin
Open(F, In_File, "data_file.dat");
File_Processor:
while not End_Of_File(F) loop
S := Get_Line(F);
Data_Processor:
for I in 1 .. Length(S) loop
Process_A_Character
(Data_Char => Element(S, I), -- Mode in
Line_Done => Done_With_Line, -- Mode out
Finished => All_Done); -- Mode out
-- If completely done, leave the outermost (file processing) loop
exit File_Processor when All_Done;
-- If just done with this line of data, go on to the next one.
exit Data_Processor when Done_With_Line;
end loop;
end loop File_Processor;
Close(F);
end;
K is essentially the name of the loop. The exit k tells the code to stop looping and go to the next statement after loop k ends.
You usually don't need to name loops, as you can just say exit and it will exit the enclosing loop. However, if you have a loop nested inside another loop, and you'd like to exit not the one immediately around the exit statement, but the outermost one, then doing something like this may be required.
K is a label that names the loop. Wow, it has been a long time since I've seen any Ada...