我试图让有向图生成器在LJF算法中使用它。问题是我不知道如何避免返回边缘(例如,如果我得到1 - > 2,我不想要2 - > 1)。我只在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());
}
}
}
}
==== EDIT ====
为迭代添加订单后:
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)));}
}
我在这一行得到了java.lang.NullPointerException异常:
tasks.get(i).add(new Transmission(keys.get(i), keys.get(j)));}
我看到我新添加的列表中充满了空元素,然后我附上了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 ====
现在我遇到了问题,我的发电机给了我一些我不想要的循环。所以,我再次添加机会进行传输,但有时我会获得自由节点或单独的图形。
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)));}
}
答案 0 :(得分:2)
如果你有(1 - > 2),则很容易避免(2 - > 1)edes。对于每个边缘(x - > y),假设x <0。收率
为迭代添加排序:
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));
}
}
要解决完整的问题,你需要这样的算法:
N
- 一组非访问顶点。开头的所有顶点。V
- 访问过的顶点集。开头就空了。x
获取随机顶点N
。V
的随机顶点 - > x
)。 x
添加到V
,然后从x
删除N
。您的图表将面向无周期。
答案 1 :(得分:0)
您可以使用由目标节点编制索引的地图,而不是每个Transmission
的{{1}}列表。然后,您可以轻松地执行检查,是否已存在向后边缘。此外,您可以添加条件以在节点没有时始终生成边缘:
Task
修改强>
尝试纳入各种评论中讨论的所有要求的新解决方案:
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());
}
}
}
}