我正在尝试创建一个跟踪人们电子邮件的程序。我在图表中使用字符串作为顶点(字符串是他们的电子邮件)和Jgrapht中的DefaultWeightedEdge。如果这些人在彼此之间发送一封电子邮件,那么连接该节点的边缘的权重将设置为1.如果他们在已经发送了一封电子邮件后发送了另一封电子邮件,我将边缘权重增加1。
我认为我的主要代码是正确的,但是我得到了这个例外。
线程“main”中的异常java.lang.IllegalArgumentException:循环 不允许的 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中,字符串是不可变的。但是,我仍然无法解决我的问题。
答案 0 :(得分:-1)
答案在这段代码中:
}else{
DefaultWeightedEdge e = graph.addEdge(email.getSender(), email.getRecipients()[k]);
graph.setEdgeWeight(e, 1);
}
事实证明,email.getSender()在email.getRecipients()中,因此边缘的源和目的地是相同的,即循环。我通过事先用if语句做一个简单的检查来解决这个问题,如果它与源不同,只添加一条边。