I searched some times but didn't get a clue.
I'm trying to set up a directed graph. Each node (instance of the class Node) should hold a bool visited to see if it was visited by a search function.
After the search is completed i want to reset the bool visited for all instances of the class without running through them again.
Is there some way i can go - or am I totally on the wrong track?
Thanks for help and cheers,
Mike
// Cans.java
public class Cans {
public static void main(String[] args) {
int[] fillLevels = {2,15,3};
int[] states = {8,0,0};
node MyNode = new node(3,0);
MyNode.setfillLevels(fillLevels);
node MyLink = new node(3,1);
MyNode.addLink(MyLink);
MyNode.setStates(states);
MyLink.printStates();
System.out.println("Number of links: "+MyNode.getNumLinks());
}
boolean fillState(node nodeA, int stateA,node nodeB, int stateB){
int value = nodeA.getState(stateA);
nodeA.setState(stateA, value);
return true;
}
}
..
// node.java
import java.util.*;
public class node {
private int[] states;
private static int[] fillLevels;
private int level;
private int n_nodes;
private static int id0 = 0;
private int id;
private boolean visited;
List<node> next = new ArrayList<node>();
node(int n_nodes,int level){
id=id0;
id0++;
this.n_nodes = n_nodes;
this.level = level;
states = new int[n_nodes];
visited = false;
fillLevels = new int[n_nodes];
}
void setfillLevels(int[] fillLevels){
this.fillLevels = fillLevels;
}
void setStates(int[] states){
this.states = states;
}
void setState(int state, int value){
states[state] = value;
}
int getState(int state){
return states[state];
}
void addLink(node linkedNode){
next.add(linkedNode);
}
boolean isVisited(){
return visited;
}
int getNumLinks(){
return next.size();
}
void printStates(){
System.out.println("States of node #"+id+" on level "+level+":");
int cntr = 0;
for(int i:states){
System.out.println(cntr+": "+i);
cntr++;
}
}
}
Don't add boolean flag to the node. It is not a stored property of the node, but a transient property of the algorithm that you are running on it.
Instead, keep a separate set of visited nodes, and pass it around in an additional parameter as you run your algorithm:
Set<Node> visited = new HashSet<>();
Instead of setting node.visited = true, use visited.add(node). Instead of checking if (node.visited) ... use if (visited.contains(node)) ...
This approach lets you reset all visited "flags" at once by calling visited.clear().
Related
I'm trying to make a custom data-structure, most similar to a list, for an assignment.
I have made the class Node:
class Node {
int data;
Node nextNode = null;
public Node(int data) {
this.data=data;
}
}
and the class DataStructure:
public class DataStructure {
private Node previousNode;
private Node StartingNode;
private boolean isEmpty = true;
public void AddNode(int data) {
if(isEmpty) {
isEmpty = false;
StartingNode = new Node(data);
previousNode = StartingNode;
}
else {
previousNode.nextNode = new Node(data);
previousNode = previousNode.nextNode;
}
}
private boolean isFirst = true;
int max = 0;
public int getMaxData(Node d) {
if(isFirst) {
isFirst = false;
max = d.data;
}
else {
if(d.data > max)
max = d.data;
if(d.nextNode != null)
getMaxData(d.nextNode);
}
return max;
}
}
When I try to run an example of the above the list is not created correctly (from what I can tell). I've been thinking that it maybe has something to do with the garbage collection but I believe the node objects are still active as they are referenced by the nextNode variable.
This is the main method that runs the example:
public static void main(String [] args) {
DataStructure list = new DataStructure();
list.AddNode(5);
list.AddNode(15);
list.AddNode(12);
list.AddNode(3);
System.out.println(list.getMaxData(list.StartingNode));
}
Expected result is the number 15 to be printed but I get the first node only(5).
I tried "debugging" by adding a System.out.writeln(d.data) at the start of getMaxData() and I only get 5 printed so I believe the other nodes aren't created.
This problem is this:
if(isFirst) {
isFirst = false;
max = d.data;
} else {...}
The if will always happen for the first element, and then you just return that value. You can do it with just the else clause:
public int getMaxData(Node d) {
if (d.data > max)
max = d.data;
if (d.nextNode != null)
return getMaxData(d.nextNode);
return max;
}
I am new to the concept of Linked list, and I am having a lot of trouble building this custom linked list for the first time.
I have two classes: CellPhone and CellList.
In CellPhone, I have 4 attributes: serialNum(long), brand(String), year(int), and price(double).
In CellList, I have:
an inner class called CellNode, which has two attributes: phone(CellPhone), and next(CellNode)
and two attributes head(CellNode) and size(int)
This is from my CellList class:
private CellNode head; // point first node in this list object
private int size; // current size of the list(how many nodes in the list)
public CellList() {
head = null;
size = 0;
}
public CellList(CellList c) { // is this a correct deep copying?
head = new CellNode(c.head);
size = c.getSize();
}
public int getSize() {
return size;
}
public void addToStart(CellPhone c) {
head = new CellNode(c, null); //head.getPhone() = c, head.getNextNode() = null.
size++;
}
I am not even sure if that addToStart method is correctly done, and now I need to add methods like insertAt(/deleteFrom)Index(CellPhone c, int index). I've done till here:
public void insertAtIndex(CellPhone c, int index) { //index is invalid when it's not 0<index<size-1
if(index<0 || index>size-1) {
throw new NoSuchElementException("index is invalid! System terminated.");
}
but I can't fully understand how this Node thing works, so I am stuck.
Here is the full code:
import java.util.NoSuchElementException;
public class CellList {
class CellNode {
private CellPhone phone;
private CellNode next;
public CellNode() {
phone = null;
next = null;
}
public CellNode(CellPhone c, CellNode n) {
phone = c;
next = n;
}
public CellNode(CellNode c) {
this(c.getPhone(), c.getNextNode());
}
public CellNode clone() {
CellNode c = new CellNode(phone, next);
return c;
}
public CellPhone getPhone() {
return phone;
}
public CellNode getNextNode() {
return next;
}
public void setPhone(CellPhone c) {
phone = c;
}
public void setNextNode(CellNode n) {
next = n;
}
}
private CellNode head; // point first node in this list object
private int size; // current size of the list(how many nodes in list)
public CellList() {
head = null;
size = 0;
}
public CellList(CellList c) {
head = new CellNode(c.head);
size = c.getSize();
}
public int getSize() {
return size;
}
public void addToStart(CellPhone c) {
head = new CellNode(c, null); //head.getPhone() = c, head.getNextNode() = null.
size++;
}
public void insertAtIndex(CellPhone c, int index) { //index is invalid when it's not 0<index<size-1
if(index<0 || index>size-1) {
throw new NoSuchElementException("index is invalid! System terminated.");
}
}
public void showContents() {
while(head.getNextNode() != null) {
System.out.println(head.getPhone()+"---->");
head = head.getNextNode();
}
}
}
If you want to insert a node at an index x you have to,
go to the node at index x-1, store the next value of node x-1 in a temp variable, put the node you want to insert in next property of x-1 node, and put the value in the temp variable in the next property of the node you want to insert.
Here is my class:
public class LinkedListSet implements Set {
private class Node //much easier as a private class; don't have to extend
{
private int data;
private Node next;
public Node (){}
public Node (int x)
{
data = x;
}
public int data()
{
return data;
}
public Node next()
{
return next;
}
}
private Node first;
private int Size;
private int whichList; //used to identify the particular LL object
Here is my interface:
public interface Set {
public boolean isEmpty();
public void makeEmpty();
public boolean isMember(int x);
public void add(int x);
public void remove(int y);
public void union(Set other, Set result);
public void intersection (Set other, Set result);
public void difference (Set other, Set result);
#Override
public String toString();
#Override
public boolean equals(Object other);
public void setList(int i); //i added this to use it as an identifier for each
//list element in the set array
public String getListId(); //these two extra methods make life easier
}
I have a method like this (in the LinkedListSet class):
public void difference (Set other, Set result)
{
if (other.isEmpty())
{
System.out.println("The set is empty before cast");
}
LinkedListSet othr = (LinkedListSet) other;
LinkedListSet res = (LinkedListSet) result;
if (this.isEmpty() || othr.isEmpty())
{
if (othr.isEmpty())
System.out.println("The set is empty after cast");
if (this.isEmpty())
System.out.println("This is also empty");
return;
}
differenceHelper(this.first, othr.first, res);
result = res;
}// the print statements were added for debugging
The problem is, in the above method I am unable to cast the Set Other into its linked list implementation. When I call this method in the main program, the parameter is actually of type linked list (so I don't get any errors obviously).
However, all the instance variables are null. The list is empty before and after I cast it (when it actually isn't empty). I know this is because the interface doesn't include any information about the Nodes, but is there anything I can do other than editing the interface to incorporate the Node?
I hope I've made this clear enough. Any help would be appreciated.
edit:
In the main program I created an array of Sets.
Set[] sets = new Set[7];
for (int i = 0; i< sets.length; i++) //initialize each element
{
sets[i] = new LinkedListSet();
}
each list has nodes with data values which are added on later on in the code...
then I call the difference method.
sets[0].difference(sets[1], sets[4])
sets[1].isEmpty returns true for some reason (even though it is not).
If I were to do something like:
System.out.println(sets[1].first.data()) I would have no problem whatsoever.
For some reason all the values become null when the parameters are passed to the difference method.
public boolean isEmpty()
{
return first == null;
}
I tested what you are trying to do with the following code and I see no problems:
import org.junit.Test;
public class RandomCastTest {
public interface Set {
boolean isEmpty();
void add(int x);
void difference(Set other, Set result);
#Override
String toString();
#Override
boolean equals(Object other);
}
public class LinkedListSet implements Set {
private class Node //much easier as a private class; don't have to extend
{
private int data;
private Node next;
public Node() {
}
public Node(int x) {
data = x;
}
public int data() {
return data;
}
public Node next() {
return next;
}
public void next(Node node) {
next = node;
}
}
private Node first;
private int Size;
private int whichList; //used to identify the particular LL object
#Override
public boolean isEmpty() {
return first == null;
}
#Override
public void add(int x) {
Node node = new Node(x);
if (first == null) {
first = node;
} else {
Node currentNode;
Node nextNode = first;
do {
currentNode = nextNode;
nextNode = currentNode.next();
} while (nextNode != null);
currentNode.next(node);
}
Size++;
}
#Override
public void difference(Set other, Set result) {
if (other.isEmpty()) {
System.out.println("The set is empty before cast");
}
LinkedListSet othr = (LinkedListSet) other;
LinkedListSet res = (LinkedListSet) result;
if (this.isEmpty() || othr.isEmpty()) {
if (othr.isEmpty())
System.out.println("The set is empty after cast");
if (this.isEmpty())
System.out.println("This is also empty");
return;
}
result = res;
}
}
#Test
public void test() {
Set[] sets = new Set[7];
for (int i = 0; i < sets.length; i++) {
sets[i] = new LinkedListSet();
}
for (int i = 0; i < 5; i++) {
sets[1].add(i);
}
for (int i = 5; i < 10; i++) {
sets[0].add(i);
}
sets[0].difference(sets[1], sets[4]);
// ... find difference
}
}
To simplify I removed unimplemented methods from the interface. Also added the add method implementation. Please see if it works for you.
I have this issue, after building my problem implementation, when running Optaplanner:
java.lang.IllegalStateException: The selectionList contains 2 times the same selection (Edge to: MinMax1 from: s4,s5,) and (Edge to: Sum2 from: s3,s4,).
at org.optaplanner.core.impl.heuristic.selector.common.decorator.WeightFactorySelectionSorter.sort(WeightFactorySelectionSorter.java:58)
at org.optaplanner.core.impl.heuristic.selector.entity.decorator.SortingEntitySelector.constructCache(SortingEntitySelector.java:44)
I've read the question in here but no object is null. I've modified the Entity class, which is Edge, to implement AbstractPersistable and before that I've tried to override the equals() method with same results:
#PlanningEntity(difficultyWeightFactoryClass = EdgeDifficultyWeightFactory.class)
public class Edge extends AbstractPersistable{
/**
*
*/
private ArrayList<Node> from;
private Node to;
private double burstTime;
private BufferSize size;
public Edge(){
from = new ArrayList<Node>();
BufferSize p = new BufferSize();
p.setSize(1);
this.size = p;
//new Random().nextInt(1000)+1;
this.burstTime += this.size.getSize();
}
public void setFrom(Node from){
this.from.add(from);
this.calculateEdgeBurstTime();
}
public ArrayList<Node> getFrom(){
return from;
}
public void setTo(Node to){
this.to = to;
}
public Node getTo(){
return to;
}
#PlanningVariable(valueRangeProviderRefs = {"bufferRange"})
public BufferSize getBufferSize(){
return size;
}
public void setBufferSize(BufferSize size){
this.size = size;
System.out.println("Size has been set: "+size);
this.calculateEdgeBurstTime();
}
public void calculateEdgeBurstTime(){
for(Node node : this.from){
this.burstTime+=this.size.getSize()*node.getNodeTime();
}
}
public double getEdgeTime(){
return burstTime;
}
#Override
public String toString(){
StringBuffer sb = new StringBuffer();
sb.append("Edge to: "+to.getID()+" from: ");
for(Node node : this.from){
sb.append(node.getID()+",");
}
return sb.toString();
}
#Override
public boolean equals(Object other){
if (other == null) return false;
if (other == this) return true;
if (!(other instanceof Edge))return false;
Edge otherMyClass = (Edge)other;
boolean checkFrom = true;
if(!(otherMyClass.getTo().getID().equals(this.getTo().getID()))) return false;
for(Node node : otherMyClass.getFrom()){
for(Node nd : this.getFrom()){
if(!(node.getID().equals(nd.getID()))){
checkFrom = false;
}
}
}
System.out.println("checked "+checkFrom+this.toString());
return checkFrom;
}
#Override
public int hashCode(){
HashCodeBuilder builder = new HashCodeBuilder();
builder.append(this.to.getID());
builder.append(this.from);
return builder.toHashCode();
}
}
To better clarify the problem, my EdgeDifficultyWeight class is implemented this way:
public class EdgeDifficultyWeightFactory implements SelectionSorterWeightFactory<SmartNodeGraph,Edge>{
public Comparable createSorterWeight(SmartNodeGraph graph, Edge edge) {
int difficulty = edge.getFrom().size(); //Edges with more dependencies are more difficult to plan
if(edge.getTo() instanceof NetworkNode){
difficulty += difficulty; //Edges to NetworkNodes are more difficult to plan.
}
for(Node node : edge.getFrom()){
if(node instanceof ProcessingNode){
difficulty +=2; //If precedes form ProcessingNode is more difficult to optimise than sensors directly
}else if(node instanceof SensorNode){
difficulty +=1;
}
}
return new EdgeDifficultyWeight(edge,difficulty);
}
public class EdgeDifficultyWeight implements Comparable<EdgeDifficultyWeight> {
private final Edge edge;
private final int difficulty;
public EdgeDifficultyWeight(Edge edge, int difficulty){
this.edge = edge;
this.difficulty = difficulty;
}
public int compareTo(EdgeDifficultyWeight arg) {
return new CompareToBuilder().append(arg.difficulty, this.difficulty).toComparison();
}
}
}
The planning problem is this: I have several separated Tree structures, the Root node of each tree has a ready time, which depends on all providers nodes. I want to make all root nodes time equal, each edge of the tree have a buffer which can be modified in size to change the time of the Father node. By changing the buffers in the several edges I want to make the times at the root level of all tree's equal.
Regarding the explanation, the Edges with more nodes (among other contraints), are more difficult to assign. Using the debugger, seem's that the problem is in this line:
Comparable difficultyWeight = selectionSorterWeightFactory.createSorterWeight(solution, selection);
The Comparable object is always the same.
Can anyone help on this?
Add .append(arg.edge.getId(), this.edge.getId()) in the EdgeDifficultyWeight to distinguish 2 weights that have different edges but the same difficulty.
public class EdgeDifficultyWeight implements Comparable<EdgeDifficultyWeight> {
private final Edge edge;
private final int difficulty;
public EdgeDifficultyWeight(Edge edge, int difficulty){
this.edge = edge;
this.difficulty = difficulty;
}
public int compareTo(EdgeDifficultyWeight arg) {
return new CompareToBuilder()
.append(arg.difficulty, this.difficulty)
.append(arg.edge.getId(), this.edge.getId())
.toComparison();
}
}
This is the initial class provided which we cannot modify
public class SLL {
public class Node {
private int data;
private Node next;
public Node() {
data = 0;
next = null;
}
public Node(int newData, Node linkValue) {
data = newData;
next = linkValue;
}
public int getData() {
return data;
}
public Node getLink() {
return next;
}
}// End of Node inner class
private Node head;
public SLL() {
head = null;
}
public void addToStart(int itemData) {
head = new Node(itemData, head);
}
public boolean contains(int item) {
return (find(item) != null);
}
/**
* Finds the first node containing the target item, and returns a reference
* to that node. If target is not in the list, null is returned.
*/
public Node find(int target) {
Node position = head;
int itemAtPosition;
while (position != null) {
itemAtPosition = position.data;
if (itemAtPosition == target) {
return position;
}
position = position.next;
}
return null; // target was not found
}
public void outputList() {
Node position = head;
while (position != null) {
System.out.print(position.data + " ");
position = position.next;
}
System.out.println();
}
}
And this is the Set class that we are supposed to finish to get the Tester to work and I keep getting a Null Pointer Exception with my add method, however, it is almost exactly as I have seen in other codes including our text book. Any insight would be very much appreciated as my instructor has pre-made powerpoints and doesn't explain anything or offer any advice to students seeking help.
public class Set {
private SLL[] hashArray; // DO NOT MODIFY THIS LINE
private int size = 10; // DO NOT MODIFY THIS LINE
// DO NOT MODIFY THIS METHOD
public Set() {
hashArray = new SLL[size];
}
// DO NOT MODIFY THIS METHOD
private int computeHash(int s) {
return s % size;
}
// COMPLETE BELOW
public void add(int x)
{
int hash = computeHash(x); // Get hash value
SLL list = hashArray[hash];
if (!list.contains(x))
{
// Only add the target if it's not already
// on the list.
list.addToStart(x);/*replaced hashArray[hash] with list*/
}
}
public void output( )
{
System.out.println("I will work on this later");
}
}
Finally, the Tester...
public class Tester{
// Have this method to display your name, instead.
static void displayName(){
System.out.println("Program written by Tony.\n");
}
// DO NOT MODIFY THE MAIN METHOD
public static void main(String[] args){
displayName();
Set set1 = new Set();
Set set2 = new Set();
set1.add(3);
set1.add(3);
set1.add(13);
set1.add(23);
set1.add(4);
set1.add(5);
set2.add(15);
set2.add(6);
set2.add(6);
System.out.println("Contents of set 'set1': ");
set1.output();
System.out.println("Contents of set 'set2': ");
set2.output();
System.out.println();
}
}
I don't want to give the answer directly as this is likely a homework assignment (correct me if I am wrong). Consider the very first time the add method is called on a newly constructed set. What values are in all indices of "hashArray" at this time and what does that mean for the local variable "list" in your add method?
This line isn't doing what you think it's doing.
hashArray = new SLL[size];
You need to actually create each SLL that will populate the array once the array itself is created.