feat: README
This commit is contained in:
		
							parent
							
								
									2bffb065aa
								
							
						
					
					
						commit
						51433dedb1
					
				| 
						 | 
					@ -1,8 +1,17 @@
 | 
				
			||||||
edge(1,2).
 | 
					:- include(randompath1000).   % 2nd way of reading input facts
 | 
				
			||||||
edge(2,1).
 | 
					 | 
				
			||||||
edge(1,3).
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					:- table path/2.
 | 
				
			||||||
path(X,Y) :- edge(X,Y).
 | 
					path(X,Y) :- edge(X,Y).
 | 
				
			||||||
path(X,Y) :- edge(X,Z), path(Z,Y), !.
 | 
					% Way 1
 | 
				
			||||||
 | 
					%path(X,Y) :- edge(X,Z), path(Z,Y).
 | 
				
			||||||
 | 
					% Way 2
 | 
				
			||||||
 | 
					path(X,Y) :- path(X,Z), edge(Z,Y).
 | 
				
			||||||
 | 
					% Way 3
 | 
				
			||||||
 | 
					%path(X,Y) :- path(X,Z), path(Z,Y).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
cycle(X) :- path(X,X), !.
 | 
					cycle(X) :- path(X,X), !.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					printPath :- path(X, Y), fail.
 | 
				
			||||||
 | 
					printPath.
 | 
				
			||||||
 | 
					timePath :- cputime(X), printPath, cputime(Y), T is Y-X, write(T).
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,18 @@
 | 
				
			||||||
%input :- [reachin1000].    % one way of reading input facts
 | 
					%input :- [reachin1000].    % one way of reading input facts
 | 
				
			||||||
:- include(reachin1000).   % 2nd way of reading input facts
 | 
					:- include(reachin1000).   % 2nd way of reading input facts
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					% Way 1
 | 
				
			||||||
 | 
					%reach(X) :- source(X).
 | 
				
			||||||
 | 
					%reach(Y) :- reach(X), edge(X,Y).
 | 
				
			||||||
 | 
					% Way 2
 | 
				
			||||||
 | 
					%reach(Y) :- reach(X), edge(X,Y).
 | 
				
			||||||
 | 
					%reach(X) :- source(X).
 | 
				
			||||||
 | 
					% Way 3
 | 
				
			||||||
 | 
					%reach(X) :- source(X).
 | 
				
			||||||
 | 
					%reach(Y) :- edge(X,Y), reach(X).
 | 
				
			||||||
 | 
					% Way 4
 | 
				
			||||||
 | 
					reach(Y) :- edge(X,Y), reach(X).
 | 
				
			||||||
reach(X) :- source(X).
 | 
					reach(X) :- source(X).
 | 
				
			||||||
reach(Y) :- reach(X), edge(X,Y).
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
:- table reach/1.
 | 
					:- table reach/1.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,20 @@ generate input set
 | 
				
			||||||
```shell
 | 
					```shell
 | 
				
			||||||
python randomgen.py [number of nodes]
 | 
					python randomgen.py [number of nodes]
 | 
				
			||||||
```  
 | 
					```  
 | 
				
			||||||
 | 
					```shell
 | 
				
			||||||
 | 
					xsb
 | 
				
			||||||
 | 
					```  
 | 
				
			||||||
 | 
					```prolog
 | 
				
			||||||
 | 
					['A/reach.P'].
 | 
				
			||||||
 | 
					timeReach.
 | 
				
			||||||
 | 
					```  
 | 
				
			||||||
 | 
					| Input size | Way 1 | Way 2 | Way 3  | Way 4  |
 | 
				
			||||||
 | 
					| ---------- | ----- | ----- | ------ | ------ |
 | 
				
			||||||
 | 
					| 1000       | 0.0   | 0.0   | 0.765  | 0.766  |
 | 
				
			||||||
 | 
					| 2000       | 0.0   | 0.0   | 3.047  | 3.047  |
 | 
				
			||||||
 | 
					| 5000       | 0.0   | 0.0   | 18.828 | 18.953 |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					There is huge impact if we write edge(X,Y) before reach. But when I try this in swi-prolog(there is no cputime/1, so I cannot table it), there is no significant different between different ways of implementation.
 | 
				
			||||||
### Transitive closure and cycle  
 | 
					### Transitive closure and cycle  
 | 
				
			||||||
```shell
 | 
					```shell
 | 
				
			||||||
xsb
 | 
					xsb
 | 
				
			||||||
| 
						 | 
					@ -34,6 +48,46 @@ xsb
 | 
				
			||||||
timeNQueen(8).
 | 
					timeNQueen(8).
 | 
				
			||||||
timeOneQueen(8).
 | 
					timeOneQueen(8).
 | 
				
			||||||
```  
 | 
					```  
 | 
				
			||||||
 | 
					| Number of queens | Time for 1 queen | Time for all queens |
 | 
				
			||||||
 | 
					| ---------------- | ---------------- | ------------------- |
 | 
				
			||||||
 | 
					| 8                | 0.0              | 0.047               |
 | 
				
			||||||
 | 
					| 10               | 0.0              | 0.25                |
 | 
				
			||||||
 | 
					| 12               | 0.0              | 7.796               |
 | 
				
			||||||
 | 
					| 14               | 0.015            | 298.719             |
 | 
				
			||||||
 | 
					| 16               | 0.094            | Too long to run     |
 | 
				
			||||||
 | 
					| 18               | 0.485            | Too long to run     |
 | 
				
			||||||
 | 
					| 20               | 2.796            | Too long to run     |
 | 
				
			||||||
 | 
					| 22               | 29.407           | Too long to run     |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					I found somewhing interesting when I tried to use swi-prolog to program this question. The following code works in swi-prolog(not xsb):  
 | 
				
			||||||
 | 
					```prolog
 | 
				
			||||||
 | 
					attacks((Row1, Col1), (Row2, Col2)) :-
 | 
				
			||||||
 | 
					    Row1 =:= Row2;
 | 
				
			||||||
 | 
					    Col1 =:= Col2;
 | 
				
			||||||
 | 
					    abs(Row1 - Row2) =:= abs(Col1 - Col2).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					no_attacks(_, []).
 | 
				
			||||||
 | 
					no_attacks(Queen, [OtherQueen|OtherQueens]) :-
 | 
				
			||||||
 | 
					    \+ attacks(Queen, OtherQueen),
 | 
				
			||||||
 | 
					    no_attacks(Queen, OtherQueens).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					queen_positions(0, []).
 | 
				
			||||||
 | 
					queen_positions(N, [(N, Col)|Queens]) :-
 | 
				
			||||||
 | 
					    N > 0,
 | 
				
			||||||
 | 
					    N1 is N - 1,
 | 
				
			||||||
 | 
					    queen_positions(N1, Queens),
 | 
				
			||||||
 | 
					    member(Col, [1,2,3,4,5,6,7,8]).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					legal_queens([]).
 | 
				
			||||||
 | 
					legal_queens([Queen|Queens]) :-
 | 
				
			||||||
 | 
					    legal_queens(Queens),
 | 
				
			||||||
 | 
					    no_attacks(Queen, Queens).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					n_queens(N, Solution) :-
 | 
				
			||||||
 | 
					    queen_positions(N, Solution),
 | 
				
			||||||
 | 
					    legal_queens(Solution).
 | 
				
			||||||
 | 
					```  
 | 
				
			||||||
 | 
					but it runs ridiculously slow(takes seconds to compute one solution of 8 queens).Then I tried to play with it and rearrange it a little bit and the answer I got (in A/queens.P) now runs much faster in swi-prolog and runs succesfully in XSB.  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Part B
 | 
					## Part B
 | 
				
			||||||
### Reach  
 | 
					### Reach  
 | 
				
			||||||
| 
						 | 
					@ -59,6 +113,7 @@ Though it looks like the Way4 is way better tha Way 1(Almost twice as fast), but
 | 
				
			||||||
 | 
					
 | 
				
			||||||
It is exactly the other way around! I belive it is because the input file becomes too large
 | 
					It is exactly the other way around! I belive it is because the input file becomes too large
 | 
				
			||||||
(42 MByte), so it waste a lot of time to load it to memory then cache, and the following ones has much higher cache hits rate, so the first one takes way longer than the others.  
 | 
					(42 MByte), so it waste a lot of time to load it to memory then cache, and the following ones has much higher cache hits rate, so the first one takes way longer than the others.  
 | 
				
			||||||
 | 
					The runtime grows linearly respect to the input size, and there is no significant difference between different implementations.
 | 
				
			||||||
### N-queens
 | 
					### N-queens
 | 
				
			||||||
```shell
 | 
					```shell
 | 
				
			||||||
clingo --models 0 B/nqueens.lp
 | 
					clingo --models 0 B/nqueens.lp
 | 
				
			||||||
| 
						 | 
					@ -72,12 +127,57 @@ clingo --models 1 B/nqueens.lp
 | 
				
			||||||
| 10               | 0.003s           | 0.086s              |
 | 
					| 10               | 0.003s           | 0.086s              |
 | 
				
			||||||
| 12               | 0.004s           | 4.909s              |
 | 
					| 12               | 0.004s           | 4.909s              |
 | 
				
			||||||
| 14               | 0.006s           | Too long to run     |
 | 
					| 14               | 0.006s           | Too long to run     |
 | 
				
			||||||
| 20               | 0.011s           |                     |
 | 
					| 20               | 0.011s           | Too long to run     |
 | 
				
			||||||
| 50               | 0.073s           |                     |
 | 
					| 50               | 0.073s           | Too long to run     |
 | 
				
			||||||
| 100              | 0.463s           |                     |
 | 
					| 100              | 0.463s           | Too long to run     |
 | 
				
			||||||
| 200              | 3.233s           |                     |
 | 
					| 200              | 3.233s           | Too long to run     |
 | 
				
			||||||
| 500              | 35.073s          |                     |  
 | 
					| 500              | 35.073s          | Too long to run     |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
## Part C  
 | 
					## Part C  
 | 
				
			||||||
### N-queens  
 | 
					### N-queens  
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					| Number of queens | Max k |
 | 
				
			||||||
 | 
					| ---------------- | ----- |
 | 
				
			||||||
 | 
					| 4                | 3     |
 | 
				
			||||||
 | 
					| 8                | 3     |
 | 
				
			||||||
 | 
					| 10               | 4     |
 | 
				
			||||||
 | 
					| 12               | 5     |
 | 
				
			||||||
 | 
					| 14               | 5     |
 | 
				
			||||||
 | 
					| 16               | 5     |
 | 
				
			||||||
 | 
					| 18               | 5     |
 | 
				
			||||||
 | 
					| 20               | 5     |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Extra Credit  
 | 
				
			||||||
 | 
					### I  
 | 
				
			||||||
 | 
					```shell
 | 
				
			||||||
 | 
					python .\randompath.py 5000
 | 
				
			||||||
 | 
					```  
 | 
				
			||||||
 | 
					```shell
 | 
				
			||||||
 | 
					xsb
 | 
				
			||||||
 | 
					```  
 | 
				
			||||||
 | 
					```prolog
 | 
				
			||||||
 | 
					['A/cycle.P'].
 | 
				
			||||||
 | 
					timePath.
 | 
				
			||||||
 | 
					```  
 | 
				
			||||||
 | 
					| Number of Nodes | Way1   | Way 2  | Way3            |
 | 
				
			||||||
 | 
					| --------------- | ------ | ------ | --------------- |
 | 
				
			||||||
 | 
					| 200             | 0.0    | 0.0    | 0.407           |
 | 
				
			||||||
 | 
					| 500             | 0.031  | 0.031  | 6.125           |
 | 
				
			||||||
 | 
					| 1000            | 0.109  | 0.093  | 50.75           |
 | 
				
			||||||
 | 
					| 2000            | 0.391  | 0.391  | Too long to run |
 | 
				
			||||||
 | 
					| 5000            | 2.484  | 3.093  | Too long to run |
 | 
				
			||||||
 | 
					| 10000           | 10.344 | 13.125 | Too long to run |
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### II  
 | 
				
			||||||
 | 
					See Extra/2.pl
 | 
				
			||||||
 | 
					| Number of queens | Max k |
 | 
				
			||||||
 | 
					| ---------------- | ----- |
 | 
				
			||||||
 | 
					| 4                | 3     |
 | 
				
			||||||
 | 
					| 8                | 3     |
 | 
				
			||||||
 | 
					| 10               | 4     |
 | 
				
			||||||
 | 
					| 12               | 5     |
 | 
				
			||||||
 | 
					| 14               | 5     |
 | 
				
			||||||
 | 
					| 16               | 5     |
 | 
				
			||||||
 | 
					| 18               | 5     |
 | 
				
			||||||
 | 
					| 20               | 5     |
 | 
				
			||||||
| 
						 | 
					@ -6,5 +6,5 @@ file = open("reachin1000", "w")
 | 
				
			||||||
for i in range(10 * x):
 | 
					for i in range(10 * x):
 | 
				
			||||||
    j = random.randint(1,x)
 | 
					    j = random.randint(1,x)
 | 
				
			||||||
    k = random.randint(1,x)
 | 
					    k = random.randint(1,x)
 | 
				
			||||||
    file.write("edge({}, {}).\n".format(i, j))
 | 
					    file.write("edge({}, {}).\n".format(j, k))
 | 
				
			||||||
file.close()
 | 
					file.close()
 | 
				
			||||||
							
								
								
									
										9
									
								
								Assignment1/randompath.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								Assignment1/randompath.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,9 @@
 | 
				
			||||||
 | 
					import random
 | 
				
			||||||
 | 
					import sys
 | 
				
			||||||
 | 
					if len(sys.argv) == 2: x = int(sys.argv[1])
 | 
				
			||||||
 | 
					else: x = 1000
 | 
				
			||||||
 | 
					file = open("randompath1000", "w") 
 | 
				
			||||||
 | 
					for i in range(x):
 | 
				
			||||||
 | 
					    file.write("edge({}, {}).\n".format(i, i + 1))
 | 
				
			||||||
 | 
					file.write("edge({}, 1).\n".format(x))
 | 
				
			||||||
 | 
					file.close()
 | 
				
			||||||
							
								
								
									
										2000100
									
								
								Assignment1/reachin1000
									
									
									
									
									
								
							
							
						
						
									
										2000100
									
								
								Assignment1/reachin1000
									
									
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
		Loading…
	
		Reference in New Issue
	
	Block a user