Guys I do have problem while inserting a new node at the end of a list. insert at begening works fine but in insert at end it shows null pointer exception.
Please look in method inserAtEnd and suggest me how to deal with it:
package linkedlist;
class Node{
Node next;
Object data;
Node(Object x)
{
data=x;
}
}
class LL
{
Node first;
LL(Node f)
{
first =f;
}
void insertAtBeg(Object x)
{
Node n= new Node(x);
n.next=first;
first=n;
}
void insertAtEnd(Object x)
{
Node n= new Node(x);
Node k;
k=first;
while(k!=null)
{
k=k.next;
}
k.next=n;
}
void print()
{
Node p=first;
while(p!=null)
{
System.out.print(p.data+"-->");
p=p.next;
}
}
}
public class LinkedList {
public static void main(String[] args) {
LL l = new LL(null);
l.insertAtBeg("Raj");
l.insertAtBeg("Am ");
l.insertAtBeg("I ");
l.insertAtBeg("100 ");
l.insertAtEnd("Hello");
l.print();
System.out.println("returned in main");
}
}
The problem is your loop is going till k is null, you want to go till k.next is equal to null. You could also solve it by having a variable for the last node(This is what is almost always done). The code I've provided fixes the problem without adding any new variables however:
void insertAtEnd(Object x) {
Node n= new Node(x);
Node k;
k=first;
while(k.next != null) {
k=k.next;
}
k.next=n;
}
Related
For academic purpose, I'm trying to implement a custom chain move in OptaPlanner.
My aim is to purposefully move one link from a chain to another to speed up the resolution of the problem.
Start
1. A -> B -> C
2. D -> E -> F
Move E from D to A
1. A -> E -> B -> C
2. D -> F
Undo move
A -> B -> C
D -> E -> F
I have read both the documentation and several posts on stackoverflow (mainly this, this, this and this) but I keep getting java.lang.IllegalStateException error.
I am surely missing some concept to solve the problem.
What am I doing wrong?
Thanks
The error
2022-08-30 18:18:24,429 (OptaPool-10-MoveThread-2) Move thread (1) exception that will be propagated to the solver thread.: java.lang.IllegalStateException: The entity (eu.gurgolo.domain.Student#1de) has a variable (previousStandStill) with value (eu.gurgolo.domain.Student#1fb) which has a sourceVariableName variable (nextStudent) with a value (eu.gurgolo.domain.Student#1f8) which is not null.
Verify the consistency of your input problem for that sourceVariableName variable.
at org.optaplanner.core.impl.domain.variable.inverserelation.SingletonInverseVariableListener.insert(SingletonInverseVariableListener.java:74)
at org.optaplanner.core.impl.domain.variable.inverserelation.SingletonInverseVariableListener.afterVariableChanged(SingletonInverseVariableListener.java:53)
The code
CustomMoveFactory
public class CustomMoveFactory implements MoveListFactory<MySolution> {
#Override
public List<CustomMove> createMoveList(MySolution solution) {
List<CustomMove> customMoves = new ArrayList<>();
List<Student> students = solution.getStudents();
for(Student s1 : students) {
for(Student s2 : students) {
//Here some logic to add
customMoves.add(new CustomMove(s1, s2));
}
}
return customMoves;
}
}
CustomMove
public class CustomMove extends AbstractMove<MySolution> {
private Student newStandStill;
private Student student;
public CustomMove(Student s1, Student s2) {
this.newStandStill = s1;
this.student = s2;
}
#Override
public boolean isMoveDoable(ScoreDirector<MySolution> scoreDirector) {
return !Objects.equals(newStandStill, student.getPreviousStandStill());
}
#Override
protected AbstractMove<MySolution> createUndoMove(ScoreDirector<MySolution> scoreDirector) {
return new CustomMove(student, newStandStill);
}
#Override
protected void doMoveOnGenuineVariables(ScoreDirector<MySolution> scoreDirector) {
Student nextStudent = student.getNextStudent();
Student nextStandStill = newStandStill.getNextStudent();
// 1. fix the chain where the student will be removed
if(nextStudent != null) {
scoreDirector.beforeVariableChanged(nextStudent, "previousStandStill");
nextStudent.setPreviousStandStill(student.getPreviousStandStill());
scoreDirector.afterVariableChanged(nextStudent, "previousStandStill");
}
// 2. fix the chain where the student will be added
if(nextStandStill != null) {
scoreDirector.beforeVariableChanged(nextStandStill, "previousStandStill");
nextStandStill.setPreviousStandStill(student.getPreviousStandStill());
scoreDirector.afterVariableChanged(nextStandStill, "previousStandStill");
}
// 3. move the student in the chain
scoreDirector.beforeVariableChanged(student, "previousStandStill");
student.setPreviousStandStill(newStandStill);
scoreDirector.afterVariableChanged(student, "previousStandStill");
}
#Override
public CustomMove rebase(ScoreDirector<MySolution> destinationScoreDirector) {
return new CustomMove(destinationScoreDirector.lookUpWorkingObject(newStandStill),
destinationScoreDirector.lookUpWorkingObject(student));
}
#Override
public Collection<? extends Object> getPlanningEntities() {
return Collections.singletonList(newStandStill);
}
#Override
public Collection<? extends Object> getPlanningValues() {
return Collections.singletonList(student);
}
#Override
public String getSimpleMoveTypeDescription() {
return getClass().getSimpleName() + "(" + Student.class.getSimpleName() + ".student)";
}
#Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final CustomMove other = (CustomMove) o;
return Objects.equals(newStandStill, other.newStandStill) &&
Objects.equals(student, other.student);
}
#Override
public int hashCode() {
return Objects.hash(newStandStill, student);
}
#Override
public String toString() {
long profId = newStandStill.getProf().getId();
long nextProfId = student.getProf().getId();
return newStandStill.getStudentId() + " {" + profId + " -> " + nextProfId + "}";
}
}
I have evaluated your CustomMove implementation on paper and tried to move E from D to A as proposed in your question.
I think you have a bug in step 2. Your code:
// 2. fix the chain where the student will be added
if(nextStandStill != null) {
scoreDirector.beforeVariableChanged(nextStandStill, "previousStandStill");
nextStandStill.setPreviousStandStill(student.getPreviousStandStill());
scoreDirector.afterVariableChanged(nextStandStill, "previousStandStill");
}
Fixed version of the above:
// 2. fix the chain where the student will be added
if(nextStandStill != null) {
scoreDirector.beforeVariableChanged(nextStandStill, "previousStandStill");
nextStandStill.setPreviousStandStill(student);
scoreDirector.afterVariableChanged(nextStandStill, "previousStandStill");
}
In "move E from D to A", A is newStandstill and so B is nextStandstill. E (the moved student) should become B's new previousStandstill. I hope that illuminates the proposed fix above.
I would like to repeatedly enter a number that is added to a linked list.
But there's an error in the code at line x = new Node():
No enclosing instance of type Main is accessible. Must qualify the allocation with an enclosing instance of type Main (e.g. x.new A() where x is an instance of Main).
Is there a way to fix my code?
static Node head;
static Node p;
static Node q;
static Node x;
class Node {
int data;
Node next;
public Node link;
// Constructor to create a new node
// Next is by default initialized
// as null
Node(int d) {
data = d;
next = null;
}
public Node() {
// TODO Auto-generated constructor stub
}
}
Two issues:
class Node should either be declared as static, or be moved to a separate file.
p = x should happen outside the else block, since it should get this value also when the if condition was true:
if(head == null) {
head = x;
} else {
p.link = x;
}
p = x;
Some remarks:
If you really want to use the Node constructor without arguments, then it is better to define explicitly what the new Node's properties should be:
public Node() {
data = 0;
next = null;
}
However, it would be better to not have this constructor signature at all, and only construct the object using the data as argument:
if(num != -999){
x = new Node(num);
...and now you don't need to do any of this any more:
x.data = num;
x.link = null;
The inner Node class is not static, meaning it belongs to a specific instance of the enclosing Main class. Since it doesn't refer to any instance methods this seems like it was not done intentionally. Make the class itself static (i.e., static class Node {) and you should be fine.
First, the class Node cannot be referenced from a static context. To fix this, make it static or move it to its own file. Second, the null pointer exception happens since you don't assign p in the special case where the list is empty.
Overall, I suggest that you clean up your class and use a more structured approach. Rename p to last to make it clear that this is a reference to the last element of the list. Move the functionality to add a node into its own method to make the code more readable. Use next in the Node class to point to the next node instead of link. Create an instance of the class where your head and last reference is defined and make them private. Use break inside the loop to only define the magic number (-999) once and exit the loop when it is entered.
The whole class could look like this:
public class CustomLinkedList {
private Node head = null;
private Node last = null;
static class Node {
int data;
Node next = null;
}
public void add(int num) {
Node x = new Node();
x.data = num;
if (this.head == null) {
this.head = x;
} else {
this.last.next = x;
}
this.last = x;
}
public static void main(String[] args) {
CustomLinkedList list = new CustomLinkedList();
int count = 0;
do {
try {
BufferedReader dataIn = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter number " + (++count) + ": ");
String strNum = dataIn.readLine();
int num = Integer.parseInt(strNum);
if (num != -999) {
list.add(num);
} else {
break; // exit loop
}
} catch (IOException e) {
System.out.print(e.getMessage());
}
} while (true);
}
}
I have a situation where the application developers and the framework provider are not the people. As a framework provider, I would like to be able to hand the developers what looks like a single Filter, but is in fact a chain of standard Filters (such as authentication, setting up invocation context, metrics, ++).
I don't seem to find this functionality in the standard library, but maybe there is an extension with it.
Instead of waiting for an answer, I went ahead with my own implementation and sharing here if some needs this.
/**
* Composes an array of Restlet Filters into a single Filter.
*/
public class ComposingFilter extends Filter
{
private final Filter first;
private final Filter last;
public ComposingFilter( Filter... composedOf )
{
Objects.requireNonNull( composedOf );
if( composedOf.length == 0 )
{
throw new IllegalArgumentException( "Filter chain can't be empty." );
}
first = composedOf[ 0 ];
Filter prev = first;
for( int i = 1; i < composedOf.length; i++ )
{
Filter next = composedOf[ i ];
prev.setNext( next );
prev = next;
}
last = composedOf[ composedOf.length - 1 ];
}
#Override
protected int doHandle( Request request, Response response )
{
if( first != null )
{
first.handle( request, response );
Response.setCurrent( response );
if( getContext() != null )
{
Context.setCurrent( getContext() );
}
}
else
{
response.setStatus( Status.SERVER_ERROR_INTERNAL );
getLogger().warning( "The filter " + getName() + " was executed without a next Restlet attached to it." );
}
return CONTINUE;
}
#Override
public synchronized void start()
throws Exception
{
if( isStopped() )
{
first.start();
super.start();
}
}
#Override
public synchronized void stop()
throws Exception
{
if( isStarted() )
{
super.stop();
first.stop();
}
}
#Override
public Restlet getNext()
{
return last.getNext();
}
#Override
public void setNext( Class<? extends ServerResource> targetClass )
{
last.setNext( targetClass );
}
#Override
public void setNext( Restlet next )
{
last.setNext( next );
}
}
NOTE: Not tested yet.
For example if I have 3 classes,
class A {
public void doA() {
/* do something */
}
}
class B {
public void doB() {
A a = new A();
a.doA();
}
}
class MyClass {
public static void main(String args[]) {
B b = new B();
b.doB();
}
}
Now I want to define a point cut for flow doB() -> doA(), like if doB() calls doA() grab parameters from class A and class B and do something in aspect method. Could someone help me out.
Let me slightly extend your sample code in order to make you understand what my solution does and what it cannot do:
class A {
public void doA() {}
}
class B {
public void doB() {
new A().doA();
new C().doC();
}
}
class C {
public void doC() {
new A().doA();
}
}
class MyClass {
public static void main(String args[]) {
new A().doA(); // should not be captured
new B().doB(); // should be captured
}
}
As you can see, there is a new class C now and we have three control flows now:
MyClass.main -> A.doA
MyClass.main -> B.doB -> A.doA
MyClass.main -> B.doB -> C.doC -> A.doA
You want to exclude #1 and capture #2, but what about #3? In this case a.doA is called indirectly from B.doB via C.doC. My solution also captures this indirect case. If this is fine for you or it does not happen in your code base, you can use my solution. Otherwise things would get a little more complicated and you would need to inspect the call stack. Tell me if you need to exclude #2, and I will extend my answer, but the solution will not look as simple as this one, I can promise.
Now here is the aspect:
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
#Aspect
public class ControlFlowInterceptor {
#Before("execution(void A.doA()) && target(a) && cflow(execution(void B.doB()) && target(b))")
public void advice(JoinPoint thisJoinPoint, A a, B b) {
System.out.println(thisJoinPoint);
System.out.println(" " + a);
System.out.println(" " + b);
}
}
The console output looks like this:
execution(void A.doA())
A#7b19f779
B#65c66812
execution(void A.doA())
A#4df2868
B#65c66812
Please note that we have the same B object ID in both outputs, but because C.doC creates an new A object, we have two different A object IDs.
I've been dealing with a score corruption error for few days with no apparent reason. The error appears only on FULL_ASSERT mode and it is not related to the constraints defined on the drools file.
Following is the error :
014-07-02 14:51:49,037 [SwingWorker-pool-1-thread-4] TRACE Move index (0), score (-4/-2450/-240/-170), accepted (false) for move (EMP4#START => EMP2).
java.util.concurrent.ExecutionException: java.lang.IllegalStateException: Score corruption: the workingScore (-3/-1890/-640/-170) is not the uncorruptedScore (-3/-1890/-640/-250) after completedAction (EMP3#EMP4 => EMP4):
The corrupted scoreDirector has 1 ConstraintMatch(s) which are in excess (and should not be there):
com.abcdl.be.solver/MinimizeTotalTime/level3/[org.drools.core.reteoo.InitialFactImpl#4dde85f0]=-170
The corrupted scoreDirector has 1 ConstraintMatch(s) which are missing:
com.abcdl.be.solver/MinimizeTotalTime/level3/[org.drools.core.reteoo.InitialFactImpl#4dde85f0]=-250
Check your score constraints.
The error appears every time after several steps are completed for no apparent reason.
I'm developing a software to schedule several tasks considering time and resources constraints.
The whole process is represented by a directed tree diagram such that the nodes of the graph represent the tasks and the edges, the dependencies between the tasks.
To do this, the planner change the parent node of each node until he finds the best solution.
The node is the planning entity and its parent the planning variable :
#PlanningEntity(difficultyComparatorClass = NodeDifficultyComparator.class)
public class Node extends ProcessChain {
private Node parent; // Planning variable: changes during planning, between score calculations.
private String delay; // Used to display the delay for nodes of type "And"
private int id; // Used as an identifier for each node. Different nodes cannot have the same id
public Node(String name, String type, int time, int resources, String md, int id)
{
super(name, "", time, resources, type, md);
this.id = id;
}
public Node()
{
super();
this.delay = "";
}
public String getDelay() {
return delay;
}
public void setDelay(String delay) {
this.delay = delay;
}
#PlanningVariable(valueRangeProviderRefs = {"parentRange"}, strengthComparatorClass = ParentStrengthComparator.class, nullable = false)
public Node getParent() {
return parent;
}
public void setParent(Node parent) {
this.parent = parent;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
/*public String toString()
{
if(this.type.equals("AND"))
return delay;
if(!this.md.isEmpty())
return Tools.excerpt(name+" : "+this.md);
return Tools.excerpt(name);
}*/
public String toString()
{
if(parent!= null)
return Tools.excerpt(name) +"#"+parent;
else
return Tools.excerpt(name);
}
public boolean equals( Object o ) {
if (this == o) {
return true;
} else if (o instanceof Node) {
Node other = (Node) o;
return new EqualsBuilder()
.append(name, other.name)
.append(id, other.id)
.isEquals();
} else {
return false;
}
}
public int hashCode() {
return new HashCodeBuilder()
.append(name)
.append(id)
.toHashCode();
}
// ************************************************************************
// Complex methods
// ************************************************************************
public int getStartTime()
{
try{
return Graph.getInstance().getNode2times().get(this).getFirst();
}
catch(NullPointerException e)
{
System.out.println("getStartTime() is null for " + this);
}
return 10;
}
public int getEndTime()
{ try{
return Graph.getInstance().getNode2times().get(this).getSecond();
}
catch(NullPointerException e)
{
System.out.println("getEndTime() is null for " + this);
}
return 10;
}
#ValueRangeProvider(id = "parentRange")
public Collection<Node> getPossibleParents()
{
Collection<Node> nodes = new ArrayList<Node>(Graph.getInstance().getNodes());
nodes.remove(this); // We remove this node from the list
if(Graph.getInstance().getParentsCount(this) > 0)
nodes.remove(Graph.getInstance().getParents(this)); // We remove its parents from the list
if(Graph.getInstance().getChildCount(this) > 0)
nodes.remove(Graph.getInstance().getChildren(this)); // We remove its children from the list
if(!nodes.contains(Graph.getInstance().getNt()))
nodes.add(Graph.getInstance().getNt());
return nodes;
}
/**
* The normal methods {#link #equals(Object)} and {#link #hashCode()} cannot be used because the rule engine already
* requires them (for performance in their original state).
* #see #solutionHashCode()
*/
public boolean solutionEquals(Object o) {
if (this == o) {
return true;
} else if (o instanceof Node) {
Node other = (Node) o;
return new EqualsBuilder()
.append(name, other.name)
.append(id, other.id)
.isEquals();
} else {
return false;
}
}
/**
* The normal methods {#link #equals(Object)} and {#link #hashCode()} cannot be used because the rule engine already
* requires them (for performance in their original state).
* #see #solutionEquals(Object)
*/
public int solutionHashCode() {
return new HashCodeBuilder()
.append(name)
.append(id)
.toHashCode();
}
}
Each move must update the graph by removing the previous edge and adding the new edge from the node to its parent, so i'm using a custom change move :
public class ParentChangeMove implements Move{
private Node node;
private Node parent;
private Graph g = Graph.getInstance();
public ParentChangeMove(Node node, Node parent) {
this.node = node;
this.parent = parent;
}
public boolean isMoveDoable(ScoreDirector scoreDirector) {
List<Dependency> dep = new ArrayList<Dependency>(g.getDependencies());
dep.add(new Dependency(parent.getName(), node.getName()));
return !ObjectUtils.equals(node.getParent(), parent) && !g.detectCycles(dep) && !g.getParents(node).contains(parent);
}
public Move createUndoMove(ScoreDirector scoreDirector) {
return new ParentChangeMove(node, node.getParent());
}
public void doMove(ScoreDirector scoreDirector) {
scoreDirector.beforeVariableChanged(node, "parent"); // before changes are made
//The previous edge is removed from the graph
if(node.getParent() != null)
{
Dependency d = new Dependency(node.getParent().getName(), node.getName());
g.removeEdge(g.getDep2link().get(d));
g.getDependencies().remove(d);
g.getDep2link().remove(d);
}
node.setParent(parent); // the move
//The new edge is added on the graph (parent ==> node)
Link link = new Link();
Dependency d = new Dependency(parent.getName(), node.getName());
g.addEdge(link, parent, node);
g.getDependencies().add(d);
g.getDep2link().put(d, link);
g.setStepTimes();
scoreDirector.afterVariableChanged(node, "parent"); // after changes are made
}
public Collection<? extends Object> getPlanningEntities() {
return Collections.singletonList(node);
}
public Collection<? extends Object> getPlanningValues() {
return Collections.singletonList(parent);
}
public boolean equals(Object o) {
if (this == o) {
return true;
} else if (o instanceof ParentChangeMove) {
ParentChangeMove other = (ParentChangeMove) o;
return new EqualsBuilder()
.append(node, other.node)
.append(parent, other.parent)
.isEquals();
} else {
return false;
}
}
public int hashCode() {
return new HashCodeBuilder()
.append(node)
.append(parent)
.toHashCode();
}
public String toString() {
return node + " => " + parent;
}
}
The graph does define multiple methods that are used by the constraints to calculate the score for each solution like the following :
rule "MinimizeTotalTime" // Minimize the total process time
when
eval(true)
then
scoreHolder.addSoftConstraintMatch(kcontext, 1, -Graph.getInstance().totalTime());
end
On other environment modes, the error does not appear but the best score calculated is not equal to the actual score.
I don't have any clue as to where the problem could come from. Note that i already checked all my equals and hashcode methods.
EDIT : Following ge0ffrey's proposition, I used collect CE in "MinimizeTotalTime" rule to check if the error comes again :
rule "MinimizeTotalTime" // Minimize the total process time
when
ArrayList() from collect(Node())
then
scoreHolder.addSoftConstraintMatch(kcontext, 0, -Graph.getInstance().totalTime());
end
At this point, no error appears and everything seems ok. But when I use "terminate early", I get the following error :
java.util.concurrent.ExecutionException: java.lang.IllegalStateException: Score corruption: the solution's score (-9133) is not the uncorruptedScore (-9765).
Also, I have a rule that doesn't use any method from the Graph class and seems to respect the incremental score calculation but returns another score corruption error.
The purpose of the rule is to make sure that we don't use more resources that available:
rule "addMarks" //insert a Mark each time a task starts or ends
when
Node($startTime : getStartTime(), $endTime : getEndTime())
then
insertLogical(new Mark($startTime));
insertLogical(new Mark($endTime));
end
rule "resourcesLimit" // At any time, The number of resources used must not exceed the total number of resources available
when
Mark($startTime: time)
Mark(time > $startTime, $endTime : time)
not Mark(time > $startTime, time < $endTime)
$total : Number(intValue > Global.getInstance().getAvailableResources() ) from
accumulate(Node(getEndTime() >=$endTime, getStartTime()<= $startTime, $res : resources), sum($res))
then
scoreHolder.addHardConstraintMatch(kcontext, 0, (Global.getInstance().getAvailableResources() - $total.intValue()) * ($endTime - $startTime) );
end
Following is the error :
java.util.concurrent.ExecutionException: java.lang.IllegalStateException: Score corruption: the workingScore (-193595) is not the uncorruptedScore (-193574) after completedAction (DWL_CM_XX_101#DWL_PA_XX_180 => DWL_PA_XX_180):
The corrupted scoreDirector has 4 ConstraintMatch(s) which are in excess (and should not be there):
com.abcdl.be.solver/resourcesLimit/level0/[43.0, 2012, 1891]=-2783
com.abcdl.be.solver/resourcesLimit/level0/[45.0, 1870, 1805]=-1625
com.abcdl.be.solver/resourcesLimit/level0/[46.0, 1805, 1774]=-806
com.abcdl.be.solver/resourcesLimit/level0/[45.0, 1774, 1762]=-300
The corrupted scoreDirector has 3 ConstraintMatch(s) which are missing:
com.abcdl.be.solver/resourcesLimit/level0/[43.0, 2012, 1901]=-2553
com.abcdl.be.solver/resourcesLimit/level0/[45.0, 1870, 1762]=-2700
com.abcdl.be.solver/resourcesLimit/level0/[44.0, 1901, 1891]=-240
Check your score constraints.
A score rule that has a LHS of just "eval(true)" is inherently broken. Either that constraint is always broken, for the exact same weight, and there really is no reason to evaluate it. Or it is sometimes broken (or always broken but for different weights) and then the rule needs to refire accordingly.
Problem: the return value of Graph.getInstance().totalTime() changes as the planning variables change value. But Drools just looks at the LHS as planning variables change and it sees that nothing in the LHS has changed so there's no need to re-evaluate that score rule, when the planning variables change. Note: this is called incremental score calculation (see docs), which is a huge performance speedup.
Subproblem: The method Graph.getInstance().totalTime() is inherently not incremental.
Fix: translate that totalTime() function into a DRL function based on Node selections. You 'll probably need to use accumulate. If that's too hard (because it's a complex calculation of the critical path or so), try it anyway (for incremental score calculation's sake) or try a LHS that does a collect over all Nodes (which is like eval(true) but it will be refired every time.