Advertisement
Mitrezzz

[АПС] Лаб 10: Алгоритми за графови Хиерархија

Jan 6th, 2021
959
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 15.36 KB | None | 0 0
  1. import java.io.BufferedReader;
  2. import java.io.IOException;
  3. import java.io.InputStreamReader;
  4. import java.util.*;
  5.  
  6.  
  7. import java.util.Iterator;
  8.  
  9.  
  10. class Graph<E> {
  11.  
  12.     int num_nodes;
  13.     GraphNode<E> adjList[];
  14.  
  15.     @SuppressWarnings("unchecked")
  16.     public Graph(int num_nodes, E[] list) {
  17.         this.num_nodes = num_nodes;
  18.         adjList = (GraphNode<E>[]) new GraphNode[num_nodes];
  19.         for (int i = 0; i < num_nodes; i++)
  20.             adjList[i] = new GraphNode<E>(i, list[i]);
  21.     }
  22.  
  23.     @SuppressWarnings("unchecked")
  24.     public Graph(int num_nodes) {
  25.         this.num_nodes = num_nodes;
  26.         adjList = (GraphNode<E>[]) new GraphNode[num_nodes];
  27.         for (int i = 0; i < num_nodes; i++)
  28.             adjList[i] = new GraphNode<E>(i, null);
  29.     }
  30.  
  31.     int adjacent(int x, int y) {
  32.         // proveruva dali ima vrska od jazelot so
  33.         // indeks x do jazelot so indeks y
  34.         return (adjList[x].containsNeighbor(adjList[y])) ? 1 : 0;
  35.     }
  36.  
  37.     void addEdge(int x, int y, float tezina) {
  38.         // dodava vrska od jazelot so indeks x do jazelot so indeks y so tezina
  39.         // i obratno
  40.         if (adjList[x].containsNeighbor(adjList[y])) {
  41.             adjList[x].updateNeighborWeight(adjList[y], tezina);
  42.             adjList[y].updateNeighborWeight(adjList[x], tezina);
  43.         } else{
  44.             adjList[x].addNeighbor(adjList[y], tezina);
  45.             adjList[y].addNeighbor(adjList[x], tezina);
  46.         }
  47.     }
  48.  
  49.     void deleteEdge(int x, int y) {
  50.         adjList[x].removeNeighbor(adjList[y]);
  51.         adjList[y].removeNeighbor(adjList[x]);
  52.     }
  53.  
  54.     /*************************** KRUSKAL ***********************************************************************/
  55.  
  56.     // Metoda koja generira niza od site rebra vo grafot
  57.     public Edge[] getAllEdges() {
  58.         int totalEdges = 0;
  59.         for (int i = 0; i < this.num_nodes; i++) {
  60.             // za sekoe teme go dodavame brojot na sosedi koi gi ima
  61.             totalEdges += this.adjList[i].getNeighbors().size();
  62.         }
  63.  
  64.         totalEdges /= 2; //bidejki e nenasocen graf, sekoe rebro se javuva kaj dve teminja
  65.  
  66.         Edge[] edges = new Edge[totalEdges];
  67.         int index = 0;
  68.         for (int i = 0; i < this.num_nodes; i++) {
  69.             for (int j = 0; j < this.adjList[i].getNeighbors().size(); j++) {
  70.                 int index1 = this.adjList[i].getIndex();
  71.                 // se zemaat indeksot i tezinata na j-ot sosed na temeto i
  72.                 int index2 = this.adjList[i].getNeighbors().get(j).node
  73.                         .getIndex();
  74.                 float weight = this.adjList[i].getNeighbors().get(j).weight;
  75.                 if(index2>index1) //bidejki grafot e nenasocen, da ne go zemame sekoe rebro dva pati
  76.                     edges[index++] = new Edge(index1, index2, weight);
  77.             }
  78.         }
  79.  
  80.         return edges;
  81.     }
  82.  
  83.     // Metoda koja gi sortira site rebra
  84.     private void sortEdges(Edge[] edges) {
  85.         for (int i = 0; i < edges.length - 1; i++) {
  86.             for (int j = i + 1; j < edges.length; j++) {
  87.                 if (edges[i].getWeight() > edges[j].getWeight()) {
  88.                     Edge tmp = edges[i];
  89.                     edges[i] = edges[j];
  90.                     edges[j] = tmp;
  91.                 }
  92.             }
  93.         }
  94.  
  95.     }
  96.  
  97.     //Metoda koja pravi unija na dve drva
  98.     private void union(int u, int v, int[] vrski){
  99.         int findWhat, replaceWith;
  100.  
  101.         if(u < v){
  102.             findWhat = vrski[v];
  103.             replaceWith = vrski[u];
  104.         }
  105.         else{
  106.             findWhat = vrski[u];
  107.             replaceWith = vrski[v];
  108.         }
  109.  
  110.         //za dvete poddrva stava ist index
  111.         //vo vrski t.e. gi spojuva
  112.         for(int i=0; i<vrski.length; i++){
  113.             if(vrski[i] == findWhat){
  114.                 vrski[i] = replaceWith;
  115.             }
  116.         }
  117.     }
  118.  
  119.     List<Edge> kruskal() {
  120.         /*
  121.          * Pomoshna niza za sledenje na kreiranite drva
  122.          * Ako dve teminja se del od isto poddrvo
  123.          * togash imaat ista vrednost vo nizata
  124.          */
  125.         int vrski[] = new int[this.num_nodes];
  126.  
  127.         // niza koja gi sodrzi site rebra
  128.         Edge[] edges = this.getAllEdges();
  129.         // se sortiraat rebrata spored tezinite vo neopagjacki redosled
  130.         this.sortEdges(edges);
  131.  
  132.         // inicijalizacija na pomosnata niza za evidencija,
  133.         // sekoj jazel si e posebno drvo
  134.         for (int i = 0; i < this.num_nodes; i++)
  135.             vrski[i] = i;
  136.  
  137.         // lista koja kje gi sodrzi MST rebra
  138.         List<Edge> mstEdges = new ArrayList<Edge>();
  139.  
  140.         for(int i=0; i<edges.length; i++){
  141.             //za sekoe rebro vo sortiran redosled
  142.             Edge e = edges[i];
  143.  
  144.             if(vrski[e.getFrom()] != vrski[e.getTo()]){
  145.                 //ako teminjata na ova rebro ne se vo isto poddrvo
  146.                 //ova rebro e MST rebro
  147.                 mstEdges.add(e);
  148.                 //sega dvete teminja treba da se vo isto poddrvo
  149.                 //t.e se pravi merge (unija) t.s. vo nizata vrski
  150.                 //za site elementi od dvete poddrva
  151.                 //go setira istiot (najmal) element od dvete poddrva
  152.                 //vrski = this.union(e.getFrom(), e.getTo(), vrski);
  153.                 this.union(e.getFrom(), e.getTo(), vrski);
  154.             }
  155.  
  156.             //ako sme dodale num_nodes-1 rebra moze da prestaneme
  157.             if(mstEdges.size()==(this.num_nodes-1))
  158.                 break;
  159.         }
  160.  
  161.         return mstEdges;
  162.     }
  163.  
  164.     /*******************************************************************************************************/
  165.     /************************ PRIM **************************************************************************/
  166.  
  167.     //Metoda koja go naogja najmaloto rebro do
  168.     //teme na neposeten sosed
  169.     private Edge getMinimalEdge(boolean[] included){
  170.         int index1 = Integer.MAX_VALUE, index2 = Integer.MAX_VALUE;
  171.         float minweight = Float.MAX_VALUE;
  172.  
  173.         for(int i=0;i<this.num_nodes;i++){
  174.             if(included[i]){
  175.                 //ako e vkluceno temeto i
  176.                 //izmini gi negovite nevkluceni sosedi
  177.                 Iterator<GraphNodeNeighbor<E>> it = adjList[i].getNeighbors().iterator();
  178.                 while(it.hasNext()){
  179.                     GraphNodeNeighbor<E> pom = it.next();
  180.                     //ako sosedot ne e poseten i ima do sega najmala tezina
  181.                     if(!included[pom.node.getIndex()] && pom.weight<minweight){
  182.                         index1 = i;
  183.                         index2 = pom.node.getIndex();
  184.                         minweight = pom.weight;
  185.                     }
  186.                 }
  187.             }
  188.         }
  189.  
  190.         if(minweight<Float.MAX_VALUE){
  191.             Edge ret = new Edge(index1, index2, minweight);
  192.             return ret;
  193.         }
  194.         return null;
  195.     }
  196.  
  197.  
  198.     List<Edge> prim(int start_index) {
  199.         // lista koja kje gi sodrzi MST rebra
  200.         List<Edge> mstEdges = new ArrayList<Edge>();
  201.  
  202.         boolean included[] = new boolean[this.num_nodes];
  203.         for(int i=0;i<this.num_nodes;i++)
  204.             included[i]=false;
  205.  
  206.         included[start_index] = true;
  207.  
  208.         for(int i=0;i<this.num_nodes-1;i++){
  209.             Edge e = this.getMinimalEdge(included);
  210.             if(e==null){
  211.                 System.out.println("Ne mozat da se povrzat site jazli");
  212.                 break;
  213.             }
  214.             included[e.getFrom()] = included[e.getTo()] = true;
  215.             mstEdges.add(e);
  216.         }
  217.  
  218.         return mstEdges;
  219.     }
  220.  
  221.     /*******************************************************************************************************/
  222.     /***************** DIJKSTRA ******************************************************************************/
  223.  
  224.     float[] dijkstra(int from) {
  225.  
  226.         /* Minimalna cena do sekoe od teminjata */
  227.         float distance[] = new float[this.num_nodes];
  228.         /* dali za temeto e najdena konecnata (minimalna) cena */
  229.         boolean finalno[] = new boolean[this.num_nodes];
  230.         for (int i = 0; i < this.num_nodes; i++) {
  231.             distance[i] = -1;
  232.             finalno[i] = false;
  233.         }
  234.  
  235.         finalno[from] = true;
  236.         distance[from] = 0;
  237.  
  238.         /*
  239.          * vo sekoj cekor za edno teme se dobiva konecna minimalna cena
  240.          */
  241.         for (int i = 1; i < this.num_nodes; i++) {
  242.             /* za site sledbenici na from presmetaj ja cenata */
  243.             Iterator<GraphNodeNeighbor<E>> it = adjList[from].getNeighbors().iterator();
  244.             while (it.hasNext()) {
  245.                 GraphNodeNeighbor<E> pom = it.next();
  246.                 /* ako grankata kon sosedot nema konecna cena */
  247.                 if (!finalno[pom.node.getIndex()]) {
  248.                     /* ako ne e presmetana cena za temeto */
  249.                     if (distance[pom.node.getIndex()] <= 0) {
  250.                         distance[pom.node.getIndex()] = distance[from]
  251.                                 + pom.weight;
  252.                     }
  253.                     /* inaku, ako e pronajdena poniska */
  254.                     else if (distance[from] + pom.weight < distance[pom.node
  255.                             .getIndex()]) {
  256.                         distance[pom.node.getIndex()] = distance[from]
  257.                                 + pom.weight;
  258.                     }
  259.                 }
  260.             }
  261.  
  262.             /* najdi teme so min. cena koja ne e konecna */
  263.             boolean minit = false; /* min. ne e inicijaliziran */
  264.             int k = -1;
  265.             float minc = -1;
  266.             /* proveri gi site teminja */
  267.             for (int j = 0; j < this.num_nodes; j++) {
  268.                 if (!finalno[j] && distance[j] != -1) { /*ako cenata ne e  konecna*/
  269.                     if (!minit) { /* ako ne e inicijaliziran minimumot */
  270.                         minc = distance[k = j]; /* proglasi go ova e minimum */
  271.                         minit = true; /* oznaci deka min e inicijaliziran */
  272.                     }
  273.                     /* proveri dali e pronajdeno teme so pomala cena */
  274.                     else if (minc > distance[j] && distance[j] > 0)
  275.                         minc = distance[k = j];
  276.                 }
  277.             }
  278.             finalno[from = k] = true;
  279.         }
  280.  
  281.         return distance;
  282.  
  283.     }
  284.  
  285.     /*******************************************************************************************************/
  286.  
  287.     @Override
  288.     public String toString() {
  289.         String ret = new String();
  290.         for (int i = 0; i < this.num_nodes; i++)
  291.             ret += adjList[i] + "\n";
  292.         return ret;
  293.     }
  294.  
  295. }
  296.  
  297. class GraphNode<E> {
  298.     private int index; //index (reden broj) na temeto vo grafot
  299.     private E info;
  300.     private LinkedList<GraphNodeNeighbor<E>> neighbors;
  301.  
  302.     public GraphNode(int index, E info) {
  303.         this.index = index;
  304.         this.info = info;
  305.         neighbors = new LinkedList<GraphNodeNeighbor<E>>();
  306.     }
  307.  
  308.     public boolean containsNeighbor(GraphNode<E> o){
  309.         GraphNodeNeighbor<E> pom = new GraphNodeNeighbor<E>(o,0);
  310.         return neighbors.contains(pom);
  311.     }
  312.  
  313.     public void addNeighbor(GraphNode<E> o, float weight){
  314.         GraphNodeNeighbor<E> pom = new GraphNodeNeighbor<E>(o,weight);
  315.         neighbors.add(pom);
  316.     }
  317.  
  318.     public void removeNeighbor(GraphNode<E> o){
  319.         GraphNodeNeighbor<E> pom = new GraphNodeNeighbor<E>(o,0);
  320.         if(neighbors.contains(pom))
  321.             neighbors.remove(pom);
  322.     }
  323.  
  324.     @Override
  325.     public String toString() {
  326.         String ret= "INFO:"+info+" SOSEDI:";
  327.         for(int i=0;i<neighbors.size();i++)
  328.             ret+="("+neighbors.get(i).node.info+","+neighbors.get(i).weight+") ";
  329.         return ret;
  330.  
  331.     }
  332.  
  333.     public void updateNeighborWeight(GraphNode<E> o, float weight){
  334.         Iterator<GraphNodeNeighbor<E>> i = neighbors.iterator();
  335.         while(i.hasNext()){
  336.             GraphNodeNeighbor<E> pom = i.next();
  337.             if(pom.node.equals(o))
  338.                 pom.weight = weight;
  339.         }
  340.  
  341.     }
  342.  
  343.     @Override
  344.     public boolean equals(Object obj) {
  345.         @SuppressWarnings("unchecked")
  346.         GraphNode<E> pom = (GraphNode<E>)obj;
  347.         return (pom.info.equals(this.info));
  348.     }
  349.  
  350.     public int getIndex() {
  351.         return index;
  352.     }
  353.  
  354.     public void setIndex(int index) {
  355.         this.index = index;
  356.     }
  357.  
  358.     public E getInfo() {
  359.         return info;
  360.     }
  361.  
  362.     public void setInfo(E info) {
  363.         this.info = info;
  364.     }
  365.  
  366.     public LinkedList<GraphNodeNeighbor<E>> getNeighbors() {
  367.         return neighbors;
  368.     }
  369.  
  370.     public void setNeighbors(LinkedList<GraphNodeNeighbor<E>> neighbors) {
  371.         this.neighbors = neighbors;
  372.     }
  373.  
  374.  
  375.  
  376. }
  377.  
  378.  class GraphNodeNeighbor<E> {
  379.     GraphNode<E> node;
  380.     float weight;
  381.  
  382.     public GraphNodeNeighbor(GraphNode<E> node, float weight) {
  383.         this.node = node;
  384.         this.weight = weight;
  385.     }
  386.  
  387.     public GraphNodeNeighbor(GraphNode<E> node) {
  388.         this.node = node;
  389.         this.weight = 0;
  390.     }
  391.  
  392.     @Override
  393.     public boolean equals(Object obj) {
  394.         @SuppressWarnings("unchecked")
  395.         GraphNodeNeighbor<E> pom = (GraphNodeNeighbor<E>)obj;
  396.         return pom.node.equals(this.node);
  397.     }
  398.  
  399.  
  400.  
  401.  
  402.  
  403. }
  404.  
  405.  class Edge{
  406.      private int fromVertex, toVertex;
  407.      private float weight;
  408.      public Edge(int from, int to, float weight){
  409.          this.fromVertex = from;
  410.          this.toVertex = to;
  411.          this.weight = weight;
  412.      }
  413.  
  414.      public int getFrom(){
  415.          return this.fromVertex;
  416.      }
  417.      public int getTo(){
  418.          return this.toVertex;
  419.      }
  420.      public float getWeight(){
  421.          return this.weight;
  422.      }
  423.  
  424.      @Override
  425.      public String toString() {
  426.          return "("+fromVertex+","+toVertex+")="+weight+" ";
  427.      }
  428.  
  429.  
  430.  }
  431.  
  432. public class Hierarchy {
  433.  
  434.  
  435.  
  436.  
  437.     public static void main(String[] args) throws IOException {
  438.  
  439.         BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
  440.         int n = Integer.parseInt(in.readLine());
  441.         int num_edges = Integer.parseInt(in.readLine());
  442.  
  443.         Hashtable<String, Integer> vraboteni = new Hashtable<>(num_edges+1);
  444.         Graph<Integer> g = new Graph<>(n);
  445.  
  446.         for(int i = 0; i < num_edges; i++){
  447.             String line = in.readLine();
  448.             String pom[] = line.split(" ");
  449.  
  450.             int index1 = Integer.parseInt(pom[0]);
  451.             int index2 = Integer.parseInt(pom[2]);
  452.  
  453.             String covek1 = pom[1];
  454.             String covek2 = pom[3];
  455.             float tezina = Float.parseFloat(pom[4]);
  456.  
  457.             if(!vraboteni.contains(covek1)){
  458.                 vraboteni.put(covek1,index1);
  459.             }
  460.             if(!vraboteni.contains(pom[3])){
  461.                 vraboteni.put(covek2 , index2);
  462.             }
  463.             g.adjList[index1].setInfo(index1);
  464.             g.adjList[index2].setInfo(index2);
  465.             g.addEdge(index1,index2 , tezina);
  466.  
  467.         }
  468.  
  469.         String line = in.readLine();
  470.         int index = vraboteni.get(line);
  471.  
  472.         List<Edge> lista = g.prim(index);
  473.  
  474.         float sum = 0;
  475.         for(int i = 0; i < lista.size(); i++){
  476.            // System.out.println("From: " + lista.get(i).getFrom() + " To: " + lista.get(i).getTo() + " Weight " +lista.get(i).getWeight() );
  477.             sum += lista.get(i).getWeight();
  478.         }
  479.         System.out.println((int)sum);
  480.  
  481.     }
  482.  
  483. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement