Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for complex actions #304

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package aima.core.search.basic.support;

import aima.core.search.api.BidirectionalActions;
import aima.core.search.api.SearchController;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
Expand All @@ -13,10 +15,14 @@ public class BasicBidirectionalActions<A> implements BidirectionalActions<A> {
private List<A> fromGoalStatePartList = new ArrayList<>();
private List<A> fromInitialStateToGoalStateList = new ArrayList<>();
private List<A> fromGoalStateToInitialStateList = new ArrayList<>();
private List<A> fromMeetingStateToGoalStateList = new ArrayList<>();
private List<A> fromMeetingStateToInitialStateList = new ArrayList<>();

public BasicBidirectionalActions(List<A> fromInitialStatePartList, List<A> fromGoalStatePartList) {
public BasicBidirectionalActions(List<A> fromInitialStatePartList, List<A> fromGoalStatePartList,List<A> fromMeetingStateToInitialStateList,List<A> fromMeetingStateToGoalStateList) {
this.fromInitialStatePartList = fromInitialStatePartList;
this.fromGoalStatePartList = fromGoalStatePartList;
this.fromMeetingStateToGoalStateList = fromMeetingStateToGoalStateList;
this.fromMeetingStateToInitialStateList= fromMeetingStateToInitialStateList;
}

private void init() {
Expand All @@ -36,21 +42,17 @@ public List<A> fromGoalStatePart() {

@Override
public List<A> fromInitialStateToGoalState() {
List<A> reversedFromGoalStatePart = new ArrayList<>(fromGoalStatePart());
Collections.reverse(reversedFromGoalStatePart);
init();
fromInitialStateToGoalStateList.addAll(fromInitialStatePart());
fromInitialStateToGoalStateList.addAll(reversedFromGoalStatePart);
fromInitialStateToGoalStateList.addAll(fromMeetingStateToGoalStateList);
return fromInitialStateToGoalStateList;
}

@Override
public List<A> fromGoalStateToInitialState() {
List<A> reversedFromInitialStatePart = new ArrayList<>(fromInitialStatePart());
Collections.reverse(reversedFromInitialStatePart);
init();
fromGoalStateToInitialStateList.addAll(fromGoalStatePart());
fromGoalStateToInitialStateList.addAll(reversedFromInitialStatePart);
fromGoalStateToInitialStateList.addAll(fromMeetingStateToInitialStateList);
return fromGoalStateToInitialStateList;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
import java.util.List;
import java.util.Map;
import java.util.Queue;

import java.util.LinkedList;
/**
* Artificial Intelligence A Modern Approach (4th Edition): Figure ??, page ??.
* <br>
Expand All @@ -35,14 +35,16 @@ public class BidirectionalSearch<A, S> implements SearchForActionsBidirectionall
private Node<A, S> meetingOfTwoFrontiers;
private Node<A, S> nextNodeToBeEvaluated;
private boolean fromFront;
private Problem<A, S> problem;
@Override

public BidirectionalActions<A> apply(Problem<A, S> originalProblem, Problem<A, S> reverseProblem) {
problem = originalProblem;
Node<A, S> node = newRootNode(originalProblem.initialState(), 0);
if (originalProblem.isGoalState(node.state())) {
this.previousMeetingOfTwoFrontiers = node;
this.nextNodeToBeEvaluated = null;
bidirectionalActions = new BasicBidirectionalActions<>(fromInitialStatePart(), fromGoalStatePart());
bidirectionalActions = new BasicBidirectionalActions<>(fromInitialStatePart(), fromGoalStatePart(), fromMeetingStateToInitialState(), fromMeetingStateToGoalState());
return bidirectionalActions;
}
Node<A, S> revNode = newRootNode(reverseProblem.initialState(), 0);
Expand All @@ -55,16 +57,16 @@ public BidirectionalActions<A> apply(Problem<A, S> originalProblem, Problem<A, S

// Existence of path is checked from both ends of the problem.
if (isSolution(pathExistsBidirectional(front, exploredFront, exploredBack, originalProblem), true)) {
bidirectionalActions = new BasicBidirectionalActions<>(fromInitialStatePart(), fromGoalStatePart());
bidirectionalActions = new BasicBidirectionalActions<>(fromInitialStatePart(), fromGoalStatePart(), fromMeetingStateToInitialState(), fromMeetingStateToGoalState());
return bidirectionalActions;
}
if (isSolution(pathExistsBidirectional(back, exploredBack, exploredFront, reverseProblem), false)) {
bidirectionalActions = new BasicBidirectionalActions<>(fromInitialStatePart(), fromGoalStatePart());
bidirectionalActions = new BasicBidirectionalActions<>(fromInitialStatePart(), fromGoalStatePart(), fromMeetingStateToInitialState(), fromMeetingStateToGoalState());
return bidirectionalActions;
}
}
this.previousMeetingOfTwoFrontiers = null;
bidirectionalActions = new BasicBidirectionalActions<>(fromInitialStatePart(), fromGoalStatePart());
bidirectionalActions = new BasicBidirectionalActions<>(fromInitialStatePart(), fromGoalStatePart(), fromMeetingStateToInitialState(), fromMeetingStateToGoalState());
return bidirectionalActions;
}

Expand Down Expand Up @@ -167,4 +169,44 @@ private List<A> fromGoalStatePart() {
return fromGoalStatePartList;
}
}

private List<A> fromMeetingStateToInitialState() {
if (this.previousMeetingOfTwoFrontiers == null || this.nextNodeToBeEvaluated == null)
return failure();
if (!this.fromFront) {
return buildPath(this.nextNodeToBeEvaluated);
} else {
return buildPath(this.meetingOfTwoFrontiers);
}
}

private List<A> fromMeetingStateToGoalState() {
if (this.previousMeetingOfTwoFrontiers == null || this.nextNodeToBeEvaluated == null)
return failure();
if (this.fromFront) {
return buildPath(this.nextNodeToBeEvaluated);
} else {
return buildPath(this.meetingOfTwoFrontiers);
}
}

private List<A> buildPath(Node<A, S> node) {
LinkedList<A> result = new LinkedList<>();
result.add(node.action());
List<A> actions;
while (node.parent() != null) {
actions = problem.actions(node.state());
Node<A, S> finalNode = node;
double pathCost = Double.POSITIVE_INFINITY;
for (A action : actions) {
Node<A, S> child = newChildNode(problem, finalNode, action);
if (finalNode.parent().state().equals(child.state()) && child.pathCost() < pathCost) {
result.add(action);
pathCost = child.pathCost();
}
}
node = node.parent();
}
return result;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,9 @@ public class BasicBidirectionalActionsTest {
public void testBasicBidirectionalActions() {
List<String> fromInitialStatePartList = Arrays.asList("start", "second", "third");
List<String> fromGoalStatePartList = Arrays.asList("goal", "fifth", "fourth");
BasicBidirectionalActions<String> basicBidirectionalActions = new BasicBidirectionalActions<>(fromInitialStatePartList, fromGoalStatePartList);
List<String> fromMeetingStateToInitialState = Arrays.asList("third", "second", "start");
List<String> fromMeetingStateToGoalState = Arrays.asList("fourth", "fifth", "goal");
BasicBidirectionalActions<String> basicBidirectionalActions = new BasicBidirectionalActions<>(fromInitialStatePartList, fromGoalStatePartList, fromMeetingStateToInitialState,fromMeetingStateToGoalState);
Assert.assertEquals(
Arrays.asList("start", "second", "third", "fourth", "fifth", "goal"),
basicBidirectionalActions.fromInitialStateToGoalState());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,16 @@ public void timisoaraToUrziceni() throws Exception {
new GoAction(ARAD),
new GoAction(SIBIU),
new GoAction(FAGARAS),
new GoAction(BUCHAREST)),
new GoAction(BUCHAREST),
new GoAction(URZICENI)),
solution.fromInitialStateToGoalState());

assertEquals(Arrays.asList(
new GoAction(BUCHAREST),
new GoAction(FAGARAS),
new GoAction(SIBIU),
new GoAction(ARAD)),
new GoAction(ARAD),
new GoAction(TIMISOARA)),
solution.fromGoalStateToInitialState());
}

Expand Down