简单加权图:循环不允许异常

时间:2016-03-04 17:11:43

标签: java graph jgrapht

我正在尝试创建一个跟踪人们电子邮件的程序。我在图表中使用字符串作为顶点(字符串是他们的电子邮件)和Jgrapht中的DefaultWeightedEdge。如果这些人在彼此之间发送一封电子邮件,那么连接该节点的边缘的权重将设置为1.如果他们在已经发送了一封电子邮件后发送了另一封电子邮件,我将边缘权重增加1。

我认为我的主要代码是正确的,但是我得到了这个例外。

  

线程“main”中的异常java.lang.IllegalArgumentException:循环   不允许的   org.jgrapht.graph.Abs​​tractBaseGraph.addEdge(AbstractBaseGraph.java:203)     at groupProject.Analysis.StoreEmails(Analysis.java:58)at   groupProject.AnalyserRun.main(AnalyserRun.java:7)

这是我的代码:

public class Analysis {
    SimpleWeightedGraph<String, DefaultWeightedEdge>  graph = new SimpleWeightedGraph<String, DefaultWeightedEdge>(DefaultWeightedEdge.class);
    jsonParser jP = new jsonParser("/Users/Kieran/test/test2.json");
    int numEmails = jP.getNumEmails();
    ArrayList<String> senders = new ArrayList<String>();
    ArrayList<String> recipients = new ArrayList<String>();
    ArrayList<String> all = senders;
    ArrayList<DefaultWeightedEdge> edges = new ArrayList<DefaultWeightedEdge>();

    public void StoreEmails(){
        //Creates vertex's for every sender
        for(int i = 0; i < numEmails; i++){
            Email email = jP.parseJSON(i);
            if(!senders.contains(email.getSender())){
                graph.addVertex(email.getSender());
                senders.add(email.getSender());
            }
        }

        //creates vertex's for every recipient
        for(int i = 0; i < numEmails; i++){
            Email email = jP.parseJSON(i);
            if(email.getRecipients().length != 0){
                    for(int j = 0; j < email.getRecipients().length; j++){
                        if(!recipients.contains(email.getRecipients()[j])){
                            graph.addVertex(email.getRecipients()[j]);
                            recipients.add(email.getRecipients()[j]);
                        }
                    }
            }
        }

        all.removeAll(recipients);
        all.addAll(recipients);
        /*
         * Adds all of the edges from senders to recipients and if the edge already exists then it will increase the weight by one
         * however is is a directed graph so you need to check both pairs.
         */
        for(int j = 0; j < numEmails; j++){
            Email email = jP.parseJSON(j);
            for(int k = 0; k < email.getRecipients().length; k++){
                if(graph.containsEdge(email.getSender(), email.getRecipients()[k])){
                    int current_weight = (int) graph.getEdgeWeight(graph.getEdge(email.getSender(), email.getRecipients()[k]));
                    graph.setEdgeWeight(graph.getEdge(email.getSender(), email.getRecipients()[k]), current_weight+1);
                }else{
                    DefaultWeightedEdge e = graph.addEdge(email.getSender(), email.getRecipients()[k]);
                    graph.setEdgeWeight(e, 1);
                }
            }
        }
        builder();
    }

    public int calcConnectedness(String s1,String s2){
        int connectedness = 0;
        int weightS1S2 = 0;
        int weightS2S1 = 0;
        if(graph.containsEdge(s1, s2)){
            weightS1S2 = (int) graph.getEdgeWeight(graph.getEdge(s1, s2));
            connectedness += weightS1S2;
        }
        /*if(graph.containsEdge(s2, s1)){
            weightS2S1 = (int) graph.getEdgeWeight(graph.getEdge(s2, s1));
            connectedness += weightS2S1;
        }*/
        return connectedness;
    }

    public void builder(){
        for(int i = 0; i < all.size(); i++){
            for(int j = i+1; j < all.size(); j++){
                    if(graph.containsEdge(all.get(i), all.get(j)))
                        make(all.get(i), all.get(j), calcConnectedness(all.get(i), all.get(j)));
            }
        }
    }

    public void make(String user1, String user2, int connectedness){
        System.out.println(user1 + " " + user2 + " Are connected by a factor of: "+connectedness);
    }
}

经过一些研究后,我能找到的唯一可能导致问题的信息是,在Java中,字符串是不可变的。但是,我仍然无法解决我的问题。

1 个答案:

答案 0 :(得分:-1)

答案在这段代码中:

}else{
                    DefaultWeightedEdge e = graph.addEdge(email.getSender(), email.getRecipients()[k]);
                    graph.setEdgeWeight(e, 1);
                }

事实证明,email.getSender()在email.getRecipients()中,因此边缘的源和目的地是相同的,即循环。我通过事先用if语句做一个简单的检查来解决这个问题,如果它与源不同,只添加一条边。