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

Simple weighted Graph: Loops not allowed exception

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

我认为我的大部分代码都是正确的,但是我遇到了这个异常。

Exception in thread "main" java.lang.IllegalArgumentException: loops not allowed at org.jgrapht.graph.AbstractBaseGraph.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 中的字符串是不可变的。但是,我还是没能解决我的问题。

答案在这段代码中:

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

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