-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* implement GCD (Euclidean algorithm) generic using Arithmetic * generate pan-diagonal latin squares when possible, else default to normal latin squares * add examples of combonatorial solutions of popular problems (eg n-queens) with sample code and notes * update readme, tests
- Loading branch information
Showing
9 changed files
with
297 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
# Combinatorial Solutions to Popular Problems using Abacus | ||
|
||
|
||
The solutions, to popular problems, below exhibit the combinatorial capabilities of solving complex combinatorial problems of `Abacus`. Sometimes a solution is found by exhaustive search, other times better than full exhaustive search can be achieved and other times the solution does not require search at all but simply smart composition and manipulation of appropriate combinatorial objects. | ||
|
||
|
||
### Contents | ||
|
||
* [N-Queens Problem](#n-queens) | ||
* [Knapsack Problem](#knapsack) | ||
* [TSP Problem](#tsp) | ||
|
||
|
||
### N-Queens | ||
|
||
[N-Queens Problem, wikipedia](https://en.wikipedia.org/wiki/Eight_queens_puzzle) | ||
|
||
see associated file: `examples/n_queens.js` | ||
|
||
**Exhaustive Search** | ||
|
||
Let's assume we have some utility methods which allow us to check if a certain potential solution configuration is valid `isValid` and also (we need that as well) a method (`toRowColumn`) to map numeric patterns of combinatorial objects to `(row,column)` pairs on a hypothetical `NxN` grid. | ||
|
||
With these utitlities available we can start directly using an exhaustive search among all configurations of placing `N` queens on distinct positions on an `NxN` grid. | ||
|
||
|
||
```javascript | ||
o = Abacus.Combination(N*N, N, {output:toRowColumn}).filterBy(isValid); | ||
|
||
echo(''+N+' Queens solutions (exhaustive search): START'); | ||
for(let solution of o) echo(solution); | ||
echo(''+N+' Queens solutions (exhaustive search): END'); | ||
``` | ||
|
||
The above (for `N=4`) gives the following output: | ||
|
||
```text | ||
4 Queens solutions (exhaustive search): START | ||
[ [ 0, 1 ], [ 1, 3 ], [ 2, 0 ], [ 3, 2 ] ] | ||
[ [ 0, 2 ], [ 1, 0 ], [ 2, 3 ], [ 3, 1 ] ] | ||
4 Queens solutions (exhaustive search): END | ||
``` | ||
|
||
**Reduced Exhaustive Search** | ||
|
||
However searching among all combinations is inefficient, we can be a little smarter and assume from the beginning that each queen is placed on different row (or column). Then we simply check among all permutations of assigning each queen on a specific (different) column. | ||
|
||
```javascript | ||
o = Abacus.Permutation(N, {output:toRowColumnP}).filterBy(isValid); | ||
|
||
echo(''+N+' Queens solutions (reduced exhaustive search): START'); | ||
for(let solution of o) echo(solution); | ||
echo(''+N+' Queens solutions (reduced exhaustive search): END'); | ||
``` | ||
The above (for `N=4`) gives the following output: | ||
|
||
```text | ||
4 Queens solutions (reduced exhaustive search): START | ||
[ [ 0, 1 ], [ 1, 3 ], [ 2, 0 ], [ 3, 2 ] ] | ||
[ [ 0, 2 ], [ 1, 0 ], [ 2, 3 ], [ 3, 1 ] ] | ||
4 Queens solutions (reduced exhaustive search): END | ||
``` | ||
|
||
**Exploiting Symmetries** | ||
|
||
If we only need to find one solution, then there is an interesting connection between **pan-diagonal latin/magic squares** and **n-queens problems**. Specificaly if we have a pan-diagonal latin or magic square of order `N` then we can have (at least) one solution for the `N` Queens problem simply by placing a queen on each cell which contains only the symbol/number `s` (whatever we choose to be). | ||
|
||
Since `Abacus` can generate `LatinSquares` and also will try to generate pan-diagonal latin squares if possible (for example for `N=5` it is possible), then we can generate a solution to the 5-Queens problem as follows: | ||
|
||
```javascript | ||
o = Abacus.LatinSquare.make(N); | ||
echo(''+N+' Queens solution (pan-diagonal latin square): START'); | ||
o.forEach(function(oi){echo(oi.map(function(x){ return N===x ? 'X' : 'O'}).join(' '));}); | ||
echo(''+N+' Queen solutions (pan-diagonal latin square): END'); | ||
``` | ||
|
||
For `N=5` we get the following output: | ||
|
||
```text | ||
5 Queens solution (pan-diagonal latin square): START | ||
O O X O O | ||
O O O O X | ||
O X O O O | ||
O O O X O | ||
X O O O O | ||
5 Queen solutions (pan-diagonal latin square): END | ||
``` | ||
|
||
We saw how we can explore and solve the N-Queens problem with a few lines of code using `Abacus` library. | ||
|
||
|
||
### Knapsack | ||
|
||
[Knapsack Problem, wikipedia](https://en.wikipedia.org/wiki/Knapsack_problem) | ||
|
||
see associated file: `examples/knapsack.js` | ||
|
||
**to be added** | ||
|
||
|
||
### TSP | ||
|
||
[Travelling Salesman Problem, wikipedia](https://en.wikipedia.org/wiki/Travelling_salesman_problem) | ||
|
||
see associated file: `examples/tsp.js` | ||
|
||
**to be added** |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
var isNode = 'undefined' !== typeof global && '[object global]' === {}.toString.call(global); | ||
var Abacus = isNode ? require('../src/js/Abacus.js') : window.Abacus, echo = console.log; | ||
|
||
var o, N; | ||
// solve exactly the Knapsack problem by Combinatorial methods using Abacus | ||
|
||
// to do |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
var isNode = 'undefined' !== typeof global && '[object global]' === {}.toString.call(global); | ||
var Abacus = isNode ? require('../src/js/Abacus.js') : window.Abacus, echo = console.log; | ||
|
||
var o, N; | ||
// solve exactly the N-queens problem by Combinatorial methods using Abacus | ||
|
||
// utility functions | ||
function toRowColumn(item) | ||
{ | ||
// convert num in 0..N^2-1 to associated row and column in NxN grid | ||
var N = item.length, i, output = new Array(N); | ||
for(i=0; i<N; i++) output[i] = [~~(item[i] / N)/* associated row*/, item[i] % N/* associated column*/]; | ||
return output; | ||
} | ||
function toRowColumnP(item) | ||
{ | ||
// convert permutation of N queens each on different row of NxN grid | ||
var N = item.length, i, output = new Array(N); | ||
for(i=0; i<N; i++) output[i] = [i/* different row */, item[i]/* permutation of column*/]; | ||
return output; | ||
} | ||
function isValid(solution) | ||
{ | ||
var N = solution.length, i, j; | ||
for(i=0; i<N; i++) | ||
{ | ||
|
||
for(j=0; j<N; j++) | ||
{ | ||
if ( i === j ) continue; | ||
if ( solution[i][0]===solution[j][0] /* same row */ || solution[i][1]===solution[j][1] /* same column */ || solution[i][0]-solution[i][1]===solution[j][0]-solution[j][1] /* same diagonal */ || solution[i][0]+solution[i][1]===solution[j][0]+solution[j][1] /* same anti-diagonal */ ) | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
N = 4; // 4-Queens | ||
// try filtering from all possible combinations of positions placed on NxN grid | ||
o = Abacus.Combination(N*N, N, {output:toRowColumn}).filterBy(isValid); | ||
|
||
echo(''+N+' Queens solutions (exhaustive search): START'); | ||
for(let solution of o) echo(solution); | ||
echo(''+N+' Queens solutions (exhaustive search): END'); | ||
|
||
echo('---'); | ||
|
||
N = 3; // 3-Queens | ||
// try filtering from all possible combinations of positions placed on NxN grid | ||
o = Abacus.Combination(N*N, N, {output:toRowColumn}).filterBy(isValid); | ||
|
||
echo(''+N+' Queens solutions (exhaustive search): START'); | ||
for(let solution of o) echo(solution); | ||
echo(''+N+' Queens solutions (exhaustive search): END'); | ||
|
||
echo('---'); | ||
|
||
N = 4; // 4-Queens | ||
// try reducing original search space by using only permutation of N!, each queen on different row | ||
o = Abacus.Permutation(N, {output:toRowColumnP}).filterBy(isValid); | ||
|
||
echo(''+N+' Queens solutions (reduced exhaustive search): START'); | ||
for(let solution of o) echo(solution); | ||
echo(''+N+' Queens solutions (reduced exhaustive search): END'); | ||
|
||
echo('---'); | ||
|
||
// for some cases can construct N-queens solution from associated pan-diagonal magic/latin squares | ||
N = 5; // 5-Queens | ||
o = Abacus.LatinSquare.make(N); | ||
echo(''+N+' Queens solution (pan-diagonal latin square): START'); | ||
o.forEach(function(oi){echo(oi.map(function(x){ return N===x ? 'X' : 'O'}).join(' '));}); | ||
echo(''+N+' Queen solutions (pan-diagonal latin square): END'); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
4 Queens solutions (exhaustive search): START | ||
[ [ 0, 1 ], [ 1, 3 ], [ 2, 0 ], [ 3, 2 ] ] | ||
[ [ 0, 2 ], [ 1, 0 ], [ 2, 3 ], [ 3, 1 ] ] | ||
4 Queens solutions (exhaustive search): END | ||
--- | ||
3 Queens solutions (exhaustive search): START | ||
3 Queens solutions (exhaustive search): END | ||
--- | ||
4 Queens solutions (reduced exhaustive search): START | ||
[ [ 0, 1 ], [ 1, 3 ], [ 2, 0 ], [ 3, 2 ] ] | ||
[ [ 0, 2 ], [ 1, 0 ], [ 2, 3 ], [ 3, 1 ] ] | ||
4 Queens solutions (reduced exhaustive search): END | ||
--- | ||
5 Queens solution (pan-diagonal latin square): START | ||
O O X O O | ||
O O O O X | ||
O X O O O | ||
O O O X O | ||
X O O O O | ||
5 Queen solutions (pan-diagonal latin square): END |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
var isNode = 'undefined' !== typeof global && '[object global]' === {}.toString.call(global); | ||
var Abacus = isNode ? require('../src/js/Abacus.js') : window.Abacus, echo = console.log; | ||
|
||
var o, N; | ||
// solve exactly the TSP problem by Combinatorial methods using Abacus | ||
|
||
// to do |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters