Shortest path in labyrinth - arrays

Let us assume that we have a labyrinth represented by a m * n array of char . Our task is to find the fastest sequence of moves in order to transfer a carriage from starting position E to finish position S.
Each element of the array has one of the following values :
S , meaning starting position
E , meaning finish position
X , meaning obstacle
. , meaning open space in which we can move
T , meaning teleport.
Each teleport is connected with all other teleports . Only the carriage can be sent through teleports , not the man himself. The man must later move to a teleport to get the carriage back.
Each time , a man can either move left (L) , move right (R), move down (D) or move up (U) . When a man moves with the carriage , each step costs 2 seconds . If a man moves without carriage , each step costs 1 second . The use of the teleport system costs 2 seconds in total.
Example :
The array is:
S . . .
. . . .
T . . T
. . X E
The optimal solution is :
Down , Down , Right , Right , Right , Down
The time cost is :
2 + 2 = 4 , for "Down , Down"
2 , in order to send the carriage with teleport. We continue without carriage.
1 + 1 + 1 = 3 , for "Right , Right, Right" . Note that each step costs 1 instead of 2 , because we move without carriage.We now pick the carriage again.
2 for "Down" . 2 because we have picked the carriage again.
Total cost : 4 + 2 + 3 + 2 = 11.
Final answer : Down , Down , Right , Right , Right , Down
With is the most suitable algorithm for the task ?
So far , I have considered the posibility of using dynamic programming .This would lead to a O(m*n) solution though...
I also considered the possibility of applying some kind of Dijkstra , but I would need O(m*n) in order to create the graph...

Related

Shortest path in Answer Set Programming

I'm trying to find all the shortest path from one source node to all other destination node (so 1-3, 1-5, 1-4) with the relative cost for each shortest path.
I've tried with this code
node(1..5).
edge(1,2,1).
edge(2,3,9).
edge(3,4,4).
edge(4,1,4).
edge(1,3,1).
edge(3,5,7).
start(1).
end(3).
end(4).
end(5).
0{selected(X,Y)}1:-edge(X,Y,W).
path(X,Y):-selected(X,Y).
path(X,Z):-path(X,Y),path(Y,Z).
:-start(X),end(Y),not path(X,Y).
cost(C):-C=#sum{W,X,Y:edge(X,Y,W),selected(X,Y)}.
#minimize{C:cost(C)}.
#show selected/2.
but my code return this answer
> `clingo version 5.6.0 (c0a2cf99)
> Reading from stdin
> Solving...
> Answer: 1
> selected(3,4) selected(1,3) selected(3,5)
> Optimization: 12
> OPTIMUM FOUND
>
> Models : 1
> Optimum : yes
> Optimization : 12
> Calls : 1
> Time : 0.043s (Solving: 0.00s 1st Model: 0.00s Unsat: 0.00s)
> CPU Time : 0.000s`
What is wrong? How can I enumerate all shortest paths with relative costs?
Surely an error is that you are aggregating all the costs in C but, if I have correctly understood, you need distinct costs depending on the ending node.
Then there may be also other errors, but I can't exactly understand what do you mean with that program.
I would write it as follows:
node(1..5) .
edge(1,2,1) .
edge(2,3,9) .
edge(3,4,4) .
edge(4,1,4) .
edge(1,3,1) .
edge(3,5,7) .
start(1) .
end(3) .
end(4) .
end(5) .
% For each destination E, some outgoing edge from the start node should be selected
:- start(S), end(E), not selected(S,_,E) .
% No edge pointing to the start node should be selected
:- start(S), selected(_,S,_) .
% If an edge points to the end node, then it may be (or not be) selected for reaching it
0{selected(X,E,E)}1 :- edge(X,E,_), end(E) .
% If an outgoing edge from Y has been selected for reaching E, then an incoming edge may be (or not be) selected for reaching E
0{selected(X,Y,E)}1 :- edge(X,Y,_), selected(Y,_,E) .
% Compute the cost for reaching E
cost(E,C) :- C=#sum{W : edge(X,Y,W), selected(X,Y,E)}, end(E) .
#minimize{C : cost(E,C)} .
#show selected/3 .
#show cost/2 .
The execution of the above program is as follows:
clingo version 5.3.0
Reading from test.lp
Solving...
Answer: 1
selected(3,5,5) selected(1,3,3) selected(3,4,4) selected(1,3,4) selected(1,3,5) cost(3,1) cost(4,5) cost(5,8)
Optimization: 14
OPTIMUM FOUND
Models : 1
Optimum : yes
Optimization : 14
Calls : 1
Time : 0.017s (Solving: 0.00s 1st Model: 0.00s Unsat: 0.00s)
CPU Time : 0.000s
where:
an atom select(X,Y,Z) indicates that the edge (X,Y) has been selected for reaching the node Z;
an atom cost(E,C) indicates that the minimum cost for reaching the end node E is C.
The starting node is implicit since it is unique.

COBOL85: How to find number of rows in an array dynamically

In my program I keep filling the following array with data obtained from a database table then inspect it to find certain words:
01 PRODUCTS-TABLE.
03 PRODUCT-LINE PIC X(40) OCCURS 50 TIMES.
sometimes it occurs 6 times, sometimes more than 6 times.
I'd like to find the number of lines in the array every time I write data to it , how can I do that ?
I tried this but it based on a fixed length:
INSPECT-PROCESS.
MOVE 0 TO TALLY-1.
INSPECT PRODUCTS-TABLE TALLYING TALLY-1 FOR ALL "PRODUCT"
IF TALLY-1 > 0
MOVE SER-NUMBER TO HITS-SN-OUTPUT
MOVE FILLER-SYM TO FILLER-O
MOVE PRODUCT-LINE(1) TO HITS-PR-OUTPUT
WRITE HITS-REC
PERFORM WRITE-REPORT VARYING CNT1 FROM 2 BY 1 UNTIL CNT1 = 11.
WRITE-REPORT.
MOVE " " TO HITS-SN-OUTPUT
MOVE PRODUCT-LINE(CNT1) TO HITS-TX-OUTPUT
WRITE HITS-REC.
In the first output line it writes the SN and the first product-line then in the following lines it writes all remaining product-line and blank out SN.
Something like:
12345678 first product-line
Second product-line
etc
It’s working, however, it only stops when CNT1 is 11, how can I feed the procedure with a variable CNT1 based on how many lines are actually in PRODUCTS-TABLE each time?
I solved the problem by adding an array line counter (LINE-COUNTER-1) to count (ADD 1 TO LINE-COUNTER-1) how many times I add data to the array and stop writing the report when "WRITE-COUNTER = LINE-COUNTER-1"
INSPECT-PROCESS.
MOVE 0 TO TALLY-1
INSPECT PRODUCTS-TABLE TALLYING TALLY-1 FOR ALL "PRODUCT"
IF TALLY-1 > 0
MOVE HOLD-SER-NUM TO HITS-SN-OUTPUT
MOVE FILLER-SYM TO FILLER-O
MOVE PRODUCT-LINE(1) TO HITS-PR-OUTPUT
WRITE HITS-REC
PERFORM WRITE-REPORT VARYING WRITE-COUNTER FROM 2 BY 1
UNTIL WRITE-COUNTER = LINE-COUNTER-1.

Prolog , endless loop

I did t he following code to go through all student Ids starting from 476 and ending at 520.
schedule_errors(A,B,C):-
Errors is 0,
check_Courses(476,A,B,C,Errors).
check_Courses(X,A,B,C,Errors):-
. .
. .
. .
Y is X+1,
check_Courses(Y,A,B,C,Er).
The problem is the programm keeps running indefinetly ignoring my exit loop predicate
check_Courses(520,A,B,C,Er):-
write('Check complete').
I can't understand what i am doing wrong. i Tried a similar easier version (just counting to 10) and it works fine
loop(10):-
write('cd finished').
loop(X):-
write(X), nl,
Y is X+1,
loop(Y).
What am i missing?
One important observation is that loop/1 does not terminate either. You can see this for example as follows:
?- loop(1), false.
1
2
3
...
8
9
cd finished10
11
12
13
14
...
49
50
51
...
32394
32395
...
Note that the textual order in which you state your clauses in Prolog matters.
If you exchange the two clauses of loop/1, then you do not get a single solution, only an endless stream of output:
?- loop(1).
...
42642
42643
...
So, in check_courses/5, if you put a more specific case after a case that subsumes it, then the textually first clause will always be tried first.
Put simple cases before more complex cases!

SPSS looping through a set of variables in combination with if-statement

I've got 53 variables named W1_C14_0 to W1_C14_52, and each has a value from 1 to 15. I need to find how many "spells" of each number there are in this list - i.e. how many seperate runs of 1's, 2's etc in each case. This is what I'm doing and it's working fine, but is there any way to condense it into a loop?
DO REPEAT first = W1_C14_0 to W1_C14_51 /
second = W1_C14_1 to W1_C14_52 .
DO IF (SYSMIS(first) OR first<>second) .
DO IF (second=1) .
COMPUTE W1_spells1 = W1_spells1 + 1 .
ELSE IF (second=2) .
COMPUTE W1_spells2 = W1_spells2 + 1 .
ELSE IF (second=3) .
COMPUTE W1_spells3 = W1_spells3 + 1 .
*and so on down to...
ELSE IF (second=15) .
COMPUTE W1_spells15 = W1_spells15 + 1 .
END IF.
END IF.
END REPEAT .
You can loop through the spell variables using the VECTOR command.
VECTOR W1_spells = W1_spells1 TO W1_spells15.
DO REPEAT first = W1_C14_0 to W1_C14_51 /
second = W1_C14_1 to W1_C14_52 .
DO IF (SYSMIS(first) OR first<>second).
LOOP #i=1 TO 15.
DO IF (second=#i) .
COMPUTE W1_spells(#i) = W1_spells(#i) + 1.
END IF.
END LOOP.
END IF.
END REPEAT.

Read/Write/Find/Replace huge csv file

I have a huge (4,5 GB) csv file.. I need to perform basic cut and paste, replace operations for some columns.. the data is pretty well organized.. the only problem is I cannot play with it with Excel because of the size (2000 rows, 550000 columns).
here is some part of the data:
ID,Affection,Sex,DRB1_1,DRB1_2,SENum,SEStatus,AntiCCP,RFUW,rs3094315,rs12562034,rs3934834,rs9442372,rs3737728
D0024949,0,F,0101,0401,SS,yes,?,?,A_A,A_A,G_G,G_G
D0024302,0,F,0101,7,SN,yes,?,?,A_A,G_G,A_G,?_?
D0023151,0,F,0101,11,SN,yes,?,?,A_A,G_G,G_G,G_G
I need to remove 4th, 5th, 6th, 7th, 8th and 9th columns;
I need to find every _ character from column 10 onwards and replace it with a space ( ) character;
I need to replace every ? with zero (0);
I need to replace every comma with a tab;
I need to remove first row (that has column names;
I need to replace every 0 with 1, every 1 with 2 and every ? with 0 in 2nd column;
I need to replace F with 2, M with 1 and ? with 0 in 3rd column;
so that in the resulting file the output reads:
D0024949 1 2 A A A A G G G G
D0024302 1 2 A A G G A G 0 0
D0023151 1 2 A A G G G G G G
(both input and output should read one line per row, ne extra blank row)
Is there a memory efficient way of doing that with java(and I need a code to do that) or a usable tool for playing with this large data so that I can easily apply Excel functionality..
You need two things:
- Knowledge of Regular Expressions (aka Regex, Regexes)
- PowerGrep

Resources