How do create array in java and pass in graphviz java method? - java

I am using graphviz with Java, and I need to loop data array and need to define relationship
Graph g = graph("example5").directed().with(node("abc")
.link(node("xyz")),node("abc")
.link(node("xyz")));
Graphviz viz = Graphviz.fromGraph(g);
viz.width(200).render(Format.SVG).toFile(new File("example/ex5.svg"));
I need to create array that should have multiple node("abc").link(node("xyz")) then pass it to with method

I think doing something like the following should work.
Here I am iterating and creating a node, calling link on the current node and assigning the the node, before reassigning current.
The entire list is then passed to with
List<Node> nodes = new ArrayList<>();
Node curr = node(String.valueOf(0));
for(int i = 0; i < 5; i++){
Node next = node(String.valueOf(i+1));
curr.link(next);
nodes.add(curr);
curr = next;
}
Graph g = graph("example5").directed().with(nodes);

Related

Create objects dynamically and run BFS

I want to modify the code below for getting data from file dynamically and run the BFS. I have tried with loop but i am stuck on how i will make dynamic connection of the nodes using the anonymous objects.
Node nA=new Node("101");
Node nB=new Node("102");
Node nC=new Node("103");
Node nD=new Node("104");
Node nE=new Node("105");
//Create the graph, add nodes, create edges between nodes
Graph g=new Graph();
g.addNode(nA);
g.addNode(nB);
g.addNode(nC);
g.addNode(nD);
g.addNode(nE);
g.setRootNode(nA);
g.connectNode(nA,nB);
g.connectNode(nA,nC);
g.connectNode(nA,nD);
g.connectNode(nD,nE);
There will be an edge file containing the connected nodes.My sample code is below
String[] nodes = {"1","2","3","4"};
ArrayList<Node> Nodelist = new ArrayList<Node>();
//create node objects
for(String val : nodes) {
Nodelist.add(new Node(val));
}
//create graph nodes from array nodelist
Graph g = new Graph();
for(Node val : Nodelist) {
g.addNode(val);
}
g.setRootNode(Nodelist.get(0));
//then in loop to create connection between nodes from file in structure [101,102] , [102,103] ...
for(){
int[] arr = file.split(",")
g.connectNode(arr[0],arr[1])
}
My problem here is with the object names.I have tried using anonymous object and then adding them in addNode() But how i will create the connection of the nodes that will be read from file using the anonymous objects array.I don't know if i am clear what i am trying to achieve.
How i can add them in HashMap but using same key and array of values.I have tried with arraylist but saves only the last value.
What you're missing is having a way to find a node by it's value. You can have it by replacing the list of nodes with a map, where node's value is a key (assumption: each value is different).
Map<String, Node> nodeMap = new HashMap<>();
for (String val: nodes) {
nodeMap.put(val, new Node(val));
}
Later on to connect nodes get them from nodeMap by their value.

duplicating a node in a linked list java

just to start off, this is homework and thank you for your assistance ahead of time. I keep getting stuck on little problems so I am hoping you guys can help me with one. What I am trying to do is create a linked list that has multiples functions. The one I am having trouble with is sorting(I can do the other ones). Each node holds a string, an integer and a double. I need to be able to sort by each of these and by the order it was inputted, on the user's request. ***It is also important to mention that the variables in my object are private and my object is called list1. Basically, I have to make one linked list for the chronological order and one for each other order.
My plan is to insert the nodes in their correct order as the user inputs them. So as the user inputs a node, that node needs to go in the correct place in the chronological list and in the other lists. So, I need to copy the node to do this. However, I cannot simply just say
icopy(copy for integer) = newNode(node the user just inputted)
That only changes the address. When I went to my instructor he told me that I should say:
icopy.data = newNode.data;
("data" being the shortcut way of mentioning that I need to get the individual data types within the node.) So I wrote:
icopy.GetI() = newNode.GetI();
When I do this I encounter this error: unexpected type required:variable, found:value. I am not sure what to do. Any assistance would be appreciated and I would be happy to clarify anything.
*GetI: method in my object that gives access to the integer value in each node.
*p: pointer for the Chronological
*pi: pointer for the integer.
*fi: front of the integer linked list
public static void main(String args[])
{
String repeat = "y";
boolean inserted = false;
list1 fChr = null;
list1 p = fChr;
list1 icopy = null;
list1 scopy = null;
list1 dcopy = null;
list1 fd = fChr;//front of the double list
list1 fi = null;//front of the integer list
list1 fStr = fChr;//front of the string list~
while(repeat.equals("y"))//while the user agrees to adding a new node
{
if(fChr == null)// if the front is empty
{
fChr = new list1();//create a new node by calling object and sets it as the front
}
else
{
p = fChr;
while(p.next != null)//finds the end of the Linked list
{
p = p.next;//moves the pointer p down the list
}
list1 newNode = new list1();
icopy.GetI() = newNode.GetI();// make a copy of newNode
p.next = nexNode;//put in chronological order
while(p != null)
{
if(fi == null)
{
fi = n;
}
else if(n.GetI() < fi.GetI)//check at beginning
{
//put at beginning
}
else if(icopy.GetI() < p.next.GetI())//check in between nodes
{
//put in between
}
//does it go at the end
}
}
repeat = JOptionPane.showInputDialog("Would you like to add a node [y/n]");
}
PrintMenu(fChr, fi, fd, fStr);// sends the user to the menu screen
}
There are a few things here that you are not understanding. Firstly, in Java iCopy.getI() = ... makes no sense. When a method returns a value it needs to be assigned to a variable if you wish to change it. If you want to change the instance variable you need a separate method called something like iCopy.setI().
It sounds as though you're not asking for help with the sorting so I'll restrict my answer to creating copies of the list.
What your professor is getting at is that the easiest way to ensure the data is consistent in your several linked lists is to separate the class storing the data from the nodes of the list. So I would expect your class structure to end up looking something like:
class Data {
private final int intValue;
private final String strValue;
private final double doubleValue;
}
class Node {
private final Data data;
private Node next;
public Node(Data data) {
this.data = data;
this.next = null;
}
}
Now if you want to create a new linked list with the same data as the old one then you can add a constructor to Node that creates a reference to the original data:
class Node {
public Node copy() {
Node copy = new Node(data);
if (next != null)
copy.next = next.copy();
return copy;
}
}
Hopefully you can see what that does: it creates a new node referencing the same data as this one and then uses recursion to copy the rest of the list.
Now creating each of the sort orders could look like:
Node listByInt = list.copy();
/* code to sort listByInt according to data.intValue */
Add a comment if you want some hints on sorting as well but I suggest you get your code to the point of having equal copies of lists before attempting that.
As a final note, you don't necessarily need to have separate linked lists to solve this problem. An alternative would be to store the original insertion order in the node. You could then sort by any order (including original insertion order) before printing the list. Personally I'd prefer that as a solution unless there are performance issues (e.g. you need to use each sorted list many times).

Adding to a specified List within a matrix of Lists

This is a homework program I"m working on for an algorithms course. The task is to simulate an adjacency matrix for a graph using a matrix of Lists (this is Java btw). The element of the matrix is interpreted as the first node. Any nodes it is connected to in the graph are added to the list of that is that matrix element. I have constructed the matrix as such:
List<Node>[] weightedList = new List[size]
I understand that there are issues with Lists of Objects and type-checking. I then call a method initializeList() to construct the initial structure.
protected void initializeList() {
List<Node> list = new ArrayList<Node>();
for (int i = 1; i < Tester.size; i++){
weightedList[i] = list;
}
}
As I'm processing my input data I need to "construct" the graph based on given node values. My problem lies here, when I call addEdge() (effectively, connecting two nodes creates an Edge), the node I am trying to add gets added to every element of the matrix. Here is the method:
public static void putEdge(Edge e) {
Node node1 = e.getVertex1();
Node node2 = e.getVertex2();
int dim1 = node1.getNode();
if (dim1 < Tester.size){
weightedList[dim1].add(node2);
}
}
Is my issue related to the type-checking problems inherent in Lists of Objects or something else? Please advise.
-- JQK
You assign the same list instance to all the indices of the array.
You should instantiate each list inside the loop :
protected void initializeList() {
for (int i = 0; i < Tester.size; i++){
List<Node> list = new ArrayList<Node>();
weightedList[i] = list;
}
}
This way, each index in the array will contain a different ArrayList instance.
And you probably should iterate from 0, since that's the first index of the array.
You're running into the problem here of assignment only copying a reference to an object, not the object itself. #Eran's solution shows how to assign a different list to each matrix element.
Thank you #Eran. Your solution was correct. Simple mistake on my part. I cannot upvote yet and I'm not sure how to give you credit for the solution.
My error was the location of the assignment statement in initializeList()
This is the correct format provided by #Eran.
protected void initializeList() {
for (int i = 0; i < Tester.size; i++){
List<Node> list = new ArrayList<Node>();
weightedList[i] = list;
}
}

how to declare object variable name in loop

public class Node<E>{
Node p,l,r;
int height;
String s;
/** class body**/
};
String[] S=new String[5000];
int i = 0;
while (i < 5000){
Node<E> x=new Node<E>();
x.s=S[i];
i++;
}
I want to make 5000 Node objects.
above code assign same variable name x every time but i want different variable name.
then how to declare 5000 class variable name without declaring it manually.
is there something by which i can create 5000 Node class object with ease.
In Java: If you don't want to change the size of the array, you can use one. Otherwise, you can use a dynamic array, like an ArrayList:
int size = 5000;
Node[] S = new Node[size];
for (int i = 0; i < size; i++) {
S[i] = new Node();
}
Edit: Assigning a name dinamically in Java is not possible. But, using the method above, you can access to the elements by
S[index]
where index will be in the range [0,size-1]
Java:
I would suggest making a Node Array with a size of 5000. This would allow you to loop through this array, placing any value inside each individual Node.
public void node() {
Node[] allNodes = new Node[5000];
//Print out all node values
for (Node currentNode : allNodes) {
currentNode.setNodeValue("Some value");
System.out.println("Name: " + currentNode.getNodeValue());
}
}
In this example, I am creating a Node array, with a size of 5000. Then, I use an enhanced for loop to loop through the array. I set every node value in the "allNodes" array to "Some value", then I print it.
When you need to access those values again, just create another loop to get each value.
Edit: You cannot "mass name variables" in Java. You can create arrays which store multiple objects, but they don't have specific names. You access array items by pointing to an index in the array
We can't do this without using an array because there is no way to change the name of the variable.
Make 5000 Node objects by creating Node array
Node[] x = new Node[size];
Please refer this code snippet
int size = 5000;
String[] S = new String[size];
int i = 0;
Node[] x = new Node[size];
while (i < 5000) {
x[i].s = S[i];
i++;
}

Deep Copying in Java

I have a Java class, Node as follows :
class Node
{
public ArrayList<Node> nbrs;
}
Each Node object contains a list of all its neighbours within the ArrayList nbrs, and nothing else.
Now I need to write a function :
public Node copy( Node curr )
This function should perform a deep copy of the entire graph rooted at curr, and return the equivalent copy for curr.
I tried implementing a copy constructor within the class Node as follows :
public Node( Node n )
{
for( Node curr : n.nbrs )
n.nbrs.add( new Node( curr ));
}
I now copy the Node n, within my copy function.
But I have found that when the graph contains loops, this code keeps running infinitely.
Any help on how I should overcome this problem.
PS : This is an interview question faced by my friend, so the class Node cannot contain any more variables
If the Node class had a parent you'd be able to check for infinite recursion that way. But it doesn't. So you'll need to maintain some state during the clone operation, a Set containing the nodes you are currently recursing into. Refuse to descend into a node that is already in the Set.
Save the mapping between the old nodes being copied and the new ones in a data structure that allows retrieving elements based on identity (i.e. that retrieves objects iff the == operator returns true). An example for this would be the IdentityHashMap. If you create a new node, then save it to the data structure.
Before creating a new Node from a previous ony, try to retrieve the node from the data structure. If you have such a node already, then add the retrieved one to the parent. If you don't have such a node, then continue creating one (and add it).
The standard trick is to first create all the new nodes and store them in a map (from old nodes to new nodes). Then in a second pass over all the nodes, all the edges are added (by adding to n.nbrs.add).
Consider making Node objects immutable. In this case using shared instance will do no harm.
If you can modify the Node class and make it Serializable, then you serialize/deserialize the object and get a new graph of objects.
Sample code to illustrate the point:
class Node implements Serializable
{
public List<Node> nbrs = new ArrayList<Node>();
}
Node n1 = new Node();
Node n2 = new Node();
Node n3 = new Node();
n1.nbrs.add(n2);
n2.nbrs.add(n1);
n2.nbrs.add(n3);
n3.nbrs.add(n2);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream dos = new ObjectOutputStream(baos);
dos.writeObject(n1);
dos.writeObject(n2);
dos.writeObject(n3);
ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
ObjectInputStream ois = new ObjectInputStream(bais);
Node n4 = (Node) ois.readObject();
Node n5 = (Node) ois.readObject();
Node n6 = (Node) ois.readObject();
At this stage, you'll have a new set of Node objects, which correctly reference each other.
There is no base case in the recursion, other than a node with no neighbors.
Daniel Earwicker suggested using a Set to make sure we don't add the same neighbor twice. Sounds good, but how can we tell if a node is in the Set? The default implementation of equals is really just == so no two nodes would be considered equal. The Set contains method relies on equals to determine if an object has already been added to a set. We cold add an id field to the node and then implement boolean equals(Node other) by checking for id equality. That should make the Set solution work.

Categories

Resources