Skip to content

Commit 22c7e9f

Browse files
implemented recursive best pancake flip order solver
1 parent 77f3679 commit 22c7e9f

File tree

9 files changed

+261
-86
lines changed

9 files changed

+261
-86
lines changed

number-generator.js

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
'use strict';
2+
3+
var amountOfNumbers = 20;
4+
5+
var n = [];
6+
for (var i = 0; i < amountOfNumbers; i++) {
7+
n[i] = i + 1;
8+
}
9+
10+
shuffle(n);
11+
console.log(n.toString());
12+
13+
function shuffle(a) {
14+
var j, x, i;
15+
for (i = a.length; i; i--) {
16+
j = Math.floor(Math.random() * i);
17+
x = a[i - 1];
18+
a[i - 1] = a[j];
19+
a[j] = x;
20+
}
21+
}

pom.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,14 @@
77
<groupId>parallel-computing-mpj</groupId>
88
<artifactId>parallel-computing-mpj</artifactId>
99
<version>1.0-SNAPSHOT</version>
10+
<dependencies>
11+
<dependency>
12+
<groupId>junit</groupId>
13+
<artifactId>junit</artifactId>
14+
<version>4.8.1</version>
15+
<scope>test</scope>
16+
</dependency>
17+
</dependencies>
1018

1119

1220
</project>
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package ch.sebastianhaeni.pancake;
2+
3+
import java.util.List;
4+
5+
public class Main {
6+
7+
public static void main(String[] args) {
8+
9+
// Node root = new Node(new int[]{46, 53, 18, 4, 56, 11, 57, 59, 55, 25, 6, 34, 41, 13, 39, 52, 7, 33, 43, 21, 32, 51, 5, 1, 58, 49, 54, 9, 24, 17, 19, 27, 50, 42, 22, 30, 20, 3, 14, 28, 40, 10, 12, 29, 37, 8, 36, 2, 26, 38, 16, 60, 15, 48, 35, 45, 31, 44, 23, 47}, 0);
10+
// Node root = new Node(new int[]{2, 6, 10, 5, 1, 3, 8, 4, 7, 9}, 0);
11+
// Node root = new Node(new int[]{1, 2, 3}, 0);
12+
// Node root = new Node(new int[]{11, 7, 15, 6, 17, 3, 19, 16, 4, 10, 8, 12, 20, 14, 2, 5, 1, 9, 13, 18}, 0);
13+
Node root = new Node(new int[]{5, 2, 7, 10, 13, 16, 14, 6, 8, 15, 11, 1, 12, 3, 4, 9}, 0);
14+
15+
long start = System.currentTimeMillis();
16+
Node solution = solve(root);
17+
long end = System.currentTimeMillis();
18+
19+
System.out.println((end - start) + "ms passed");
20+
21+
if (solution == null) {
22+
System.out.println("No solution found");
23+
return;
24+
}
25+
System.out.println("Found solution after " + solution.getFlipCount() + " flips.");
26+
}
27+
28+
private static Node solve(Node root) {
29+
if (root.isSolution()) {
30+
return root;
31+
}
32+
33+
Node solutionNode = null;
34+
int bound = root.getOptimisticDistanceToSolution();
35+
int maxBound = bound * 10;
36+
37+
while (solutionNode == null) {
38+
SearchResult result = search(root, bound);
39+
40+
if (result.solutionNode != null) {
41+
solutionNode = result.solutionNode;
42+
}
43+
44+
if (result.bound >= maxBound) {
45+
return null;
46+
}
47+
48+
bound = result.bound;
49+
}
50+
51+
return solutionNode;
52+
}
53+
54+
private static SearchResult search(Node node, int bound) {
55+
int newBound = node.getFlipCount() + node.getOptimisticDistanceToSolution();
56+
57+
if (newBound > bound) {
58+
return new SearchResult(newBound);
59+
}
60+
61+
if (node.isSolution()) {
62+
return new SearchResult(node);
63+
}
64+
65+
int min = Integer.MAX_VALUE;
66+
List<Node> successors = node.nextNodes();
67+
68+
for (Node successor : successors) {
69+
SearchResult result = search(successor, bound);
70+
71+
if (result.solutionNode != null) {
72+
return result;
73+
}
74+
75+
if (result.bound < min) {
76+
min = result.bound;
77+
}
78+
}
79+
80+
return new SearchResult(min);
81+
}
82+
83+
}
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
package ch.sebastianhaeni.pancake;
2+
3+
import java.util.AbstractList;
4+
import java.util.ArrayList;
5+
import java.util.List;
6+
7+
class Node {
8+
private final int[] pancakes;
9+
private final int flipCount;
10+
11+
Node(int[] pancakes, int flipCount) {
12+
this.pancakes = pancakes;
13+
this.flipCount = flipCount;
14+
}
15+
16+
int getOptimisticDistanceToSolution() {
17+
int distance = 0;
18+
int current = 1;
19+
20+
for (int i = 1; i < pancakes.length; i++) {
21+
int pancake = pancakes[i];
22+
if (Math.abs(pancake - current) != 1) {
23+
distance++;
24+
}
25+
current = pancake;
26+
}
27+
28+
return distance;
29+
}
30+
31+
int getFlipCount() {
32+
return flipCount;
33+
}
34+
35+
boolean isSolution() {
36+
int current = 1;
37+
38+
for (int i = 1; i < pancakes.length; i++) {
39+
int pancake = pancakes[i];
40+
if (pancake - current != 1) {
41+
return false;
42+
}
43+
current = pancake;
44+
}
45+
46+
return true;
47+
}
48+
49+
List<Node> nextNodes() {
50+
AbstractList<Node> list = new ArrayList<>();
51+
52+
int current = pancakes[1];
53+
54+
for (int i = 1; i < pancakes.length; i++) {
55+
int pancake = pancakes[i];
56+
if (pancake - current != 1) {
57+
list.add(flip(i + 1));
58+
}
59+
current = pancake;
60+
}
61+
62+
return list;
63+
}
64+
65+
Node flip(int flipPosition) {
66+
67+
int[] flipped = new int[pancakes.length];
68+
69+
for (int i = 0; i < flipPosition; i++) {
70+
flipped[i] = pancakes[flipPosition - i - 1];
71+
}
72+
73+
System.arraycopy(pancakes, flipPosition, flipped, flipPosition, pancakes.length - flipPosition);
74+
75+
return new Node(flipped, getFlipCount() + 1);
76+
}
77+
78+
int[] getPancakes() {
79+
return pancakes;
80+
}
81+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package ch.sebastianhaeni.pancake;
2+
3+
class SearchResult {
4+
Node solutionNode;
5+
int bound;
6+
7+
SearchResult(Node node) {
8+
this.solutionNode = node;
9+
}
10+
11+
SearchResult(int bound) {
12+
this.bound = bound;
13+
}
14+
}

src/main/java/idaStar/Main.java

Lines changed: 0 additions & 53 deletions
This file was deleted.

src/main/java/idaStar/Node.java

Lines changed: 0 additions & 20 deletions
This file was deleted.

src/main/java/idaStar/SearchResult.java

Lines changed: 0 additions & 13 deletions
This file was deleted.
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package ch.sebastianhaeni.pancake;
2+
3+
import org.junit.Test;
4+
5+
import java.util.List;
6+
7+
import static junit.framework.Assert.assertEquals;
8+
import static org.junit.Assert.*;
9+
10+
public class NodeTest {
11+
12+
@Test
13+
public void testFlip1() {
14+
Node node = new Node(new int[]{1, 2}, 0);
15+
Node flip = node.flip(1);
16+
assertArrayEquals(new int[]{1, 2}, flip.getPancakes());
17+
}
18+
19+
@Test
20+
public void testFlip2() {
21+
Node node = new Node(new int[]{1, 2, 3}, 0);
22+
Node flip = node.flip(2);
23+
assertArrayEquals(new int[]{2, 1, 3}, flip.getPancakes());
24+
}
25+
26+
@Test
27+
public void testFlip3() {
28+
Node node = new Node(new int[]{2, 6, 10, 5, 1, 3, 8, 4, 7, 9}, 0);
29+
Node flip = node.flip(5);
30+
assertArrayEquals(new int[]{1, 5, 10, 6, 2, 3, 8, 4, 7, 9}, flip.getPancakes());
31+
}
32+
33+
@Test
34+
public void testIsSolution1() {
35+
Node node = new Node(new int[]{1, 2, 3}, 0);
36+
assertTrue(node.isSolution());
37+
}
38+
39+
@Test
40+
public void testIsSolution2() {
41+
Node node = new Node(new int[]{2, 1, 3}, 0);
42+
assertFalse(node.isSolution());
43+
}
44+
45+
@Test
46+
public void testNextNodes() {
47+
Node node = new Node(new int[]{2, 1, 3}, 0);
48+
List<Node> nodes = node.nextNodes();
49+
50+
assertEquals(2, nodes.size());
51+
assertArrayEquals(nodes.get(0).getPancakes(), new int[]{1, 2, 3});
52+
assertArrayEquals(nodes.get(1).getPancakes(), new int[]{3, 1, 2});
53+
}
54+
}

0 commit comments

Comments
 (0)