Optaplanner doesn't see my planning variable - optaplanner

So I have a class Cycle:
#PlanningEntity
public class Cycle {
private Integer START = 29;
private Integer END = 42;
private final int SUSTAIN_START = 29;
private final int SUSTAIN_END = 72;
#PlanningVariable(valueRangeProviderRefs = { "startRange" } )
public Integer getStartIndex() {
System.out.println("DEBUG: getStartIndex");
return START;
}
public void setStartIndex(Integer i) {
System.out.println("DEBUG: setStartIndex");
START = i;
END = i+13;
}
#ValueRangeProvider(id = "startRange")
public List<Integer> getStartIndexes () {
ArrayList<Integer> startRange = new ArrayList<Integer>();
for(int i = SUSTAIN_START; i < SUSTAIN_END; i++) {
startRange.add(i);
}
return startRange;
}
}
and Optplanner doesn't ever call any of these methods, and I have no clue why. I've tried adding a "#ProblemFactCollectionProperty" annotatation on the getStartIndexes method, but I read in the docs that that annotation should only be used within a PlanningSolution.
I've also tried using scanAnnotatedClasses and explicitly specifying the entityClass in my solver config and neither seemed to make a difference.
Why can't Optaplanner see my variable and why doesn't Optaplanner change it?
More Info: I'm using Optaplanner version 7.30.0.Final and I have another planning entity with two planning variables that are seen and changed by Optaplanner.

The problem, per #yurloc's comment, was that I was missing the PlanningEntityCollectionProperty for Cycles in my PlanningSolution class. Thanks for the help!

Related

In Linked list how to produce value

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);
}
}

Optaplanner shadow variable with more than one source

Optaplanner allows for a shadow variable to have more than one source (sources = {}) but only one variableListsnerClass. In my implementation i have a planning entity with shadow variables that should be able to change by two listsners, but this is not supported it seems or am i wrong? is there a way to have two listeners affect one shadow variable?
I have the following planning entities: PlannerActivity, PlannerTask and PlannerTaskResourceAllocation.
Any change on a PlannerActivity startIndex (genuine var) is listened to by the ActivityStartIndexVariableListener which moves the startindex (shadow var) and endIndex (shadow var) on all tasks belonging to that activity. this works fine
In addition to that, any change on a PlannerTaskResourceAllocation resource (geniune var), is listened to by TaskResourceVariableListener, and when the resource is a product, also updates the ohHandAmounts for that product, this also works fine.
The problem i have is that i need to add logic that when a resource is changed on a PlannerTaskResourceAllocation and that resource is an equipment, i need to possibly recalculate the task duration is the new equipment might be slower or faster than what was assigned before.
so what i need here is that the PlannerActivity and PlannerTask startIndex and endIndex should be able to be changed by the TaskResourceVariableListener as well, but they are already listed to by the
ActivityStartIndexVariableListener, and there's no way for me to specify two listeners for one shadow variable.
PlannerTask:
public class PlannerTask extends InventoryTransactionCause {
private static final long serialVersionUID = 1L;
#Getter
#Setter
private Activity activity;
#Getter
#Setter
private Integer indexInActivity;
// shadow variable
private Integer startIndex;
#Getter
#Setter
private double startOffset;
// shadow variable
private Integer length;
// shadow variable
private Integer endIndex;
#Getter
#Setter
private double endOffset;
#Getter
#Setter
private Integer originalStartIndex;
#Getter
#Setter
private Integer originalEndIndex;
#Getter
#Setter
private String state;
// getters and setters for shadow variables
// this is one of the shadow variables that i need affected by two
// listeners, one is the ActivityStartIndexVariableListener and the
// other is TaskResourceVariableListener
#CustomShadowVariable(variableListenerClass = ActivityStartIndexVariableListener.class,
sources = { #CustomShadowVariable.Source(entityClass = PlannerActivity.class, variableName = "endIndex"),
#CustomShadowVariable.Source(entityClass = PlannerTaskResourceAllocation.class,
variableName = "resource") })
public Integer getStartIndex() {
return this.startIndex;
}
public void setStartIndex(Integer startIndex) {
this.startIndex = startIndex;
}
#CustomShadowVariable(variableListenerClass = ActivityStartIndexVariableListener.class,
sources = { #CustomShadowVariable.Source(entityClass = PlannerActivity.class, variableName = "endIndex"),
#CustomShadowVariable.Source(entityClass = PlannerTaskResourceAllocation.class,
variableName = "resource") })
public Integer getEndIndex() {
return this.endIndex;
}
public void setEndIndex(Integer endIndex) {
this.endIndex = endIndex;
}
#CustomShadowVariable(variableListenerClass = TaskResourceVariableListener.class,
sources = { #CustomShadowVariable.Source(entityClass = PlannerTaskResourceAllocation.class,
variableName = "resource") })
public Integer getLength() {
return this.length;
}
public void setLength(Integer length) {
this.length = length;
}
}
This is supported with the variableListenerRef attribute: the first shadow variable has a normal shadow variable annotation and the second shadow variable points to the first shadow variable with #CustomShadowVariable(variableListenerRef = #PlanningVariableReference(variableName = "firstShadow"))
For example, 1 variable listener that changes 2 shadow variables that is based on 2 genuine variables:
#PlanningVariable(valueRangeProviderRefs = "valueRange")
public TestdataValue getPrimaryValue() {
return primaryValue;
}
public void setPrimaryValue(TestdataValue primaryValue) {
this.primaryValue = primaryValue;
}
#PlanningVariable(valueRangeProviderRefs = "valueRange")
public TestdataValue getSecondaryValue() {
return secondaryValue;
}
public void setSecondaryValue(TestdataValue secondaryValue) {
this.secondaryValue = secondaryValue;
}
#CustomShadowVariable(variableListenerClass = ComposedValuesUpdatingVariableListener.class,
sources = {#CustomShadowVariable.Source(variableName = "primaryValue"),
#CustomShadowVariable.Source(variableName = "secondaryValue")})
public String getComposedCode() {
return composedCode;
}
public void setComposedCode(String composedCode) {
this.composedCode = composedCode;
}
#CustomShadowVariable(variableListenerRef = #PlanningVariableReference(variableName = "composedCode"))
public String getReverseComposedCode() {
return reverseComposedCode;
}
public void setReverseComposedCode(String reverseComposedCode) {
this.reverseComposedCode = reverseComposedCode;
}
You can make shadow variables that depend on shadow variables.
Create a custom shadow variable (with a VariableListener impl) for startIndex that depends on endIndex and length (which are both shadow vars).

OrmLite Foreign Collection to List

I try to use foreign collections in ORMLite. However, I dont know how to convert it into list. I try to do something like this :
public class Car implements Serializable {
#DatabaseField(columnName = "carId" , generatedId = true, id=true)
private int id;
#DatabaseField(columnName = "carNumber")
private String mNumber;
#DatabaseField(columnName = "carName")
private String mName;
#ForeignCollectionField(eager = true,columnName = "carParts")
private Collection<Part> mParts;
ArrayList<Part> parts = new ArrayList<>(mParts);
public ArrayList<Part> getParts() {
return parts;
}
public void setParts(ArrayList<Part> parts) {
this.parts = parts;
}
but when I try to use it I get exception :
java.lang.NullPointerException: collection == null
at this line :
ArrayList<Part> parts = new ArrayList<>(mParts);
please, help.
The reason is simple - you have to wait until mParts will be initialized by ORMLite library, then you can create ArrayList from it.
public ArrayList<Part> getParts() {
return new ArrayList<>( mParts );
}

Wicket Wizard show index of step

for my Wicket Wizard I want to display an information like: "Wizard step 1 of 4". I started by getting the number of steps and I already came across the first problem:
public WizardPanel(String id) {
super(id, false);
// false deactivates the default style.
setDefaultModel(new CompoundPropertyModel<WizardPanel>(this));
WizardModel model = new WizardModel();
model.add(new FirstStep());
model.add(new SecondStep());
model.add(new ThirdStep());
model.add(new ConfirmationStep());
Iterator<IWizardStep> iterator = model.stepIterator();
for(int i = 1; iterator.hasNext(); i ++){
System.out.println(String.valueOf(i));
}
init(model);
}
My Iterator creates an infinite loop. Shouldn't there only be four objects he can iterate through?
Or is there even a basic implementation for this kind of pagination I haven't found yet?
Because my next step would be to get the current index out of model.getActiveStep(); and find which number it is.
I thought I share my solution (as far as it now is)
public class OverviewComponent extends Panel{
private static final long serialVersionUID = 1L;
private List<WizardStep> steps;
private WizardModel model;
public OverviewComponent(String id, WizardModel model) {
super(id);
this.model = model;
steps = fillList();
this.add(new ListView<WizardStep>("steps", steps) {
private static final long serialVersionUID = 1L;
/**
* Wrap a markup container around the item append a css attribute to every item
*/
#Override
protected void populateItem(ListItem<WizardStep> item) {
WebMarkupContainer stepOverviewItem;
item.add(stepOverviewItem = new WebMarkupContainer("stepOverviewItem"));
stepOverviewItem.add(new Label("index", Model.of(item.getIndex()+1)));
stepOverviewItem.add(new AttributeModifier("class", getCSSProperty(item.getModelObject())));
stepOverviewItem.setOutputMarkupId(true);
stepOverviewItem.setOutputMarkupPlaceholderTag(true);
}
});
}
public String getCSSProperty(WizardStep step) {
if (step.equals(model.getActiveStep())) {
return "active";
} else if (!step.isComplete()) {
return "pending";
} else if (step.isComplete()) {
return "completed";
}
return "";
}
public List<WizardStep> fillList() {
List<WizardStep> iSteps = new ArrayList<WizardStep>();
Iterator<IWizardStep> iterator = model.stepIterator();
while (iterator.hasNext()) {
iSteps.add((WizardStep)iterator.next());
}
return iSteps;
}
}

Method to check if number is contained in ArrayList will not work, NullPointerExcepton. Can you use ArrayList method inside a constructed method?

This is a project I am working on and it is supposed to take input from the user then which is an area code then see if it is contained in a array list. My method that I have created will not work in another class and I am not sure why, it is returning a NullPointerException.
The NullPointerException is shown at this line of code: if (mountainTime.contains(input))
This is the class with methods
package finalPro;
import java.util.ArrayList;
public class Final
{
public Final()
{
input = 0;
timezone = 0;
}
public void checkIfTrue(int y)
{
input = y;
if (mountainTime.contains(input))
{
timezone = 1;
}
else
timezone = 0;
System.out.println(timezone);
}
public int getZone()
{
return timezone;
}
public ArrayList<Integer> mountainTime;
private int input;
private int timezone;
}
Here is test class
package finalPro;
import java.util.ArrayList;
import javax.swing.JOptionPane;
public class FinalLogic
{
public static void main(String[] args)
{
ArrayList<Integer> mountainTime = new ArrayList<Integer>();
mountainTime.add(480);
mountainTime.add(602);
mountainTime.add(623); //Arizona area codes
mountainTime.add(928);
mountainTime.add(520);
mountainTime.add(303);
mountainTime.add(719); //Colorado
mountainTime.add(720);
mountainTime.add(970);
mountainTime.add(406); //Montana
mountainTime.add(505); //New Mexico
mountainTime.add(575);
mountainTime.add(385);
mountainTime.add(435); //Utah
mountainTime.add(801);
mountainTime.add(307); //Wyoming
Final myMap = new Final();
{
String x = JOptionPane.showInputDialog("Please enter a number: ");
int input = Integer.parseInt(x);
myMap.checkIfTrue(input);
}
}
}
I hope it's not too late, I haven't done anything special to fix your code, just some movement of code,
Removed the initialization logic from class FinalLogic to Final class .(btw Final name is not really good, you might be aware final is reserved word in Java. Although your name is case sensitive but still)
package finalPro;
import javax.swing.JOptionPane;
public class FinalLogic {
public static void main(String[] args) {
Final myMap = new Final();
String x = JOptionPane.showInputDialog("Please enter a number: ");
int input = Integer.parseInt(x);
myMap.checkIfTrue(input);
}
}
And here is your class Final
package finalPro;
import java.util.ArrayList;
public class Final {
public Final() {
input = 0;
timezone = 0;
// moved all initialization logic to constructor
mountainTime = new ArrayList<>();
mountainTime.add(480);
mountainTime.add(602);
mountainTime.add(623); // Arizona area codes
mountainTime.add(928);
mountainTime.add(520);
mountainTime.add(303);
mountainTime.add(719); // Colorado
mountainTime.add(720);
mountainTime.add(970);
mountainTime.add(406); // Montana
mountainTime.add(505); // New Mexico
mountainTime.add(575);
mountainTime.add(385);
mountainTime.add(435); // Utah
mountainTime.add(801);
mountainTime.add(307); // Wyoming
}
public void checkIfTrue(int y) {
input = y;
if (mountainTime.contains(input)) {
timezone = 1;
} else
timezone = 0;
System.out.println(timezone);
}
public int getZone() {
return timezone;
}
public ArrayList<Integer> mountainTime;
private int input;
private int timezone;
}
I tried in my workspace, it gives no NPE, Hope it helps.