Skip to content

Commit 7db19bc

Browse files
fixed gap calculation
1 parent 8596bd1 commit 7db19bc

File tree

7 files changed

+62
-45
lines changed

7 files changed

+62
-45
lines changed

src/main/java/ch/sebastianhaeni/pancake/IterativeSolver.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ private IterativeSolver() {
1616

1717
public static void main(String[] args) {
1818

19-
Node root = new Node(Generator.alternate(20));
20-
// Node root = new Node(Generator.random(40));
19+
Node root = new Node(Generator.alternate(14));
20+
// Node root = new Node(Generator.alternate(20));
21+
// Node root = new Node(Generator.random(25));
2122

2223
System.out.format("Solving a pancake pile of height %d.\n", root.getState().length);
2324

@@ -33,12 +34,13 @@ private static void solve(Node root) {
3334
NODES.push(root);
3435
NODES.peek().nextNodes();
3536

36-
int bound = root.getDistance();
37+
int bound = root.getGap();
38+
System.out.println("Searching with bound " + bound);
3739
int candidateBound = Integer.MAX_VALUE;
3840

39-
while (NODES.peek().gap() > 0) {
40-
if (NODES.peek().getDistance() + NODES.peek().getDepth() > bound) {
41-
int stateBound = NODES.peek().getDepth() + NODES.peek().getDistance();
41+
while (NODES.peek().getGap() > 0) {
42+
int stateBound = NODES.peek().getGap() + NODES.peek().getDepth();
43+
if (stateBound > bound) {
4244
if (stateBound < candidateBound) {
4345
candidateBound = stateBound;
4446
}

src/main/java/ch/sebastianhaeni/pancake/ParallelSolver.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ public final class ParallelSolver {
1111
public static final int CONTROLLER_RANK = 0;
1212
public static final int[] EMPTY_BUFFER = new int[0];
1313

14-
private static final int[] INITIAL_STATE = Generator.random(30);
14+
// private static final int[] INITIAL_STATE = Generator.random(30);
15+
private static final int[] INITIAL_STATE = Generator.alternate(14);
1516
/*
1617
private static final int[] INITIAL_STATE = {7, 13, 21, 4, 16, 31, 30, 35, 40, 23, 8, 19, 33, 24, 38, 28, 29, 14, 26, 6, 25, 32, 1, 3, 5, 22, 37, 9, 20, 2, 10, 34, 18, 17, 11, 27, 12, 15, 39, 36}; // 40
1718
private static final int[] INITIAL_STATE = {3, 4, 2, 5, 1}; // 5

src/main/java/ch/sebastianhaeni/pancake/model/Node.java

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,9 @@ public class Node implements Serializable {
2525
private final Stack<Node> children = new Stack<>();
2626

2727
/**
28-
* Pancake pile size.
28+
* Gap heuristic value.
2929
*/
30-
private final int size;
31-
private int distance;
30+
private final int gap;
3231

3332
public Node(int[] state) {
3433
this(state, 0);
@@ -37,62 +36,75 @@ public Node(int[] state) {
3736
private Node(int[] state, int depth) {
3837
this.state = state;
3938
this.depth = depth;
40-
this.size = state.length;
41-
this.distance = gap();
39+
this.gap = gap();
4240
}
4341

44-
public Node(int[] state, int depth, int distance) {
42+
public Node(int[] state, int depth, int gap) {
4543
this.state = state;
4644
this.depth = depth;
47-
this.size = state.length;
48-
this.distance = distance;
45+
this.gap = gap;
4946
}
5047

51-
public int gap() {
48+
private int gap() {
5249
int gap = 0;
5350

54-
for (int i = 0; i < size - 1; i++) {
55-
if (state[i] - state[i + 1] != -1) {
51+
for (int i = 1; i < state.length; i++) {
52+
if (Math.abs(state[i] - state[i - 1]) > 1) {
5653
gap++;
5754
}
5855
}
5956
return gap;
6057
}
6158

59+
/**
60+
* Expands this node.
61+
*/
6262
public void nextNodes() {
63-
for (int i = 2; i < size; i++) {
64-
if (state[i] - state[0] == 1) {
65-
children.push(flip(i, distance - 1));
66-
} else {
67-
children.push(flip(i, distance));
63+
for (int i = 2; i < state.length; i++) {
64+
int gap = this.gap;
65+
66+
int currentDiff = Math.abs(state[i] - state[i - 1]);
67+
int newDiff = Math.abs(state[i] - state[0]);
68+
69+
if (currentDiff != 1 && newDiff == 1) {
70+
gap -= 1;
71+
} else if (currentDiff == 1 && newDiff != 1) {
72+
gap += 1;
6873
}
74+
75+
children.push(flip(i, gap));
6976
}
7077
}
7178

7279
/**
7380
* Flips the prefix at the defined flip position.
7481
*
7582
* @param flipPosition the position where the state shall be reversed
76-
* @param distance predetermined optimistic distance for the new nodes
83+
* @param gap predetermined optimistic gap for the new node
7784
* @return prefix reversed state
7885
*/
79-
Node flip(int flipPosition, int distance) {
86+
Node flip(int flipPosition, int gap) {
8087

81-
int[] flipped = new int[size];
88+
int[] flipped = new int[state.length];
8289

8390
for (int i = 0; i < flipPosition; i++) {
8491
flipped[i] = state[flipPosition - i - 1];
8592
}
8693

87-
System.arraycopy(state, flipPosition, flipped, flipPosition, size - flipPosition);
94+
System.arraycopy(state, flipPosition, flipped, flipPosition, state.length - flipPosition);
8895

89-
return new Node(flipped, getDepth() + 1, distance);
96+
return new Node(flipped, getDepth() + 1, gap);
9097
}
9198

99+
/**
100+
* Augments the state of this node. An additional item is added at the end of the state.
101+
*
102+
* @return new instanced node with augmented state
103+
*/
92104
public Node augment() {
93-
int[] augmentedState = new int[size + 1];
94-
System.arraycopy(state, 0, augmentedState, 0, size);
95-
augmentedState[size] = size + 1;
105+
int[] augmentedState = new int[state.length + 1];
106+
System.arraycopy(state, 0, augmentedState, 0, state.length);
107+
augmentedState[state.length] = state.length + 1;
96108
return new Node(augmentedState, getDepth());
97109
}
98110

@@ -104,12 +116,11 @@ public int[] getState() {
104116
return state;
105117
}
106118

107-
public int getDistance() {
108-
return distance;
109-
}
110-
111119
public Stack<Node> getChildren() {
112120
return children;
113121
}
114122

123+
public int getGap() {
124+
return gap;
125+
}
115126
}

src/main/java/ch/sebastianhaeni/pancake/processor/Controller.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ private boolean solve() {
7272

7373
initialWork();
7474

75-
if (stack.peek().gap() == 0) {
75+
if (stack.peek().getGap() == 0) {
7676
return true;
7777
}
7878

@@ -138,15 +138,15 @@ private void clearListeners() {
138138

139139
private void initialWork() {
140140
if (bound < 0) {
141-
bound = stack.peek().getDistance();
141+
bound = stack.peek().getGap();
142142
}
143143
candidateBound = Integer.MAX_VALUE;
144144

145145
int i = 0;
146-
while (stack.peek().gap() > 0 && i < INITIAL_WORK_DEPTH) {
146+
while (stack.peek().getGap() > 0 && i < INITIAL_WORK_DEPTH) {
147147
i++;
148-
if (stack.peek().getDistance() + stack.peek().getDepth() > bound) {
149-
int stateBound = stack.peek().getDepth() + stack.peek().getDistance();
148+
int stateBound = stack.peek().getGap() + stack.peek().getDepth();
149+
if (stateBound > bound) {
150150
if (stateBound < candidateBound) {
151151
candidateBound = stateBound;
152152
}

src/main/java/ch/sebastianhaeni/pancake/processor/Worker.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ public void run() {
3838

3939
waitForWork();
4040

41-
while (!stack.isEmpty() && stack.peek().gap() > 0 && !status.isDone()) {
41+
while (!stack.isEmpty() && stack.peek().getGap() > 0 && !status.isDone()) {
4242
solve();
4343
}
4444

@@ -61,9 +61,9 @@ private void listenToKill() {
6161
private void solve() {
6262
candidateBound = Integer.MAX_VALUE;
6363

64-
while (!stack.isEmpty() && stack.peek().gap() > 0 && !status.isDone()) {
65-
if (stack.peek().getDistance() + stack.peek().getDepth() > bound) {
66-
int stateBound = stack.peek().getDepth() + stack.peek().getDistance();
64+
while (!stack.isEmpty() && stack.peek().getGap() > 0 && !status.isDone()) {
65+
int stateBound = stack.peek().getGap() + stack.peek().getDepth();
66+
if (stateBound > bound) {
6767
if (stateBound < candidateBound) {
6868
candidateBound = stateBound;
6969
}

src/main/java/ch/sebastianhaeni/pancake/util/Output.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ public static void showSolution(Vector<Node> nodes) {
3838
}
3939
}
4040

41+
// sb.append(", gap: ");
42+
// sb.append(nodes.get(i).getGap());
43+
4144
System.out.format("state %d: %s\n", i, sb.toString());
4245
}
4346
}

src/main/java/ch/sebastianhaeni/pancake/util/Partition.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public Stack<Node> get(int index) {
1717
Stack<Node> nodes = new Stack<>();
1818

1919
for (Node node : stack) {
20-
Node element = new Node(node.getState(), node.getDepth(), node.getDistance());
20+
Node element = new Node(node.getState(), node.getDepth(), node.getGap());
2121
nodes.push(element);
2222

2323
for (int i = node.getChildren().size() - 1 - index; i >= 0; i -= partitionCount) {

0 commit comments

Comments
 (0)