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();
}
}
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.
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().
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'm writing a program in Java to solve puzzles from this game:
http://universefactory.net/0/
I've modeled the problem as follows
Node Class:
package model;
import java.util.ArrayList;
public class Node {
private final int nodeId;
private ArrayList<Edge> edges;
ArrayList<Edge> getEdges() {
return edges;
}
public int getNodeId() {
return nodeId;
}
public Node(int id) {
nodeId = id;
edges = new ArrayList<Edge>();
}
#SuppressWarnings("unused")
private Node() {
nodeId = -1;
}
private void addEdge(Edge toBeAdded) {
if (toBeAdded != null)
edges.add(toBeAdded);
}
public void addEdgeTo(Node to, Star star) {
if(this.equals(to))
return;
if (to != null) {
Edge edge = new Edge(to, star);
addEdge(edge);
}
}
public void addEdgeTo(Node to) {
if(this.equals(to))
return;
if (to != null) {
Edge edge = new Edge(to);
addEdge(edge);
}
}
public Edge getEdge(Node to)
{
Node edgeDestination;
for(Edge edgeIterator: edges)
{
edgeDestination = edgeIterator.goesTo();
if(edgeDestination.equals(to))
return edgeIterator;
}
return null;
}
public Edge popEdge(Node to)
{
Node edgeDestination;
for(Edge edgeIterator: edges)
{
edgeDestination = edgeIterator.goesTo();
if(edgeDestination.equals(to))
{
edges.remove(edgeIterator);
return edgeIterator;
}
}
return null;
}
#Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Node other = (Node) obj;
if (nodeId != other.nodeId)
return false;
return true;
}
}
Edge class:
package model;
public class Edge {
private final Star star;
private final Node to;
Edge(Node nodeTo) {
star = null;
to = nodeTo;
}
Edge(Node nodeTo, Star star) {
this.star = star;
to = nodeTo;
}
public void consumeEdge() {
if (star != null) {
star.die();
}
}
public boolean consumable() {
if (star == null)
return false;
return star.isAlive();
}
public Node goesTo() {
return to;
}
}
Star Class
package model;
public class Star {
boolean dead = false;
public void die() {
dead = true;
}
public boolean isAlive()
{
return !dead;
}
}
and Graph Class:
package model;
import java.util.ArrayList;
public class Graph {
private ArrayList<Node> nodes = null;
private ArrayList<Star> stars = null;
private Node startNode = null;
private final int startNodeID = 0;
public Graph(ArrayList<Node> nodeArr, ArrayList<Star> starArr) {
// TODO Auto-generated constructor stub
nodes = nodeArr;
stars = starArr;
setStartNode();
}
private void setStartNode() {
for (Node nodeIterator : nodes) {
if (nodeIterator.getNodeId() == startNodeID) {
startNode = nodeIterator;
break;
}
}
}
public Graph(Graph other) {
nodes = new ArrayList<Node>();
stars = new ArrayList<Star>();
nodes.addAll(other.getNodes());
stars.addAll(other.getStars());
setStartNode();
}
public ArrayList<Node> solve() {
final int numberOfStars = stars.size();
ArrayList<Node> solution = new ArrayList<Node>();
solution.add(startNode);
recursiveSolver(startNode, numberOfStars, solution);
return solution;
}
private boolean recursiveSolver(Node currentNode, int numberOfStars,
ArrayList<Node> solutionPointer) {
if (numberOfStars == 0)
return true;
for(Edge edgeIterator: currentNode.getEdges())
{
Node nextNode = edgeIterator.goesTo();
Graph deepCopy = new Graph(this);
currentNode = deepCopy.getNode(currentNode);
nextNode = deepCopy.getNode(nextNode);
//deepCopy.traverse(currentNode, nextNode);
//deepCopy.recursiveSolver(.....);
//Not sure how to finish this <---------------------------PROBLEM AREA
}
}
private Node getNode(Node currentNode) {
return getNode(currentNode.getNodeId());
}
private ArrayList<Node> getNodes() {
return nodes;
}
private ArrayList<Star> getStars() {
return stars;
}
public void linkNodesWith(int fromNodeID, int toNodeID, Star star) {
final Node from = getNode(fromNodeID);
final Node to = getNode(toNodeID);
if (from != null && to != null)
linkNodesWith(from, to, star);
}
private void linkNodesWith(Node nodeFrom, Node nodeTo, Star star) {
nodeFrom.addEdgeTo(nodeTo, star);
nodeTo.addEdgeTo(nodeFrom, star);
}
public Node getNode(int nodeId) {
for (Node iteratorNode : nodes) {
if (iteratorNode.getNodeId() == nodeId)
return iteratorNode;
}
return null;
}
public void removeNode(Node nodeToRemove) {
nodes.remove(nodeToRemove);
for (Node nodeIterator : nodes) {
nodeIterator.popEdge(nodeToRemove);
}
}
public void removeNode(int nodeIdToRemove) {
Node nodeToRemove = getNode(nodeIdToRemove);
removeNode(nodeToRemove);
}
//Last three functions are used to create a specific graph to solve
public void populateEdges() {
for (Node nodeFromIterator : nodes) {
for (Node nodeToIterator : nodes) {
nodeFromIterator.addEdgeTo(nodeToIterator);
}
}
}
public void replaceEdge(int nodeFromID, int nodeToID, Star star) {
Node nodeFrom = getNode(nodeFromID);
Node nodeTo = getNode(nodeToID);
unlinkNodes(nodeFrom, nodeTo);
linkNodesWith(nodeFrom, nodeTo, star);
}
private void unlinkNodes(Node nodeFrom, Node nodeTo) {
nodeFrom.popEdge(nodeTo);
nodeTo.popEdge(nodeFrom);
}
}
I can't figure out a way to solve this without making deep copies of the graph every time a node is deleted/traversed, and even then am not sure as to how I can save the path in an array-list. Is there a better way to model the problem that would simplify the solution?
universefactory.net/0 : the game im trying to write a solution for.
You can do this with a recursive backtracking solution and an immutable graph, for example
1) Construct a graph of all nodes + all edges and a list of stars (each star containing a list of all edges it is on, OR each edge containing a list of references to stars (not copies) that are on its path. Whatever makes more sense to you)
2) Write a recursive method. Its parameters will be:
the graph + list of stars (immutable)
the list of nodes taken so far, in order
the list of edges taken so far, in order
the list of stars left to take
It should do the following:
2a) If it has possible moves to take (edges from the node it's on that aren't in the list of edges taken so far), recursively branch and try each of those next moves, by calling itself with
the graph + list of stars (immutable)
a copy of the list of edges taken so far, in order, adding the new edge taken by this mode
a copy of the list of nodes taken so far, in order, adding the new node taken by this mode
a copy of the list of stars left to take, subtracting new stars taken by this move
2b) If it has no possible modes to take, check if we have taken all stars. If we have, then this is the solution (print out the list of edges taken)