在java中生成无返回边的有向图
我试图制作一个有向图生成器,在LJF算法中使用它。问题是我不知道如何避免返回边(例如,如果我得到1->2,我不想得到2->1)。我只在在java中生成无返回边的有向图,java,algorithm,graph,generator,Java,Algorithm,Graph,Generator,我试图制作一个有向图生成器,在LJF算法中使用它。问题是我不知道如何避免返回边(例如,如果我得到1->2,我不想得到2->1)。我只在if中做了一个声明,以避免同一节点的边缘(例如1->1)。另一个问题是,我的生成器有时会让一些节点没有任何边,但每个节点至少需要一条边。我想要达到的是类似于BST的东西,但没有规定最多有2条边,可以更多 public class Graph { private final int maxT = 3; private final int chance = 30;
if
中做了一个声明,以避免同一节点的边缘(例如1->1)。另一个问题是,我的生成器有时会让一些节点没有任何边,但每个节点至少需要一条边。我想要达到的是类似于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());
}
}
}
}
我看到我新添加的列表中充满了空元素,我附加了任务类:
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;
}
}
==编辑====
现在我遇到了一个问题,我的发电机给了我我不想要的周期。所以,我又增加了一次进行传输的机会,但有时我会获得空闲节点或分离图形
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)));}
}
List keys=new ArrayList(tasks.keySet());
对于(int i=0;i
您可以使用由目标节点索引的映射,而不是每个任务的传输
列表。然后,您可以轻松地执行检查,确定是否已经存在后向边缘。此外,可以添加一个条件,以便在节点没有边时始终生成边:
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());
}
}
}
}
公共类图{
私有最终整数最大值=3;
private final int chance=30;//连接边的机会
Map tasks=newhashmap();
公共图(){
随机r=新随机();
int range=r.nextInt(maxT)+3;//节点数
对于(int i=0;i而不是每个任务的传输
列表,您可以使用由目标节点索引的映射。然后,您可以轻松执行检查,是否已经存在后向边。此外,您可以添加一个条件,以便在节点没有后向边时始终生成边:
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());
}
}
}
}
公共类图{
私有最终整数最大值=3;
private final int chance=30;//连接边的机会
Map tasks=newhashmap();
公共图(){
随机r=新随机();
int range=r.nextInt(maxT)+3;//节点数
对于(inti=0;i来说,如果有(1->2),则很容易避免(2->1)EDE。对于每个边(x->y),假设x
向迭代添加顺序:
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)));}
}
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));
}
}
List keys=new ArrayList(map.keySet());
对于(int i=0;i
要解决完整的问题,您需要这样的算法:
N
-一组未访问的顶点。所有顶点都在开始处
V
-访问顶点集。开始时为空
从N
中获取随机顶点x
从第二次迭代添加边(来自V
->x
)的随机顶点
将x
添加到V
并从N
中删除x
继续执行步骤3或退出
您的图形将是无循环定向的。如果有(1->2),很容易避免(2->1)EDE。对于每个边(x->y),假设x
向迭代添加顺序:
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)));}
}
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));
}
}
List keys=new ArrayList(map.keySet());
对于(int i=0;i
要解决完整的问题,您需要这样的算法:
N
-一组未访问的顶点。所有顶点都在开始处
V
-访问顶点集。开始时为空
从N
中获取随机顶点x
从第二次迭代添加边(来自V
->x
)的随机顶点
将x
添加到V
并从N
中删除x
继续执行步骤3或退出
您的图形将是无循环的。您是否认为有一个严格的树,或者如果有两条从a到B的路径,例如1->2->4和1->3->4,它是否可以?更长的循环可以吗,比如说,1->2->3->->->->4->1?在NullPointerException行中:使用tasks.get(key.get(i))…
而不是tasks.get(i)…
@Beethoven是的,它是有效的,很明显,idk为什么我没有看到它。不管怎样,你知道在这个例子中如何避免自由节点吗?@Beethoven,因为这一个给出了循环,所以我又加了一次机会来做一个transmission@Buszman如果传输列表仍然为空,则必须绕过随机,如下所示:if(tasks.get(keys.get(i)).isEmpty()| | r.nextInt(100)
你想有一个严格的树吗,或者如果从a到B有两条路径,例如1->2->4和1->3->4,它可以吗?在NullPointerException行中使用tasks.get(key.get(i))…
而不是tasks.get(i)可以吗…
@Beethoven是的,它是有效的,很明显,idk为什么我没有看到它。不管怎样,你知道在这个例子中如何避免自由节点吗?@Beethoven,因为这一个给出了循环,所以我又加了一次机会来做一个transmission@Buszman如果传输列表仍然为空,则必须绕过随机,如下所示:if(tasks.get(keys.get(i)).isEmpty()| | r.nextInt(100)
这似乎不错,但我的程序的下一步是在处理器上调度此任务,我不知道如何引用这一秒Map@Buszman如果需要任务的传输
,可以使用tasks.get(Task).values()
,即从内部映射获取值的集合(Transmission
s)。这是否回答了问题