2015-04-01 19 views
3

我正在創建一個程序來爲參考書目數據集創建圖。該圖是直接的,具有Author節點和Paper節點,並且具有2種類型的邊緣(作者爲紙邊緣,紙張邊緣)。在java圖中創建具有權重的節點

我想從你那裏得到關於我所創建的內容是否合理的意見。現在,當我想從一個節點獲取outEdge和inEdge時,它會產生正確的結果。但我不知道這個實現在方法,設計和算法方面是否正確。

另外,我有一個給節點分配權重的問題。我想問我怎麼能做到這一點。現在,我已經試過如下:

for (String item : CandidateAuthorType1Unique) { 
    double weight = Collections.frequency(CandidateAuthorType1, item); 
    n.setWeight(item,weight);; 
    System.out.println(n.getName() + " : " + n.getWeight()); 
} 

然而,使用setWeight之後,getName()方法返回null。這意味着分配的重量未分配給某個項目。我想知道如何更新某個項目的重量。

如果我使用

for (String item : CandidateAuthorType1Unique) { 
    double weight = Collections.frequency(CandidateAuthorType1, item); 
    n = new Node(item,weight); 
    System.out.println(n.getName() + " : " + n.getWeight()); 
} 

這是否意味着每一個新的節點n被創建的時候,老器N節點將不被保存?我如何檢查創建的每個節點及其重量?

我想問你輸入這個程序。任何輸入都會對我很有幫助。謝謝。

主類:Ranker.java

import java.util.*; 
import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.lang.reflect.Field; 
import java.sql.*; 

public class Ranker { 

    static Graph g; 
    static Node n; 
    static Edge e; 
    static HashMap nodeMap; // maps Integer NodeIDs to Node object 
    String id; 
    double weight; 

    Ranker() { 
      g = new Graph(); 
      nodeMap = new HashMap(); 
      n = new Node(id,weight); 
    } 

    public static void main (String[] args) throws ClassNotFoundException, SQLException, IOException, IllegalArgumentException, IllegalAccessException{ 

     Ranker Ranker = new Ranker(); 
     Connection connect = null; 
     PreparedStatement preparedStatement = null; 
     ResultSet resultSet = null; 
     HashMap nodeMap = new HashMap(); // maps Integer NodeIDs to Node objects 

     Class.forName("com.mysql.jdbc.Driver"); 
     connect = DriverManager.getConnection("jdbc:mysql://localhost/arnetminer?"+"user=root&password=1234"); 
     preparedStatement = connect.prepareStatement("Select fr,t,ty from subedge"); 

     resultSet = preparedStatement.executeQuery(); 
     int i=0; 

     while(resultSet.next()) { 
      g.addEdgeForIndexing(resultSet.getInt(1),resultSet.getInt(2),resultSet.getInt(3)); 
      i++;    
      System.out.println("edges added to G = "+i); 
     }  

     System.out.println("Loaded " + g.nodeCount() + " nodes."); 

     buildNodes(); 

     System.out.println("Enter first author key:"); 
     BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); 
     String authorkey1 = br.readLine(); 
     int authorID1 = Integer.parseInt(authorkey1); 
     String AuthorID1 = "A"+authorID1; 
     ArrayList<String> p1 = g.getOutEdgesToP(AuthorID1); 
     System.out.println("P1 = " + p1); 

     ArrayList<String> p2 = new ArrayList<String>(); 
     for (int j = 0; j<p1.size();j++){ 
      ArrayList<String> temp = g.getOutEdgesToP(p1.get(j)); 
      if (temp!=null) 
      p2.addAll(temp); 
     } 
     System.out.println("P2 = " +p2); 

     ArrayList<String> CandidateAuthorType1 = new ArrayList<String>(); 
     for (int k = 0; k<p2.size(); k++){ 
      ArrayList<String> temp = g.getInEdgesFromPtoA(p2.get(k)); 
      if(temp!=null) 
       CandidateAuthorType1.addAll(temp); 
     } 
     System.out.println("Candidate Author Type 1= " + CandidateAuthorType1); 

     ArrayList<String> CandidateAuthorType1Unique = removeDuplicates(CandidateAuthorType1); 
     System.out.println("-----------------------------------------------"); 
     System.out.println("Candidate author type 1 and author node weight:"); 
     for (String item : CandidateAuthorType1Unique) { 
      double weight = Collections.frequency(CandidateAuthorType1, item); 
      n.setWeight(item,weight);; 
      System.out.println(n.getName() + " : " + n.getWeight()); 
     }  

     ArrayList<String> CandidatePaperType1 = new ArrayList<String>(); 
     for (int l = 0; l<CandidateAuthorType1.size(); l++){ 
      ArrayList<String> temp = g.getOutEdgesToP(CandidateAuthorType1.get(l)); 
      if(temp!=null) 
       CandidatePaperType1.addAll(temp); 
     } 
     System.out.println("Candidate Paper Type 1= " + CandidatePaperType1); 
    } 


    private static ArrayList<String> removeDuplicates(ArrayList<String> element){ 
     ArrayList<String> result = new ArrayList<>(); 
     HashSet<String> set = new HashSet<>(); 
     for (String item : element) { 
      if (!set.contains(item)) { 
      result.add(item); 
      set.add(item); 
      } 
     } 
     return result; 
    } 

    private static void buildNodes() 
    { 
     String nodeID; 
     double weight = 0; 
     Node n; 
     Iterator it = g.nodeIteratorInitial(); 
     while (it.hasNext()) { 
      nodeID = (String) it.next(); 
      if (!nodeMap.containsKey(nodeID)){ 
       n = new Node(nodeID,weight); 
       nodeMap.put(nodeID, 0); 
      } 
     } 
    } 
} 

Graph.java

import java.lang.reflect.Field; 
import java.util.*; 

public class Graph { 

    private HashSet<String> nodeIDs; 
    public HashMap<Integer, String> nodeIDsWithTN; 
    public HashMap<Integer, String> TNMap; 
    private HashMap<String, ArrayList<String>> edges; 
    private HashMap<String, ArrayList<String>> reverse; 
    private int numNodes; 
    private int numEdges; 
    private int numReverse; 

    public Graph() { 
     edges = new HashMap<String, ArrayList<String>>(); 
     reverse = new HashMap<String, ArrayList<String>>(); 
     nodeIDs = new HashSet<String>(); 
     nodeIDsWithTN = new HashMap<Integer, String>(); 
     TNMap = new HashMap<Integer, String>(); 
     new HashSet(); 
    } 

    public void addEdgeForIndexing(int from, int to, int T) throws IllegalArgumentException, IllegalAccessException { 
     String From = ""+from; 
     String To = ""+to; 
     int type = T; 
     if(T==1) 
     { 
      From="A"+from; 
      To="P"+to; 
     } 
     else if(T==2) 
     { 
      From="P"+from; 
      To="P"+to; 
     }   
     else 
      System.out.println("T ="+T+" value undefined"); 

      Edge e = new Edge(From,To,type); 

      nodeIDs.add(e.From); 
      nodeIDs.add(e.To); 

      ArrayList<String> tmp = null; 
      if (edges.containsKey(e.From)) 
       tmp = (ArrayList<String>) edges.get(e.From); 
      else { 
       tmp = new ArrayList<String>(); 
       edges.put(e.From,tmp); 
      } 
      tmp.add(e.To); 

      ArrayList<String> tmp2 = null; 
      if (reverse.containsKey(e.To)) 
       tmp2 = (ArrayList<String>) reverse.get(e.To); 
      else { 
       tmp2 = new ArrayList<String>(); 
       reverse.put(e.To,tmp2); 
      } 
      tmp2.add(e.From); 
    } 

    public int nodeCount() { 
     if(nodeIDs.size() > 0) 
      return nodeIDs.size(); 
      // else return numNodes; 
     return numEdges; 
    } 

    public int countInEdges(Integer key) { 
     if (!reverse.containsKey(key)) return 0; 
      return ((ArrayList<?>) reverse.get(key)).size(); 
    } 

    public int countOutEdges(Integer key) { 
     if (!edges.containsKey(key)) return 0; 
      return ((ArrayList<?>) edges.get(key)).size(); 
    } 

    public ArrayList<String> getInEdgesFromPtoA(String id) { 
     if (!reverse.containsKey(id)) return null; 
      ArrayList<String> a = reverse.get(id); 
      ArrayList<String> result = new ArrayList<String>(); 
       for(int j=0;j<a.size();j++){ 
         if(a.get(j).startsWith("A")){ 
          result.add(a.get(j));       
         } 
       } 
     return result; 
    } 

    public ArrayList<String> getOutEdgesToP(String id) { 
     if (!edges.containsKey(id)) return null;  
      ArrayList<String> a = edges.get(id); 
      ArrayList<String> result = new ArrayList<String>(); 
      for(int j=0;j<a.size();j++){ 
       if(a.get(j).startsWith("P")){ 
       result.add(a.get(j));       
       } 
      } 
     return result; 
    } 

    public Iterator<String> nodeIteratorInitial() { 
     return nodeIDs.iterator(); 
    } 
} 

Edge.java

public class Edge { 


    String From; 
    String To; 
    int type; 
    private static int counter = 0; 
    public Edge(String From, String To, int type) { 
     this.From = new String(From); 
     this.To = new String(To); 
     this.type = type; 
    // System.out.println("edges added from " + From + " to " + To + " with type "+ type); 
    } 

    public String getFrom(){ 
     return From; 
    } 

    public String getTo(){ 
     return To; 
    } 

    public int getType(){ 
     return type; 
    } 

    public void setFrom(String From){ 
     this.From = From; 
    } 

    public void setTo(String To){ 
     this.To = To; 
    } 

    public void setType(int type){ 
     this.type = type; 
    } 
} 

Node.java

public class Node { 

     String id; 
     double weight; 
     private static int counter = 0; 

     public Node(String id,double weight) { 
      this.id = id; 
      this.weight = weight;; 

     } 

     public double getWeight(){ 
      return weight; 
     } 

     public String getName() { 
      return id; 
     } 

     public void setWeight(String id, double weight){ 
     if (this.id==id){ 
      this.weight=weight;} 
      System.out.println("The node " + id + " has weight " + weight); 
     } 


     public void setName(String id){ 
      this.id=id; 
     } 

} 
+0

正如你問過關於設計的建議,我發現setWeight上的id參數很奇怪。因爲它也涉及到裏面的ID檢查。最好是通過Id獲取節點,然後執行setter。 – Yantraguru 2015-04-01 06:26:28

+0

我使用id參數的原因是爲了能夠更新某個節點id的權重。我可以問你如何按照你的建議獲取節點ID嗎? – fuschia 2015-04-01 06:50:15

+1

您正在使用地圖'nodemap'來存儲您正在創建的節點。而不是僅存儲標識符,您存儲,那麼當您需要獲取節點時,請查詢此映射,通過id獲取節點並更新其權重。所以,這樣你可以增加權重到正確的節點 – Yantraguru 2015-04-01 06:55:52

回答

1

正如你在Ranker()構造函數,當調用構造函數初始化n,該String id尚未分配,因此總是包含值null。因此你的Node n也得到id作爲null。這就是爲什麼重量不會像setWeight(String id, double weight)功能那樣更新的原因,新的idnull相比較,因爲它總是返回false,因此重量不會更新。

你可以使你的代碼

1)以下更改您的Ranker()構造取下n = new Node(id,weight)初始化。

2)在Ranker類的main方法中添加以下行而不是n.setWeight(item,weight)

if (n == null) 
    n = new Node(item, weight); 
n.setWeight(item, weight);