Advertisement
Guest User

State-Space Representation & Super Operator Design Pattern

a guest
Sep 30th, 2016
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 7.53 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Threading.Tasks;
  6.  
  7. namespace StateSpaceRepresentationUsingSuperOperatorDesignPattern
  8. {
  9.     class Program
  10.     {
  11.         static void Main(string[] args)
  12.         {
  13.             State startingState = new MonksAndCannibalsState();
  14.             BackTrack bt = new BackTrack(startingState);
  15.             Node terminalNode = bt.GraphSearch();
  16.             if (terminalNode == null) Console.WriteLine("There is no solution");
  17.             else
  18.             {
  19.                 Console.WriteLine("A solution is:");
  20.                 terminalNode.PrintPath();
  21.             }
  22.             Console.ReadLine();
  23.         }
  24.     }
  25.  
  26.     /// <summary>
  27.     /// The common interface for state-space representation
  28.     /// </summary>
  29.     abstract class State : ICloneable
  30.     {
  31.         public abstract bool IsState();
  32.         public abstract bool IsGoalState();
  33.         public abstract int GetNumberOfOperators();
  34.         public abstract bool SuperOperator(int i);
  35.         public abstract object Clone();
  36.         public override abstract bool Equals(Object a);
  37.         public override int GetHashCode() { return base.GetHashCode(); }
  38.     }
  39.     class MonksAndCannibalsState : State
  40.     {
  41.         int monksOnLeft, cannibalsOnLeft, boat, monksOnRight, cannibalsOnRight;
  42.         public MonksAndCannibalsState()
  43.         {
  44.             monksOnLeft = 3;
  45.             cannibalsOnLeft = 3;
  46.             boat = 1; // 1: left, -1: right
  47.             monksOnRight = 0;
  48.             cannibalsOnRight = 0;
  49.         }
  50.         public override object Clone() { return MemberwiseClone(); }
  51.         public override bool IsState()
  52.         {
  53.             return ((monksOnLeft >= cannibalsOnLeft) || (monksOnLeft == 0)) &&
  54.                 ((monksOnRight >= cannibalsOnRight) || (monksOnRight == 0));
  55.         }
  56.         public override bool IsGoalState()
  57.         {
  58.             return monksOnRight == 3 && cannibalsOnRight == 3 && boat == -1;
  59.         }public override int GetNumberOfOperators() { return 5; }
  60.         public override bool SuperOperator(int i)
  61.         {
  62.             switch (i)
  63.             {
  64.                 case 0: return operate(0, 1);
  65.                 case 1: return operate(0, 2);
  66.                 case 2: return operate(1, 1);
  67.                 case 3: return operate(1, 0);
  68.                 case 4: return operate(2, 0);
  69.                 default: return false;
  70.             }
  71.         }
  72.         private bool operate(int monksToMove, int cannibalsToMove)
  73.         {
  74.             if (!preCondiction(monksToMove, cannibalsToMove)) return false;
  75.             if (boat == 1)
  76.             {
  77.                 monksOnLeft -= monksToMove;
  78.                 cannibalsOnLeft -= cannibalsToMove;
  79.                 boat = -1;
  80.                 monksOnRight += monksToMove;
  81.                 cannibalsOnRight += cannibalsToMove;
  82.             }
  83.             else
  84.             {
  85.                 monksOnLeft += monksToMove;
  86.                 cannibalsOnLeft += cannibalsToMove;
  87.                 boat = 1;
  88.                 monksOnRight -= monksToMove;
  89.                 cannibalsOnRight -= cannibalsToMove;
  90.             }
  91.             if (IsState()) return true;
  92.             return false;
  93.         }
  94.         private bool preCondiction(int monksToMove, int cannibalsToMove)
  95.         {
  96.             if (monksToMove + cannibalsToMove > 2 ||
  97.                 monksToMove + cannibalsToMove < 0 ||
  98.                 monksToMove < 0 || cannibalsToMove < 0) return false;
  99.             if (boat == 1)
  100.                 return monksOnLeft >= monksToMove &&
  101.                     cannibalsOnLeft >= cannibalsToMove;
  102.             else
  103.                 return monksOnRight >= monksToMove &&
  104.                     cannibalsOnRight >= cannibalsToMove;
  105.         }
  106.         public override string ToString()
  107.         {
  108.             return monksOnLeft + "," + cannibalsOnLeft + "," + boat +
  109.                 "," + monksOnRight + "," + cannibalsOnRight;
  110.         }
  111.         public override bool Equals(Object a)
  112.         {
  113.             MonksAndCannibalsState aa = (MonksAndCannibalsState)a;
  114.             return aa.monksOnLeft == monksOnLeft &&
  115.                 aa.cannibalsOnLeft == cannibalsOnLeft && aa.boat == boat;
  116.         }
  117.         public override int GetHashCode()
  118.         {
  119.             return monksOnLeft.GetHashCode() + cannibalsOnLeft.GetHashCode() + boat.GetHashCode();
  120.         }
  121.     }
  122.     class Node
  123.     {
  124.         State state;
  125.         int depth;
  126.         Node parentNode;
  127.         int indexOfLastTestedOperator = -1;
  128.         public Node(State state, int depth, Node parentNode)
  129.         {
  130.             this.state = state;
  131.             this.depth = depth;
  132.             this.parentNode = parentNode;
  133.         }
  134.         public Node(State startState) : this(startState, 0, null) { }
  135.         public Node GetParentNode() { return parentNode; }
  136.         public int GetDepth() { return depth; }
  137.         public bool IsTerminalNode() { return state.IsGoalState(); }
  138.         public Node GetNextChildNode()
  139.         {
  140.             State newState;
  141.             bool isApplicable;
  142.             do
  143.             {
  144.                 indexOfLastTestedOperator++;
  145.                 if (indexOfLastTestedOperator == state.GetNumberOfOperators()) return null;
  146.                 newState = (State)state.Clone();
  147.                 isApplicable = newState.SuperOperator(indexOfLastTestedOperator);
  148.             } while (!isApplicable);
  149.             return new Node(newState, depth + 1, this);
  150.         }
  151.         public override bool Equals(Object obj)
  152.         {
  153.             Node otherNode = (Node)obj;
  154.             return state.Equals(otherNode.state);
  155.         }
  156.         public override int GetHashCode() { return state.GetHashCode(); }
  157.         public override string ToString()
  158.         {
  159.             return "depth = " + depth + ", state = " + state;
  160.         }
  161.         public void PrintPath()
  162.         {
  163.             Node actualNode = this;
  164.             Stack<Node> path = new Stack<Node>();
  165.             while (actualNode != null)
  166.             {
  167.                 path.Push(actualNode);
  168.                 actualNode = actualNode.GetParentNode();
  169.             }
  170.             foreach (Node act in path) Console.WriteLine(act);
  171.         }
  172.     }
  173.  
  174.     class BackTrack
  175.     {
  176.         State startingState;
  177.         public BackTrack(State startingState)
  178.         {
  179.             this.startingState = startingState;
  180.         }
  181.         public Node GraphSearch()
  182.         {
  183.             State startState = (State)this.startingState.Clone();
  184.             Node actualNode = new Node(startState);
  185.             while (!actualNode.IsTerminalNode())
  186.             {
  187.                 Node newNode = actualNode.GetNextChildNode();
  188.                 while (newNode == null)
  189.                 {
  190.                     actualNode = actualNode.GetParentNode(); // backtrack
  191.                     if (actualNode == null) return null;
  192.                     newNode = actualNode.GetNextChildNode();
  193.                 }
  194.                 actualNode = newNode;
  195.                 // cycle detection
  196.                 Node parentNodeForCicleDetection = actualNode.GetParentNode();
  197.                 while (parentNodeForCicleDetection != null)
  198.                 {
  199.                     if (actualNode.Equals(parentNodeForCicleDetection))
  200.                     {
  201.                         actualNode = actualNode.GetParentNode(); // backtrack
  202.                         break;
  203.                     }
  204.                     parentNodeForCicleDetection = parentNodeForCicleDetection.GetParentNode();
  205.                 }
  206.             }
  207.             return actualNode;
  208.         }
  209.     }
  210. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement