mercredi 30 octobre 2019

How to define a shortest path problem with preconditions in Java

I'm trying to develop a program like a planner. This means that for each node has to decide which action is better and go on with that path. However, for now I'm stucked at the first decision node after the start. This decision has to depend on the minimum action cost and on if the action precondition are respected. With my code I had success in the minimum action cost, but the precondition are not working good yet.

I have defined an array of all the actions, and with a for cycle I check which is the one with lower cost. After, I have implemented an if statement to verify the precondition. This precondition is based on the previous state parameter and on a check to choose the right action to do.

This is my code, with a main class, an action class and a state class(and a node one but is not relevant for this).

public class Action {

         int actionCost;    
        static String actParameter1;
        static String actParameter2;
        static String actParameter3;
        static String actParameter4;
        static String actParameter5;
        public String name;


    public Action(String name1, String pkg1Loc, String pkg2Loc, String truckLoc, String planeLoc, String city1, int cost) {

        actParameter1 = pkg1Loc;
        actParameter2 = pkg2Loc;
        actParameter3 = truckLoc;
        actParameter4 = planeLoc;
        actParameter5 = city1;

        actionCost = cost;
        name = name1;

    }

/*  public boolean loadPlaneP1Precondition() {

        if(State.stateParameter1 == State.pkg1Location[0]) {
            if(State.stateParameter4 == State.planeLocation[0]) {
                if(State.stateParameter5 == State.cityLocation[0]) {
                    if(Action.actParameter1 == State.pkg1Location[1]) {
                        if(Action.actParameter2 == State.pkg2Location[0]) {
                            if(Action.actParameter4 == State.planeLocation[0]) {
                                return true;
                            }else {
                                return false;
                                  }
                        }else {
                            return false;
                              }
                    }else {
                        return false;
                          }
                }else {
                    return false;
                      }
            }else {
                return false;
                  }     
        }else {
            return false;
             }
    }
    */

public boolean loadPlaneP1Precondition() {

        if(Action.actParameter1 == State.pkg1Location[1]) {
            return true;
        }else {
            return false;
        }
}



    public String getActParameter1() {
        return actParameter1;
    }

    public String getActParameter2() {
        return actParameter2;
    }

    public String getActParameter3() {
        return actParameter3;
    }

    public String getActParameter4() {
        return actParameter4;
    }

    public String getActParameter5() {
        return actParameter5;
    }

    public int getActionCost() {
        return actionCost;
    }
}

The loadPlaneP1 commented precondition is the completed one, but is not working. So I defined just a small version of that with just one action check and is still not working(with only the state checks works).

public class State {

            static String[] pkg1Location = {"lhr","plane", "cdg", "truck", "south","north"};
            static String[] pkg2Location = {"lhr","plane", "cdg", "truck", "south","north"};
            static String[] truckLocation = {"cdg","driving", "south", "north"};
            static String[] planeLocation = {"lhr","flying","cdg"};
            static String[] parisLocation = {"north", "south"};
            static String[] cityLocation = {"london", "paris"};
            static String parisAirport = "cdg";
            static String londonAirport = "lhr";


            int stateValue; 
            static String stateParameter1;
            static String stateParameter2;
            static String stateParameter3;
            static String stateParameter4;
            static String stateParameter5;


    public State(int number, String pkg1Loc, String pkg2Loc, String truckLoc, String planeLoc, String cityLoc) {

        stateParameter1 = pkg1Loc;
        stateParameter2 = pkg2Loc;
        stateParameter3 = truckLoc;
        stateParameter4 = planeLoc;
        stateParameter5 = cityLoc;

        stateValue = number;

    }


    public String getStateParameter1() {
        return stateParameter1;
    }

    public void setStateParameter1(String x) {
         stateParameter1 = x;
    }

    public String getStateParameter2() {
        return stateParameter2;
    }

    public void setStateParameter2(String x) {
         stateParameter2 = x;
    }

    public String getStateParameter3() {
        return stateParameter3;
    }

    public void setStateParameter3(String x) {
         stateParameter3 = x;
    }

    public String getStateParameter4() {
        return stateParameter4;
    }

    public void setStateParameter4(String x) {
         stateParameter4 = x;
    }

    public String getStateParameter5() {
        return stateParameter5;
    }

    public void setStateParameter5(String x) {
         stateParameter5 = x;
    }

    public int getStateValue() {
        return stateValue;
    }

This is the state class

public class Main {


    private static String[] pkg1Location = {"lhr","plane", "cdg", "truck", "south","north"};
    private static String[] pkg2Location = {"lhr","plane", "cdg", "truck", "south","north"};
    private static String[] truckLocation = {"cdg", "driving", "north","south"};
    private static String[] planeLocation = {"lhr","flying","cdg"};
    private static String[] parisLocation = {"north", "south"};
    private static String[] cityLocation = {"london", "paris"};
    private static String cdgAirport = "paris";
    private static String lhrAirport = "london";


    private static Node nodeStatus;

    private static Action nextAction;


    //actions with effects
    static Action loadPlaneP1 = new Action("loadPlaneP1",pkg1Location[1], pkg2Location[0], truckLocation[0], planeLocation[0], cityLocation[0], 30);
    static Action loadPlaneP2 = new Action("loadPlaneP2", pkg1Location[0], pkg2Location[1], truckLocation[0], planeLocation[0], cityLocation[0], 40);
    static Action fly = new Action("fly",pkg1Location[1], pkg2Location[1], truckLocation[0], planeLocation[1], cityLocation[0], 100);
    static Action unloadPlaneP1 = new Action("unloadPlaneP1",pkg1Location[2], pkg2Location[1], truckLocation[0], planeLocation[2], cityLocation[1], 50);
    static Action unloadPlaneP2 = new Action("unloadPlaneP2",pkg1Location[1], pkg2Location[2], truckLocation[0], planeLocation[2], cityLocation[1], 55);
    static Action loadTruckP1 = new Action("loadTruckP1",pkg1Location[3], pkg2Location[2], truckLocation[0], planeLocation[2], cityLocation[1], 60);
    static Action loadTruckP2 = new Action("loadTruckP2",pkg1Location[2], pkg2Location[3], truckLocation[0], planeLocation[2], cityLocation[1], 60);
    static Action drive = new Action("drive",pkg1Location[3], pkg2Location[3], truckLocation[1], planeLocation[2], cityLocation[1], 70);
    static Action unloadTruckP1 = new Action("unloadTruckP1", pkg1Location[5], pkg2Location[5], truckLocation[2], planeLocation[2], cityLocation[1], 40);
    static Action unloadTruckP2 = new Action("unloadTruckP2",pkg1Location[4], pkg2Location[4], truckLocation[3], planeLocation[2], cityLocation[1], 43);

    static State goal = new State(11, pkg1Location[5], pkg2Location[4], truckLocation[3], planeLocation[2], cityLocation[1]);

    static Action[] acts = {loadPlaneP1, loadPlaneP2, fly, unloadPlaneP1, unloadPlaneP2, loadTruckP1, loadTruckP2, drive, unloadTruckP1, unloadTruckP2 };


    public static void main(String args[]) {



    State state = new State(0, pkg1Location[0], pkg2Location[0], truckLocation[0], planeLocation[0], cityLocation[0]);

    Node startNode = new Node(state, 0);

    nodeStatus = startNode;


     int[] costs = {loadPlaneP1.getActionCost(), loadPlaneP2.getActionCost(), fly.getActionCost(), unloadPlaneP1.getActionCost(), unloadPlaneP2.getActionCost(), loadTruckP1.getActionCost(), loadTruckP2.getActionCost(), drive.getActionCost(), unloadTruckP1.getActionCost(), unloadTruckP2.getActionCost()};

     //HERE STARTS THE MECHANISM

     if(nodeStatus == startNode) {


        System.out.println("Old state parameters are " + "pkg1Location: " + state.getStateParameter1() + " pkg2Location: " + state.getStateParameter2() + " truckLocation: "+ state.getStateParameter3() + " planeLocation: " + state.getStateParameter4() + " cityLocation:"+ state.getStateParameter5());



                 for(int i = 0; acts[i].getActionCost() == getMinValue(costs); i++) {


                     //THIS IS THE PRECONDITION THAT IS NOT WORKING, DEFINED IN THE ACTION CLASS

                 if(acts[i].loadPlaneP1Precondition() == true) {

                     System.out.println("Precondition satysfied" + " with action name: " + acts[i].name);

                     if(acts[i].getActParameter1() != state.getStateParameter1()) {

                         state.setStateParameter1(acts[i].getActParameter1());
                     }

                     if(acts[i].getActParameter2() != state.getStateParameter2()) {

                         state.setStateParameter2(acts[i].getActParameter2());
                     }

                     if(acts[i].getActParameter3() != state.getStateParameter3()) {

                         state.setStateParameter3(acts[i].getActParameter3());
                     }

                     if(acts[i].getActParameter4() != state.getStateParameter4()) {

                         state.setStateParameter4(acts[i].getActParameter4());
                     }

                     if(acts[i].getActParameter5() != state.getStateParameter5()) {

                         state.setStateParameter5(acts[i].getActParameter5());
                     }
                 }

                         Node child = new Node(state, startNode, acts[i].getActionCost());


                        /*    List<Action> removeList = new ArrayList<Action>(Arrays.asList(acts));
                            removeList.remove(Arrays.asList(i));
                            acts = removeList.toArray(acts);*/


                         //nextAction = acts[i];

                         System.out.println("Costs array: "+  Arrays.toString(costs));
                         System.out.println("ActionID" +" " +  i);
                         System.out.println("The action choosen is " + acts[i].name);
                         System.out.println("State parameters updated are " + "pkg1Location: " + state.getStateParameter1() + " pkg2Location: " + state.getStateParameter2() + " truckLocation: "+ state.getStateParameter3() + " planeLocation: " + state.getStateParameter4() + " cityLocation:"+ state.getStateParameter5());

                     };




                     }  





            }

This is the main. The result that I obtain is

Old state parameters are pkg1Location: lhr pkg2Location: lhr truckLocation: cdg planeLocation: lhr cityLocation:london
Costs array: [30, 40, 100, 50, 55, 60, 60, 70, 40, 43]
ActionID 0
The action choosen is loadPlaneP1
State parameters updated are pkg1Location: lhr pkg2Location: lhr truckLocation: cdg planeLocation: lhr cityLocation:london       

This show that the precondtion is not satysfied and for this reason the state is not updated. The precondition that I developed is veryfied only if I define like this

public boolean loadPlaneP1Precondition() {

            if(Action.actParameter1 == State.pkg1Location[4]) {
                return true;
            }else {
                return false;
            }
    }

With this result

Old state parameters are pkg1Location: lhr pkg2Location: lhr truckLocation: cdg planeLocation: lhr cityLocation:london
Precondition satysfied with action name: loadPlaneP1
Costs array: [30, 40, 100, 50, 55, 60, 60, 70, 40, 43]
ActionID 0
The action choosen is loadPlaneP1
State parameters updated are pkg1Location: south pkg2Location: south truckLocation: south planeLocation: cdg cityLocation:paris

This means that the action that verify the precondition is loadTruckP2(the last of the array). But the action name printed is loadPlaneP1(the one that should be correct), updating differently that states parameter.

Why is this happening?

Aucun commentaire:

Enregistrer un commentaire