[英]Generate directed graph without returning edges in java
I'm trying to make a directed graph generator to use it in LJF algorithm. 我正在尝试制作一个有向图生成器以在LJF算法中使用它。 The thing is that I have no idea how to avoid the returning edges (eg. if I got 1 -> 2 I don't want to have 2 -> 1).
问题是我不知道如何避免返回边缘(例如,如果我得到1-> 2,我不想拥有2-> 1)。 I only made a statement in
if
to avoid edges to the same node (eg. 1 -> 1). 我只是在声明
if
避免边缘到同一节点(例如1-> 1)。 Another problem is that my generator sometimes leaves some nodes alone without any edges but I need at least one edge per node. 另一个问题是我的生成器有时会留下一些没有任何边缘的节点,但是每个节点至少需要一个边缘。 What I want to reach is something similar to BST but there is no rule to have max 2 edges, it can be more.
我想达到的效果与BST类似,但是没有最大2条边的规则,它可以更多。
public class Graph {
private final int maxT = 3;
private final int chance = 30; //chance to connect edges
Map<Task, List<Transmission>> tasks = new HashMap<Task, List<Transmission>>();
public Graph() {
Random r = new Random();
int range = r.nextInt(maxT) + 3; // number of nodes
for(int i = 0; i<range; i++){
List<Transmission> trans = new ArrayList<Transmission>();
tasks.put(new Task(i), trans);
}
System.out.println("Number of tasks: " + tasks.size());
for(Task key1 : tasks.keySet()){
for(Task key2 : tasks.keySet()){
if(key1 != key2 && r.nextInt(100) < chance)
tasks.get(key1).add(new Transmission(key1,key2));
}
}
}
public void printGraph(){
System.out.println("Generated graph:\n");
for(Task key : tasks.keySet()){
System.out.println(key.getId());
for(Transmission ts : tasks.get(key)){
System.out.println("\t" + ts.getT1().getId() + " -> " + ts.getT2().getId());
}
}
}
}
====EDIT==== ====编辑====
After adding order to iterations: 在为迭代添加顺序之后:
List<Task> keys = new ArrayList<Task>(tasks.keySet());
for(int i = 0; i < keys.size() - 1; i++){
for(int j = i + 1; j < keys.size(); j++){
tasks.get(i).add(new Transmission(keys.get(i), keys.get(j)));}
}
I got java.lang.NullPointerException exception on this line: 我在此行上收到java.lang.NullPointerException异常:
tasks.get(i).add(new Transmission(keys.get(i), keys.get(j)));}
I see that my newly added list is full of null elements, I attach then Task class: 我看到新添加的列表中充满了null元素,然后附加Task类:
import java.util.Random;
public class Task extends Node{
Random r = new Random();
int tstart; // start time
int tend; // end time
int size;
int deadline;
public Task(int id) {
super(id);
tstart = r.nextInt(5);
tend = r.nextInt(5);
size = r.nextInt(10);
deadline = r.nextInt(8);
}
public int getDeadline() {
return deadline;
}
public int getTstart() {
return tstart;
}
public int getTend() {
return tend;
}
public int getSize() {
return size;
}
} }
===EDIT==== ===编辑====
Now I got the problem that my generator gives me cycles which I don't want to have. 现在我遇到了一个问题,就是我的发电机给了我不想拥有的周期。 So, I added again chance to make a transmission but sometimes I got free nodes or to seperate graphs.
因此,我再次增加了进行传输的机会,但有时我得到了自由节点或分离了图表。
List<Task> keys = new ArrayList<Task>(tasks.keySet());
for(int i = 0; i < keys.size() - 1; i++){
for(int j = i + 1; j < keys.size(); j++){
if(r.nextInt(100) < chance && tasks.get(keys.get(i)).isEmpty())
tasks.get(keys.get(i)).add(new Transmission(keys.get(i), keys.get(j)));}
}
It is simple to avoid (2 -> 1) edes if you have (1 -> 2). 如果您拥有(1-> 2),则避免(2-> 1)edes很简单。 For each edge (x -> y) assume that x < y.
对于每个边(x-> y)假设x <y。
Add ordering to iterations: 为迭代添加顺序:
List<T> keys = new ArrayList<>(map.keySet());
for (int i = 0; i < keys.size() - 1; i++) {
for (int j = i + 1; j < keys.size(); j++) {
make new Transmission(keys.get(i), keys.get(j));
}
}
To solve the complete problem you need an alogorithm like this: 要解决完整的问题,您需要这样的算法:
N
- set of non visited vertexes. N
未访问的顶点集。 All vertexes at the beginning. V
- set of visited vertexes. V
访问的顶点集。 Empty at the beginning. x
from N
. N
取随机顶点x
。 V
-> x
) from second iteration. V
> x
随机顶点)。 x
to V
and remove x
from N
. x
加到V
并从N
删除x
。 Your graph will be oriented cycles-free. 您的图形将无周期定向。
Instead of a list of Transmission
s for each Task
, you could use a map, indexed by the destination node. 您可以使用按目标节点索引的映射来代替每个
Task
的Transmission
列表。 Then, you can easily perform a check, whether a backwards-edge already exists. 然后,您可以轻松地执行检查,是否已经存在向后边缘。 Furthermore, you can add a condition to always generate an edge when the node has none:
此外,您可以添加条件以在节点没有节点时始终生成边:
public class Graph {
private final int maxT = 3;
private final int chance = 30; //chance to connect edges
Map<Task, Map<Task, Transmission>> tasks = new HashMap<>();
public Graph() {
Random r = new Random();
int range = r.nextInt(maxT) + 3; // number of nodes
for(int i = 0; i<range; i++){
Map<Task, Transmission> trans = new HashMap<>();
tasks.put(new Task(i), trans);
}
System.out.println("Number of tasks: " + tasks.size());
for(Task key1 : tasks.keySet()){
for(Task key2 : tasks.keySet()){
if(key1 != key2
&& !tasks.get(key2).containsKey(key1) // Don't generate an edge, if there already is a reverse edge
&& (tasks.get(key1).isEmpty() // Always generate an edge, if there is none
|| r.nextInt(100) < chance))
{
tasks.get(key1).put(key2, new Transmission(key1,key2));
}
}
}
}
public void printGraph(){
System.out.println("Generated graph:\n");
for(Task key : tasks.keySet()){
System.out.println(key.getId());
for(Transmission ts : tasks.get(key).values()){
System.out.println("\t" + ts.getT1().getId() + " -> " + ts.getT2().getId());
}
}
}
}
EDIT 编辑
New solution trying to incorporate all requirements discussed in the various comments: 试图合并各种注释中讨论的所有要求的新解决方案:
public Graph() {
Random r = new Random();
int range = r.nextInt(maxT) + 3; // number of nodes
for(int i = 0; i<range; i++){
List<Transmission> trans = new ArrayList<Transmission>();
tasks.put(new Task(i), trans);
}
System.out.println("Number of tasks: " + tasks.size());
List<Task> keys = new ArrayList<Task>(tasks.keySet());
for(int i = 0; i < keys.size() - 1; i++) {
Task task1 = keys.get(i);
List<Transmission> task1Transmissions = tasks.get(task1);
task1Transmissions.add(new Transmission(task1, keys.get(i + 1)));
for(int j = i + 2; j < keys.size(); j++) {
if(r.nextInt(100) < chance)
task1Transmissions.add(new Transmission(task1, keys.get(j)));
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.