Compare commits
6 Commits
18511dc973
...
f33e543d6f
| Author | SHA1 | Date | |
|---|---|---|---|
| f33e543d6f | |||
| b0798bc53c | |||
| f0fad37243 | |||
| b35a87b38b | |||
| 102880a276 | |||
| c0aec8dff0 |
9
.gitignore
vendored
9
.gitignore
vendored
@@ -1,9 +1,18 @@
|
||||
# out files
|
||||
*.out
|
||||
*.file
|
||||
|
||||
# Java
|
||||
.class
|
||||
.jar
|
||||
|
||||
# Perl
|
||||
nytprof*
|
||||
.callgrind
|
||||
|
||||
# Python
|
||||
*.pyc
|
||||
*.lprof
|
||||
|
||||
# Executables
|
||||
*.x
|
||||
|
||||
@@ -60,6 +60,9 @@ HTTP Server:
|
||||
Calculus: Simpson's Rule for Integration
|
||||
* Implements composite Simpson's Rule to integrate a function over an interval `[a,b]` using `n` approximating points
|
||||
|
||||
N Queens:
|
||||
* Solve the N queens problem using integer arrays, with minimal object-oriented fluff.
|
||||
|
||||
|
||||
### Programs In Progress
|
||||
|
||||
@@ -84,7 +87,7 @@ Arrays:
|
||||
* Use a native built-in data type to store a 1D array of data
|
||||
|
||||
Matrix inversion:
|
||||
* Gauss-Jordan elimination algorithm
|
||||
* Gauss-Jordan elimination or back-substitution algorithm
|
||||
|
||||
Vector products:
|
||||
* Given three three-dimensional vectors, compute dot/cross product, scalar/vector triple products
|
||||
|
||||
@@ -3,15 +3,20 @@ import java.util.Arrays;
|
||||
|
||||
public class NQueens {
|
||||
|
||||
public static final int SIZE = 9;
|
||||
|
||||
///////////////////////////////////////////////////
|
||||
// main
|
||||
//
|
||||
public static void main(String[] args) {
|
||||
long start = System.nanoTime();
|
||||
SolutionSaver s = new SolutionSaver();
|
||||
Board b = new Board(8);
|
||||
Board b = new Board(SIZE);
|
||||
explore(b,0);
|
||||
long end = System.nanoTime();
|
||||
long duration = end - start;
|
||||
System.out.printf("Found %d solutions\n ", SolutionSaver.nSolutions() );
|
||||
System.out.printf("Elapsed time %03f s\n ", (duration/1E9) );
|
||||
}
|
||||
//
|
||||
///////////////////////////////////////////////////
|
||||
@@ -20,25 +25,25 @@ public class NQueens {
|
||||
/// Placing queens, column-by-column; place the queen in column col.
|
||||
public static void explore(Board b, int col) {
|
||||
|
||||
if(col >= b.size() ) {
|
||||
if(col >= SIZE ) {
|
||||
|
||||
// We have reached the end.
|
||||
// No conflicts so far means no conflicts period.
|
||||
|
||||
// Save solution in a static class, no instantiation overhead
|
||||
String serial = b.toString();
|
||||
SolutionSaver.saveSolution(serial);
|
||||
SolutionSaver.saveSolution( b.toString() );
|
||||
|
||||
} else {
|
||||
|
||||
// The legalRows() method is a little bit of magic.
|
||||
// It returns an array of valid rows on which to place the col^th queen.
|
||||
for(Integer row : b.legalRows(col) ) { // important question: is this called each time in the loop?
|
||||
// (do i need to make a copy outside the loop?)
|
||||
int[] attacked = b.getDiagAttacked(col);
|
||||
int[] occupied = b.getOccupied(col);
|
||||
|
||||
for(int row=0; row<SIZE; row++) {
|
||||
if(occupied[row]!=1 && attacked[row]!=1) {
|
||||
b.choose(row,col);
|
||||
explore(b,col+1);
|
||||
b.unchoose(row,col);
|
||||
|
||||
}
|
||||
}
|
||||
}// done with base/recursive cases
|
||||
}
|
||||
@@ -55,7 +60,7 @@ class Board {
|
||||
int[] occupiedrows; // Array to mark occupied rows.
|
||||
// This is how we check for horizontal attacks.
|
||||
|
||||
int board_size; // Size of our problem
|
||||
public static int board_size;
|
||||
|
||||
public Board(int size) {
|
||||
this.board_size = size;
|
||||
@@ -63,11 +68,6 @@ class Board {
|
||||
this.occupiedrows = new int[size];
|
||||
}
|
||||
|
||||
/// Get board size
|
||||
public int size(){
|
||||
return this.board_size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get String representation of queen positions.
|
||||
* This prints 8 numbers, corresponding to 8 columns.
|
||||
@@ -95,52 +95,44 @@ class Board {
|
||||
}
|
||||
}
|
||||
|
||||
/// Get a list of legal rows
|
||||
public LinkedList<Integer> legalRows( int col ) {
|
||||
/// Get a list of occupied rows
|
||||
public int[] getOccupied(int col) {
|
||||
return this.occupiedrows;
|
||||
}
|
||||
|
||||
LinkedList<Integer> legalList = new LinkedList<Integer>();
|
||||
/// Get a list of attacked diagonals
|
||||
public int[] getDiagAttacked( int col ) {
|
||||
|
||||
// 1. Mark invalid squares on diagonals of already-placed queens
|
||||
// 1. Mark invalid squares on diagoonals of already-placed queens
|
||||
//
|
||||
// 2. For this column, loop over each row where it's legal to place a queen,
|
||||
// and run backtracking on that choice. Then unmake the choice and keep going.
|
||||
|
||||
// Store invalid rows on other queens' diagonals
|
||||
int[] diag = new int[size()];
|
||||
int[] diag = new int[this.board_size];
|
||||
|
||||
// Loop over all of the queens already placed (col-1)
|
||||
for(int k = 0; k <= (col-1); k++ ) {
|
||||
|
||||
// We're gonig to place the next queen on col.
|
||||
// Find which squares are on diagonal of queen k,
|
||||
// Find which squares are on diagonals of queen k,
|
||||
// and mark them as impossible.
|
||||
|
||||
// Lower right diagonal
|
||||
// Lower right diag
|
||||
int ix1 = this.queens[k] + col - k;
|
||||
if(ix1 >= 0 && ix1 < size() ) {
|
||||
if(ix1 >= 0 && ix1 < this.board_size ) {
|
||||
diag[ix1] = 1;
|
||||
}
|
||||
|
||||
// Upper right diagonal
|
||||
// Upper right diag
|
||||
int ix2 = this.queens[k] - col + k;
|
||||
if(ix2 >= 0 && ix2 < size() ) {
|
||||
if(ix2 >= 0 && ix2 < this.board_size ) {
|
||||
diag[ix2] = 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Legal rows are non-diagonal squares and squares on non-occupied rows.
|
||||
for (int row = 0; row < size(); row++) {
|
||||
|
||||
// If this row is legal, add it to the list
|
||||
boolean legal = diag[row]==0 && this.occupiedrows[row]==0;
|
||||
if(legal) {
|
||||
legalList.add(row);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return legalList;
|
||||
return diag;
|
||||
}
|
||||
}
|
||||
|
||||
30
java/nqueens/prof_java_hprof.sh
Executable file
30
java/nqueens/prof_java_hprof.sh
Executable file
@@ -0,0 +1,30 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Profile the N queens problem using Java Iteractive Profiler
|
||||
# http://jiprof.sourceforge.net/
|
||||
#
|
||||
# Also see http://charlesreid1.com/wiki/Java/Profiling
|
||||
#
|
||||
# Download source and look for profile/profile.jar
|
||||
|
||||
export PATH2JIP="${HOME}/Downloads/jip-src-1.2"
|
||||
|
||||
for N in 14
|
||||
do
|
||||
|
||||
echo "**************************************"
|
||||
echo "Profiling $N queens problem with Java JIP..."
|
||||
|
||||
# Update N
|
||||
/usr/local/bin/sed -i "s/SIZE = [0-9]\{1,\}/SIZE = ${N}/g" NQueens.java
|
||||
|
||||
# Compile
|
||||
javac NQueens.java
|
||||
|
||||
java -javaagent:${PATH2JIP}/profile/profile.jar NQueens
|
||||
|
||||
mv profile.txt profile_jip_${N}queens.out
|
||||
tail -n30 profile_${N}queens.out
|
||||
|
||||
done
|
||||
|
||||
32
java/nqueens/prof_java_jip.sh
Executable file
32
java/nqueens/prof_java_jip.sh
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Profile the N queens problem using Java Iteractive Profiler
|
||||
# http://jiprof.sourceforge.net/
|
||||
#
|
||||
# Also see http://charlesreid1.com/wiki/Java/Profiling
|
||||
#
|
||||
# Download source and look for profile/profile.jar
|
||||
|
||||
for N in 14
|
||||
do
|
||||
|
||||
echo "**************************************"
|
||||
echo "Profiling $N queens problem with Java HPROF..."
|
||||
|
||||
# Update N
|
||||
/usr/local/bin/sed -i "s/SIZE = [0-9]\{1,\}/SIZE = ${N}/g" NQueens.java
|
||||
|
||||
# Compile
|
||||
javac NQueens.java
|
||||
|
||||
echo " - - - - - - - - - - - - - - - - - - - - -"
|
||||
echo "Profiling $N queens with HPROF..."
|
||||
|
||||
java -agentlib:hprof=verbose=n NQueens
|
||||
#java -agentlib:hprof NQueens
|
||||
#java -agentlib:hprof=cpu=samples NQueens
|
||||
|
||||
mv java.hprof.txt profile_hprof_${N}queens.out
|
||||
tail -n30 hprof_${N}queens.out
|
||||
done
|
||||
|
||||
26
java/nqueens/time_java.sh
Executable file
26
java/nqueens/time_java.sh
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/bin/sh
|
||||
|
||||
export RIGHTNOW="`date +"%Y%m%d_%H%M%S"`"
|
||||
export OUT="timeout_nqueens_java_${RIGHTNOW}.out"
|
||||
touch ${OUT}
|
||||
cat /dev/null > ${OUT}
|
||||
|
||||
for N in 8 9 10 11 12 13 14 15
|
||||
do
|
||||
echo "**************************************" >> ${OUT}
|
||||
echo "Running $N queens problem with Java..." >> ${OUT}
|
||||
|
||||
# Update N
|
||||
/usr/local/bin/sed -i "s/SIZE = [0-9]\{1,\}/SIZE = ${N}/g" NQueens.java
|
||||
|
||||
# Compile
|
||||
javac Nqueens.java
|
||||
|
||||
# Semicolon is important here
|
||||
echo "Running..."
|
||||
{ time java NQueens >> ${OUT}; } 2>> ${OUT}
|
||||
echo "Done."
|
||||
|
||||
echo "" >> ${OUT}
|
||||
|
||||
done
|
||||
@@ -1,4 +1,4 @@
|
||||
#!/usr/bin/perl -w
|
||||
#!/usr/local/bin/perl -w
|
||||
|
||||
my $verse = <<"VERSE";
|
||||
100 bottles of beer on the wall,
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
#!/usr/bin/perl
|
||||
#!/usr/local/bin/perl
|
||||
|
||||
print 'hello world';
|
||||
|
||||
119
perl/nqueens/nqueens.pl
Normal file
119
perl/nqueens/nqueens.pl
Normal file
@@ -0,0 +1,119 @@
|
||||
#!/usr/local/bin/perl
|
||||
use Time::HiRes qw(time);
|
||||
use strict;
|
||||
use warnings;
|
||||
my $start = time;
|
||||
|
||||
######################################
|
||||
########## N Queens Puzzle ###########
|
||||
#
|
||||
#
|
||||
# The 8 queens problem is to place 8 queens on a chessboard
|
||||
# such that no queen attacks any other queen.
|
||||
#
|
||||
# In 1972, Dijkstra published the first depth-first
|
||||
# backtracking algorithm to solve the problem.
|
||||
#
|
||||
# This file implements a recursive backtracking algorithm
|
||||
# to find solutions to the N queens problem.
|
||||
#
|
||||
# This requires a way of choosing queens,
|
||||
# and a way to check if a configuration is valid (as we go).
|
||||
# The backtracking algorithm recursively calls a method
|
||||
# to place one queen at a time, 8 times.
|
||||
# When there are no more choices left to make, it has reached a leaf,
|
||||
# and it stores (or prints out) a solution.
|
||||
#
|
||||
# Modified and expanded from http://rosettacode.org/wiki/N-queens_problem#Perl
|
||||
|
||||
# Create an array to store solutions
|
||||
my @solutions;
|
||||
|
||||
# Create an array to store where queens have been placed
|
||||
my @queens;
|
||||
|
||||
# Mark the rows already used (useful for lookup)
|
||||
my @occupied;
|
||||
|
||||
# Size of board
|
||||
my $board_size;
|
||||
|
||||
|
||||
# explore() implements a recursive, depth-first backtracking method
|
||||
sub explore {
|
||||
# Parameters:
|
||||
# depth : this is the argument passed by the user
|
||||
|
||||
# First argument passed to the function is $depth
|
||||
# (how many queens we've placed on the board),
|
||||
# so use shift to pop that out of the parameters
|
||||
my ($depth, @attacked) = shift;
|
||||
|
||||
# Explore is a recursive method,
|
||||
# so we need a base case and a recursive case.
|
||||
#
|
||||
# The base case is, we've reached a leaf node,
|
||||
# placed 8 queens, and had no problems,
|
||||
# so we found a solution.
|
||||
if ($depth==$board_size) {
|
||||
# Here, we store the stringified version of @queens,
|
||||
# which are the row numbers of prior queens.
|
||||
# This is a global variable that is shared across
|
||||
# instances of this recursive function.
|
||||
push @solutions, "@queens\n";
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
##################################
|
||||
# Method 1
|
||||
#
|
||||
# Mark the squares that are attackable,
|
||||
# so that we can cut down on the search space.
|
||||
my($ix1, $ix2);
|
||||
$#attacked = 2 * $board_size;
|
||||
for( 0 .. $#queens) {
|
||||
$ix1 = $queens[$_] + $depth - $_ ;
|
||||
$attacked[ $ix1 ] = 1;
|
||||
|
||||
$ix2 = $queens[$_] - $depth + $_ ;
|
||||
$attacked[ $ix2 ] = 1;
|
||||
}
|
||||
#
|
||||
####################################
|
||||
|
||||
|
||||
for my $row (0 .. $board_size-1) {
|
||||
# Cut down on the search space:
|
||||
# if this square is already occupied
|
||||
# or will lead to an invalid solution,
|
||||
# don't bother exploring it.
|
||||
next if $occupied[$row] || $attacked[$row];
|
||||
|
||||
# Make a choice
|
||||
push @queens, $row;
|
||||
# Mark the square as occupied
|
||||
$occupied[$row] = 1;
|
||||
|
||||
# Explore the consequences
|
||||
explore($depth+1);
|
||||
|
||||
# Unmake the choice
|
||||
pop @queens;
|
||||
|
||||
# Mark the square as unoccupied
|
||||
$occupied[$row] = 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
$board_size = 11;
|
||||
|
||||
explore(0);
|
||||
|
||||
my $duration = time - $start;
|
||||
|
||||
print "Found ", scalar(@solutions), " solutions\n";
|
||||
printf "Execution time: %0.3f s \n",$duration;
|
||||
|
||||
|
||||
32
perl/nqueens/prof_perl.sh
Executable file
32
perl/nqueens/prof_perl.sh
Executable file
@@ -0,0 +1,32 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Profile the N queens problem using Devel::NYTProf
|
||||
#
|
||||
# Install using cpanm:
|
||||
# $ cpanm Devel::NYTProf
|
||||
#
|
||||
|
||||
for N in 8 9 10 11 12
|
||||
do
|
||||
|
||||
echo "**************************************"
|
||||
echo "Profiling $N queens problem with Perl..."
|
||||
|
||||
# Update N
|
||||
/usr/local/bin/sed -i "s/board_size = [0-9]\{1,\};/board_size = ${N};/g" nqueens.pl
|
||||
|
||||
echo "Running..."
|
||||
/usr/local/bin/perl -d:NYTProf nqueens.pl
|
||||
echo "Done."
|
||||
|
||||
# CSV contains interesting info
|
||||
${HOME}/perl5/bin/nytprofcsv nytprof.out
|
||||
|
||||
## More information...
|
||||
#${HOME}/perl5/bin/nytprofcg nytprof.out
|
||||
#${HOME}/perl5/bin/nytprofhtml nytprof.out
|
||||
|
||||
mv nytprof nytprof${N}
|
||||
|
||||
done
|
||||
|
||||
23
perl/nqueens/time_perl.sh
Executable file
23
perl/nqueens/time_perl.sh
Executable file
@@ -0,0 +1,23 @@
|
||||
#!/bin/sh
|
||||
|
||||
export RIGHTNOW="`date +"%Y%m%d_%H%M%S"`"
|
||||
export OUT="timeout_queens_perl_${RIGHTNOW}.out"
|
||||
touch ${OUT}
|
||||
cat /dev/null > ${OUT}
|
||||
|
||||
for N in 8 9 10 11 12 13 14 15
|
||||
do
|
||||
echo "**************************************" >> ${OUT}
|
||||
echo "Running $N queens problem with Perl..." >> ${OUT}
|
||||
|
||||
# Update N
|
||||
/usr/local/bin/sed -i "s/board_size = [0-9]\{1,\};/board_size = ${N};/g" nqueens.pl
|
||||
|
||||
# Semicolon is important here
|
||||
echo "Running..."
|
||||
{ time /usr/local/bin/perl nqueens.pl >> ${OUT}; } 2>> ${OUT}
|
||||
echo "Done."
|
||||
|
||||
echo "" >> ${OUT}
|
||||
|
||||
done
|
||||
@@ -1,12 +1,14 @@
|
||||
# Look ma, no modules!
|
||||
|
||||
# bottlenecks around 12, when the problem size starts to mushroom
|
||||
board_size = 10
|
||||
board_size = 11
|
||||
|
||||
solutions = []
|
||||
queens = []
|
||||
occupied = board_size*[0,]
|
||||
|
||||
|
||||
|
||||
def explore(depth):
|
||||
# base case
|
||||
if(depth==board_size):
|
||||
24
python/nqueens/prof_python_cprof.sh
Executable file
24
python/nqueens/prof_python_cprof.sh
Executable file
@@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Profile the N queens problem using cProfile
|
||||
|
||||
export RIGHTNOW="`date +"%Y%m%d_%H%M%S"`"
|
||||
export OUT="outfile_prof_nqueens_python_${RIGHTNOW}.out"
|
||||
|
||||
for N in 8 9 10 11
|
||||
do
|
||||
|
||||
echo "**************************************" >> ${OUT}
|
||||
echo "Profiling $N queens problem with Python..." >> ${OUT}
|
||||
|
||||
# Update N
|
||||
/usr/local/bin/sed -i "s/board_size = [0-9]\{1,\}/board_size = ${N}/g" nqueens.py
|
||||
|
||||
rm -f *.pyc
|
||||
|
||||
echo "Running..."
|
||||
python pycprof_nqueens.py >> ${OUT}
|
||||
echo "Done."
|
||||
|
||||
done
|
||||
|
||||
36
python/nqueens/prof_python_lineprof.sh
Executable file
36
python/nqueens/prof_python_lineprof.sh
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# Profile the N queens problem using cProfile
|
||||
|
||||
export RIGHTNOW="`date +"%Y%m%d_%H%M%S"`"
|
||||
export OUT="outfile_prof_nqueens_python_${RIGHTNOW}.out"
|
||||
|
||||
# Add function decorator
|
||||
/usr/local/bin/sed -i "s/def explore/@profile\ndef explore/g" nqueens.py
|
||||
|
||||
for N in 8 9 10 11
|
||||
do
|
||||
|
||||
echo "**************************************" >> ${OUT}
|
||||
echo "Profiling $N queens problem with Python..." >> ${OUT}
|
||||
|
||||
# Update N
|
||||
/usr/local/bin/sed -i "s/board_size = [0-9]\{1,\}/board_size = ${N}/g" nqueens.py
|
||||
|
||||
rm -f *.pyc
|
||||
|
||||
echo "Running program via kernprof..."
|
||||
|
||||
# runs the program
|
||||
kernprof -l nqueens.py >> ${OUT}
|
||||
|
||||
# results are in nqueens.py.lprof
|
||||
python -m line_profiler nqueens.py.lprof >> ${OUT}
|
||||
|
||||
echo "Done."
|
||||
|
||||
done
|
||||
|
||||
# Remove function decorator
|
||||
/usr/local/bin/sed -i "s/@profile//g" nqueens.py
|
||||
|
||||
21
python/nqueens/pycprof_nqueens.py
Normal file
21
python/nqueens/pycprof_nqueens.py
Normal file
@@ -0,0 +1,21 @@
|
||||
print "*******************************"
|
||||
print "cProfile:"
|
||||
print "*******************************"
|
||||
|
||||
import pstats, StringIO
|
||||
import cProfile
|
||||
pr = cProfile.Profile()
|
||||
pr.enable()
|
||||
import nqueens
|
||||
pr.disable()
|
||||
|
||||
## Simple
|
||||
#pr.dump_stats('stats.file')
|
||||
#pr.print_stats()
|
||||
|
||||
# Complicated
|
||||
s = StringIO.StringIO()
|
||||
sortby = 'time'
|
||||
ps = pstats.Stats(pr, stream=s).sort_stats(sortby)
|
||||
ps.print_stats()
|
||||
print s.getvalue()
|
||||
@@ -6,8 +6,8 @@ touch ${OUT}
|
||||
cat /dev/null > ${OUT}
|
||||
|
||||
#for N in 8 9 10 11 12 13 14 15
|
||||
#for N in 8 9 10 11 12
|
||||
for N in 13 14
|
||||
#for N in 12 13 14
|
||||
for N in 8 9 10 11
|
||||
do
|
||||
echo "**************************************" >> ${OUT}
|
||||
echo "Running $N queens problem with Python..." >> ${OUT}
|
||||
@@ -15,6 +15,8 @@ do
|
||||
# Update N
|
||||
/usr/local/bin/sed -i "s/board_size = [0-9]\{1,\}/board_size = ${N}/g" nqueens.py
|
||||
|
||||
rm -f *.pyc
|
||||
|
||||
# Semicolon is important here
|
||||
echo "Running..."
|
||||
{ time python time_nqueens.py >> ${OUT}; } 2>> ${OUT}
|
||||
@@ -1,7 +0,0 @@
|
||||
import cProfile
|
||||
pr = cProfile.Profile()
|
||||
pr.enable()
|
||||
import nqueens
|
||||
pr.disable()
|
||||
|
||||
pr.print_stats()
|
||||
Reference in New Issue
Block a user