简单加权图:循环不允许异常
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 语句进行简单检查来解决这个问题,如果它与源不同,则只添加一条边。
我正在尝试创建一个程序来跟踪人们的电子邮件。我在我的图表中使用一个字符串作为顶点(该字符串是他们的电子邮件)和一个来自 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 语句进行简单检查来解决这个问题,如果它与源不同,则只添加一条边。