تبليغاتX
UNiComp.iR | Download Direct Tutorials Video , Film | دانلودمستقیم فیلم آموزشی،کتاب،جزوه،مقاله

N-queen problem 8 وزیر


/*
 *------------------------------------------------------------------------
 *			    	N-queen problem
 *
 * The problem is to position n queens on a n-by-n chessboard such
 * that no queen beats the others
 *
 * Obviously there can be no more than one queen on any row of the board.
 * If we have n queens and a n-by-n chessboard, each row of the board
 * will have exactly one queen. Therefore, we can describe a board position
 * by listing only column positions of the corresponding queens. For example,
 * a list [c1 c2 c3 c4 c5 ... cn] of n numbers tells that
 * the first queen is on row 1 and column c1, the second queen stands
 * at the intersection of the 2nd row and the c2-th column, etc.
 *
 * Since no two queens can safely stand on the same column, all numbers
 * in the list [c1 ... cn] are different. Thus we can re-formulate the
 * problem as finding such a permutation from a list [1 2 3 ... n] which
 * describes a safe position of n queens.
 *
 * The present program is a prolog interpretation of the corresponding
 * E-lisp program, see "~/langs/lisp/QueensProblem.el"
 *
 *------------------------------------------------------------------------
 */


/*
 *------------------------------------------------------------------------
 * The following predicate checks to see if a position is safe.
 * The position is safe if the first queen does not beat the others,
 * and the position of the other queens is also safe.
 * As the representation of board positions guarantees that no
 * two queens share the same row or column, we only need to check
 * diagonals to make sure a position is safe.
 * Queen (i,ci) can beat queen (j,cj)
 * only if i-j = ci-cj, or i-j = cj-ci (assuming that i>j).
 * In other words, if the row distance between the queens is d,
 * they peacefully coexist if neither cj-ci = d, nor ci-cj = d.
 */
				% Check to see if a queen located
				% on column col and 'row-dist' rows 
				% above the first queen in the list
				% L beats someone in the list
queen_doesnt_hit(_,_,[]) :- !.
queen_doesnt_hit(Col,Row_dist,[A_queen_col|Other_queens]) :- !,
		Diag_hit_col1 is Col + Row_dist, A_queen_col =\= Diag_hit_col1,
		Diag_hit_col2 is Col - Row_dist, A_queen_col =\= Diag_hit_col2,
		Row_dist1 is Row_dist + 1,
		queen_doesnt_hit(Col,Row_dist1,Other_queens).
	

safe_position([_]) :- !.	% A single queen position is always safe
safe_position([A_queen|Other_queens]) :- !,
	queen_doesnt_hit(A_queen,1,Other_queens),
	safe_position(Other_queens).

% Check the safe_position predicate...
?-safe_position([1, 2]).
?-safe_position([1, 3, 5]).
?-safe_position([2, 4, 1, 3]).

/*
 *------------------------------------------------------------------------
 * The following function searches for a safe layout. 
 * It produces a permutation of a given list and checks to see if it
 * corresponds to a safe position.
 *
 */

do_insert(X,Y,[X|Y]).
do_insert(X,[Y1|Y2],[Y1|Z]) :- do_insert(X,Y2,Z).

permute([X],[X]).
permute([X|Y],Z) :- permute(Y,Z1), do_insert(X,Z1,Z).


safe_layout(Layout,Layout1) :-
	permute(Layout,Layout1), safe_position(Layout1).

safe_layout_all(Layout) :- 
 nl,nl,print('Solving an n-queen problem with n='),
 length(Layout,N), print(N), nl,
	safe_layout(Layout,Layout1),
	print(Layout1),nl,
	fail.
safe_layout_all(_).

% A 2-queen problem has no solutions
?-safe_layout_all([1,2]).

% A 3-queen problem has no solutions
?-safe_layout_all([1,2,3]).

% A 4-queen problem has two solutions: [3,1,4,2] and [2,4,1,3]
?-safe_layout_all([1,2,3,4]).

% A 5-queen problem has ten solutions; the following
% predicates tells them all
?-safe_layout_all([1,2,3,4,5]).

?-safe_layout_all([1,2,3,4,5,6]).

?-safe_layout_all([1,2,3,4,5,6,7]).

?-safe_layout_all([1,2,3,4,5,6,7,8]).

Search Engine Submission - AddMe