Advertisement
kimo12

Untitled

Apr 14th, 2017
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 12.69 KB | None | 0 0
  1. package signalFlowGraph;
  2.  
  3. import java.awt.Point;
  4. import java.sql.Array;
  5. import java.util.ArrayList;
  6. import java.util.Arrays;
  7. import java.util.Scanner;
  8.  
  9. public class AnalyzeSFG {
  10.  
  11.     private int[][] adjMatrix;
  12.     private int numberOfNodes;
  13.     private String path = new String();
  14.     private int forwardPathGain = 1;
  15.     private ArrayList<String> loopsPath = new ArrayList<>();
  16.     private ArrayList<String> forwardPath = new ArrayList<>();
  17.     private ArrayList<Integer> forwardGains = new ArrayList<>();
  18.     private ArrayList<Integer> loopsGains = new ArrayList<>();
  19.     private ArrayList<Point> searchLoops = new ArrayList<>();
  20.     private ArrayList<ArrayList<String>> nonTouchingLoopsPath = new ArrayList<>();
  21.     private ArrayList<ArrayList<Integer>> nonTouchingLoopsGains = new ArrayList<>();
  22.     private ArrayList<Integer> nonTouchedLoopsWithPathGains = new ArrayList<>();
  23.     private Scanner scan;
  24.  
  25.     public static void main(String[] args) {
  26.         AnalyzeSFG g = new AnalyzeSFG();
  27.         g.inputs();
  28.         g.printMatrix();
  29.         g.traverseForwardPath(0);
  30.         g.loops();
  31.         g.nonTouchingLoops();
  32.         g.print();
  33.         // System.out.println("mason value = " + g.masonValue());
  34.     }
  35.  
  36.     private void makeAllZeros(int[][] matrix) {
  37.         for (int i = 0; i < matrix.length; i++)
  38.             Arrays.fill(matrix[i], 0);
  39.     }
  40.  
  41.     private void inputs() {
  42.         scan = new Scanner(System.in);
  43.         System.out.print("Enter The Number Of Nodes : ");
  44.         numberOfNodes = scan.nextInt();
  45.         adjMatrix = new int[numberOfNodes][numberOfNodes];
  46.         makeAllZeros(adjMatrix);
  47.         System.out.println("To Get Out From Entering Signal Flow Graph Representation");
  48.         System.out.println("Put From = 0 ");
  49.         while (true) {
  50.             int from, to, gain;
  51.             System.out.print("From : ");
  52.             from = scan.nextInt() - 1;
  53.             if (from < 0) {
  54.                 break;
  55.             }
  56.             System.out.print("To : ");
  57.             to = scan.nextInt() - 1;
  58.             System.out.print("gain : ");
  59.             gain = scan.nextInt();
  60.             adjMatrix[to][from] = gain;
  61.         }
  62.         addFinalNode();
  63.     }
  64.  
  65.     private void printMatrix() {
  66.         for (int i = 0; i < numberOfNodes; i++) {
  67.             for (int j = 0; j < numberOfNodes; j++) {
  68.                 System.out.print(adjMatrix[i][j] + " ");
  69.             }
  70.             System.out.println();
  71.         }
  72.  
  73.     }
  74.  
  75.     private void print() {
  76.         System.out.println("Forward Paths");
  77.         for (int i = 0; i < this.forwardGains.size(); i++) {
  78.             System.out.println(this.forwardGains.get(i));
  79.             System.out.println(this.forwardPath.get(i));
  80.         }
  81.         System.out.println("\nLoops");
  82.         for (int i = 0; i < this.loopsPath.size(); i++) {
  83.             System.out.println(this.loopsPath.get(i));
  84.             System.out.println(this.loopsGains.get(i));
  85.         }
  86.     }
  87.  
  88.     private int[][] copyMatrix(int[][] copyTo, int[][] copyFrom) {
  89.         for (int i = 0; i < copyFrom.length; i++)
  90.             for (int j = 0; j < copyFrom.length; j++)
  91.                 copyTo[i][j] = copyFrom[i][j];
  92.         return copyTo;
  93.     }
  94.  
  95.     private int[] getLoopPathArray(String gainString) {
  96.         gainString = gainString.substring(1, gainString.length()).replace("x", " ");
  97.         String[] arrayString = gainString.split(" ");
  98.         int[] array = new int[arrayString.length];
  99.         for (int i = 0; i < arrayString.length; i++) {
  100.             array[i] = Integer.parseInt(arrayString[i]);
  101.         }
  102.         return array;
  103.     }
  104.  
  105.     private int getSimpleLoopGain(String gainString) {
  106.         int[] array = getLoopPathArray(gainString);
  107.         int column, row;
  108.         int gain = 1;
  109.         for (int i = 1; i < array.length; i++) {
  110.             column = array[i - 1];
  111.             row = array[i];
  112.             gain *= adjMatrix[row][column];
  113.         }
  114.         return gain;
  115.         // x1x2x3x4x1
  116.     }
  117.  
  118.     private int getSimpleLoopGain(int[] array) {
  119.         int column, row;
  120.         int gain = 1;
  121.         for (int i = 1; i < array.length; i++) {
  122.             column = array[i - 1];
  123.             row = array[i];
  124.             gain *= adjMatrix[row][column];
  125.         }
  126.         return gain;
  127.         // x1x2x3x4x1
  128.     }
  129.  
  130.     private void addFinalNode() {
  131.         boolean addColumn = false;
  132.         for (int i = 0; i < this.adjMatrix.length; i++)
  133.             if (this.adjMatrix[i][this.numberOfNodes - 1] != 0) {
  134.                 addColumn = true;
  135.                 break;
  136.             }
  137.  
  138.         if (addColumn == true) {
  139.             int newDimension = this.numberOfNodes + 1;
  140.             int[][] copy = new int[newDimension][newDimension];
  141.             makeAllZeros(copy);
  142.             copy = copyMatrix(copy, adjMatrix);
  143.             copy[newDimension - 1][newDimension - 2] = 1;
  144.             adjMatrix = copy;
  145.             this.numberOfNodes = newDimension;
  146.         }
  147.     }
  148.  
  149.     private void loops() {
  150.         // searching for self loops
  151.         for (int i = 0; i < numberOfNodes; i++) {
  152.             if (adjMatrix[i][i] != 0) {
  153.                 String selfLoop = "x" + i + "x" + i;
  154.                 loopsPath.add(selfLoop);
  155.                 loopsGains.add(adjMatrix[i][i]);
  156.             }
  157.         }
  158.         // finding possible loops path
  159.         for (int i = 1; i < numberOfNodes; i++) {
  160.             for (int j = i - 1; j >= 0; j--) {
  161.                 if (adjMatrix[j][i] != 0) {
  162.                     // from i to j (reverse path) j <==== i
  163.                     Point x = new Point(j, i);
  164.                     searchLoops.add(x);
  165.                 }
  166.             }
  167.         }
  168.         // search in the forwardPathes for path from j to i
  169.         // if found j ===> i then the is a loop j => i => j
  170.         for (int i = 0; i < this.forwardPath.size(); i++) {
  171.             String current = this.forwardPath.get(i);
  172.             for (int j = 0; j < this.searchLoops.size(); j++) {
  173.                 int x = this.searchLoops.get(j).x;
  174.                 String from = "x" + x;
  175.                 if (current.contains(from)) {
  176.                     int y = this.searchLoops.get(j).y;
  177.                     String to = "x" + y;
  178.                     if (current.contains(to)) {
  179.                         // this is a loop we must calculate the gain and print
  180.                         // the loop path
  181.                         int start = current.lastIndexOf(from);
  182.                         int end;
  183.                         if (y < 10)
  184.                             end = current.lastIndexOf(to) + 1;
  185.                         else
  186.                             end = current.lastIndexOf(to) + 2;
  187.                         String loop;
  188.                         if (x < 10)
  189.                             loop = current.substring(start, end + 1) + current.substring(start, start + 2);
  190.                         else
  191.                             loop = current.substring(start, end + 1) + current.substring(start, start + 3);
  192.                         // Check that this loop isn't already taken
  193.                         boolean exist = false;
  194.                         for (int k = 0; k < this.loopsPath.size(); k++) {
  195.                             if (loop.equals(this.loopsPath.get(k))) {
  196.                                 exist = true;
  197.                             }
  198.                         }
  199.                         if (!exist) {
  200.                             loopsPath.add(loop);
  201.                             loopsGains.add(getSimpleLoopGain(loop));
  202.                         }
  203.                     }
  204.                 }
  205.             }
  206.         }
  207.     }
  208.  
  209.     private void nonTouchingLoops() {
  210.         ArrayList<String> pathes = new ArrayList<>();
  211.         ArrayList<Integer> gains = new ArrayList<>();
  212.         // search for the two non-touching loops
  213.         for (int i = 0; i < this.loopsPath.size(); i++) {
  214.             pathes.add(loopsPath.get(i));
  215.             gains.add(loopsGains.get(i));
  216.         }
  217.         this.nonTouchingLoopsPath.add(pathes);
  218.         this.nonTouchingLoopsGains.add(gains);
  219.         pathes = new ArrayList<>();
  220.         gains = new ArrayList<>();
  221.         for (int i = 0; i < this.nonTouchingLoopsPath.get(0).size(); i++) {
  222.             for (int j = i + 1; j < this.nonTouchingLoopsPath.get(0).size(); j++) {
  223.                 if (!areTouching(this.nonTouchingLoopsPath.get(0).get(i), this.nonTouchingLoopsPath.get(0).get(j))) {
  224.                     String nonTouchingLoop = this.nonTouchingLoopsPath.get(0).get(i)
  225.                             + this.nonTouchingLoopsPath.get(0).get(j);
  226.                     int gain = this.nonTouchingLoopsGains.get(0).get(i) * this.nonTouchingLoopsGains.get(0).get(j);
  227.                     pathes.add(nonTouchingLoop);
  228.                     gains.add(gain);
  229.                 }
  230.             }
  231.         }
  232.         if (pathes.size() > 0) {
  233.             this.nonTouchingLoopsPath.add(pathes);
  234.             this.nonTouchingLoopsGains.add(gains);
  235.         }
  236.         // search for more than two non touching loops
  237.         int k = 1;
  238.         while (nonTouchingLoopsPath.size() == k + 1) {
  239.             pathes = new ArrayList<>();
  240.             gains = new ArrayList<>();
  241.             for (int i = 0; i < this.nonTouchingLoopsPath.get(k).size(); i++) {
  242.                 for (int j = 0; j < this.nonTouchingLoopsPath.get(k - 1).size(); j++) {
  243.                     if (!areTouching(this.nonTouchingLoopsPath.get(k).get(i),
  244.                             this.nonTouchingLoopsPath.get(k - 1).get(j))) {
  245.                         String nonTouchingLoop = this.nonTouchingLoopsPath.get(k).get(i)
  246.                                 + this.nonTouchingLoopsPath.get(k - 1).get(j);
  247.                         int gain = this.nonTouchingLoopsGains.get(k).get(i)
  248.                                 * this.nonTouchingLoopsGains.get(k - 1).get(j);
  249.                         if (pathes.size() == 0) {
  250.                             pathes.add(nonTouchingLoop);
  251.                             gains.add(gain);
  252.                         } else {
  253.                             boolean equal = false;
  254.                             int[] a = getLoopPathArray(nonTouchingLoop);
  255.                             for (int m = 0; m < pathes.size(); m++) {
  256.                                 int[] b = getLoopPathArray(pathes.get(m));
  257.                                 if (a.length == b.length) {
  258.                                     Arrays.sort(a);
  259.                                     Arrays.sort(b);
  260.                                     for (int z = 0; z < a.length; z++) {
  261.                                         if (a[i] == b[i]) {
  262.                                             equal = true;
  263.                                             break;
  264.                                         }
  265.                                     }
  266.                                 }
  267.                             }
  268.                             if (!equal) {
  269.                                 pathes.add(nonTouchingLoop);
  270.                                 gains.add(gain);
  271.                             }
  272.                         }
  273.                     }
  274.                 }
  275.             }
  276.             if (pathes.size() > 0) {
  277.                 this.nonTouchingLoopsPath.add(pathes);
  278.                 this.nonTouchingLoopsGains.add(gains);
  279.                 k++;
  280.             } else {
  281.                 k++;
  282.             }
  283.         }
  284.         // printing the nonTouched loops
  285.         if (nonTouchingLoopsPath.size() > 1) {
  286.             System.out.println("nonTouching");
  287.             for (int i = 1; i < this.nonTouchingLoopsPath.size(); i++) {
  288.                 for (int j = 0; j < this.nonTouchingLoopsPath.get(i).size(); j++) {
  289.                     System.out.println(this.nonTouchingLoopsPath.get(i).get(j));
  290.                     System.out.println(this.nonTouchingLoopsGains.get(i).get(j));
  291.                 }
  292.             }
  293.         }
  294.     }
  295.  
  296.     private void nonTouchingWithPathGain() {
  297.         ArrayList<ArrayList<Integer>> nonTouchedLoopsWithPathGain = new ArrayList<>();
  298.         ArrayList<Integer> gains;
  299.         for (int i = 0; i < forwardPath.size(); i++) {
  300.             gains = new ArrayList<>();
  301.             for (int j = 0; j < this.nonTouchingLoopsPath.size(); j++) {
  302.                 int sum = 0;
  303.                 for (int k = 0; k < this.nonTouchingLoopsPath.get(j).size(); k++) {
  304.                     if (!areTouching(forwardPath.get(i), this.nonTouchingLoopsPath.get(j).get(k))) {
  305.                         sum += this.nonTouchingLoopsGains.get(j).get(k);
  306.                     }
  307.                 }
  308.                 gains.add(sum);
  309.             }
  310.             nonTouchedLoopsWithPathGain.add(gains);
  311.         }
  312.         for (int i = 0; i < nonTouchedLoopsWithPathGain.size(); i++) {
  313.             int gainSum = 1;
  314.             for (int j = 0; j < nonTouchedLoopsWithPathGain.get(i).size(); j++) {
  315.                 if (j % 2 == 0) {
  316.                     gainSum -= nonTouchedLoopsWithPathGain.get(i).get(j);
  317.                 } else {
  318.                     gainSum += nonTouchedLoopsWithPathGain.get(i).get(j);
  319.                 }
  320.             }
  321.             this.nonTouchedLoopsWithPathGains.add(gainSum);
  322.         }
  323.     }
  324.  
  325.     private double numerator() {
  326.         nonTouchingWithPathGain();
  327.         int numerator = 0;
  328.         for (int i = 0; i < forwardPath.size(); i++) {
  329.             numerator += this.forwardGains.get(i) * this.nonTouchedLoopsWithPathGains.get(i);
  330.         }
  331.         return numerator;
  332.     }
  333.  
  334.     private double denominator() {
  335.         // 1 - (sum gains individual) + (sum gain of two non touching)
  336.         ArrayList<Integer> sumGains = new ArrayList<>();
  337.         for (int i = 0; i < this.nonTouchingLoopsPath.size(); i++) {
  338.             int sum = 0;
  339.             for (int j = 0; j < this.nonTouchingLoopsPath.get(i).size(); j++) {
  340.                 sum += this.nonTouchingLoopsGains.get(i).get(j);
  341.             }
  342.             sumGains.add(sum);
  343.         }
  344.         int denominator = 1;
  345.         for (int k = 0; k < sumGains.size(); k++) {
  346.             if (k % 2 == 0) {
  347.                 denominator -= sumGains.get(k);
  348.             } else {
  349.                 denominator += sumGains.get(k);
  350.             }
  351.         }
  352.         return denominator;
  353.     }
  354.  
  355.     private double masonValue() {
  356.         return numerator() / denominator();
  357.     }
  358.  
  359.     private boolean areTouching(String loopPath1, String loopPath2) {
  360.         return compareTwoLoops(getLoopPathArray(loopPath1), getLoopPathArray(loopPath2));
  361.     }
  362.  
  363.     private boolean compareTwoLoops(int[] loopPath1, int[] loopPath2) {
  364.         for (int i = 0; i < loopPath1.length; i++)
  365.             for (int j = 0; j < loopPath2.length; j++)
  366.                 if (loopPath1[i] == loopPath2[j])
  367.                     return true;
  368.         return false;
  369.     }
  370.  
  371.     private void traverseForwardPath(int columnIndex) {
  372.  
  373.         if (isLastNode(columnIndex)) {
  374.             addToForwardPath(columnIndex, 1);
  375.             forwardPath.add(path);
  376.             forwardGains.add(forwardPathGain);
  377.             path = path.replace("x" + columnIndex, "");
  378.             return;
  379.         }
  380.  
  381.         int rowIndex = -1;
  382.         rowIndex = getNextNode(rowIndex + 1, columnIndex);
  383.         while (rowIndex != -1) {
  384.             if (rowIndex <= columnIndex) {
  385.                 rowIndex = getNextNode(rowIndex + 1, columnIndex);
  386.                 continue;
  387.             }
  388.             addToForwardPath(columnIndex, adjMatrix[rowIndex][columnIndex]);
  389.             traverseForwardPath(rowIndex);
  390.             removeFromForwardPath(columnIndex, adjMatrix[rowIndex][columnIndex]);
  391.             rowIndex = getNextNode(rowIndex + 1, columnIndex);
  392.         }
  393.     }
  394.  
  395.     private void removeFromForwardPath(int currentNode, int gain) {
  396.         String toBeRemoved = "x" + currentNode;
  397.         if (path.contains(toBeRemoved))
  398.             path = path.replace(toBeRemoved, "");
  399.         forwardPathGain /= gain;
  400.  
  401.     }
  402.  
  403.     private void addToForwardPath(int currentNode, int gain) {
  404.         path += "x" + currentNode;
  405.         forwardPathGain *= gain;
  406.     }
  407.  
  408.     private int getNextNode(int rowIndex, int columnIndex) {
  409.         for (; rowIndex < this.numberOfNodes; rowIndex++)
  410.             if (adjMatrix[rowIndex][columnIndex] != 0)
  411.                 return rowIndex;
  412.         return -1;
  413.     }
  414.  
  415.     private boolean isLastNode(int columnIndex) {
  416.         for (int i = 0; i < this.numberOfNodes; i++)
  417.             if (adjMatrix[i][columnIndex] != 0)
  418.                 return false;
  419.         return true;
  420.     }
  421.  
  422. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement