How to use OptaPlanner ValueRange from planning entity? - java

I'm attempting to limit the planning variables that can be associated with a particular entity. In the OptaPlanner manual in section 4.3.4.2.2, an example is shown, but it isn't clear how the list of variables should be generated. What should the list contain? Are these planning variables themselves? Can they be copies? If copies are allowed, then how are they compared? If not, the planning variable is not in scope when defining the planning entity - I realize that this is a Java question, but it isn't apparent how to access the list of planning variables from the planning entity definition.
Is this is a 6.1 feature that was not supported in earlier versions?
Will the Working Memory size be constrained by using this feature? That is my goal.
Your assistance is greatly appreciated!
Here's the example from the manual:
#PlanningVariable
#ValueRange(type = ValueRangeType.FROM_PLANNING_ENTITY_PROPERTY, planningEntityProperty = "possibleRoomList")
public Room getRoom() {
return room;
}
public List<Room> getPossibleRoomList() {
return getCourse().getTeacher().getPossibleRoomList();
}

Let's set the terminology straight first: The planning variable (for example getRoom() in the example) has a value range (which is a list of planning values) which different from entity instance to entity instance.
About such a List of planning values:
Each entity has it's own List instance, although multiple entities can share the same List instance if they have the exact same value range.
No copies: A planning value instance should only exists once in a Solution. So 2 entities with different value ranges, but with the same planning value in their value ranges, should be using the same planning value instance.

Related

Indexing a simple Java Record

I have a Java Object, Record . It represents a single record as a result of SQL execution. Can CQEngine index collection of Record ?
My class is of the form
public class Record {
private List<String> columnNames;
private List<Object> values;
... Other getters
}
I have looked through some examples, but I have no luck there.
I want to index only specific column(s) with its name and corresponding value. Can this be achived using cqengine or is there any other alternatives to achieve the same.
Thanks.
That seems to be a strange way to model data, but you can use CQEngine with that model if you wish.
(First off, CQEngine will have no use for your column names so you can remove that field.)
To do this, you will need to define a CQEngine virtual attribute for each of the indexes in your list of values.
Each attribute will need to be declared with the data type which will be stored in that column/index, and will need to be able to cast the object at that index in your list of values, to the appropriate data type (String, Double, Integer etc.).
So let's say your Record has a column called 'price', which is of type Double, and is stored at index 5 in the list of values. You could define an attribute which reads it as follows:
public static final Attribute<Record, Double> PRICE =
attribute("PRICE", record -> ((Double) record.values.get(5));
If this sounds complicated, it's because that way of modelling data makes things a bit complicated :) It's usually easier to work with a data model which leverages the Java type system (which your model does not). As such, you will need to keep track of the data types etc. of each field programmatically yourself.
CQEngine itself will work fine with that model though, because at the end of the day CQEngine attributes don't need to read fields, the attributes are just functions which are programmed to fetch values.
There's a bunch of stuff not covered above. For example can your values be null? (if so, you should use the nullable variety of attributes as discussed in the CQEngine docs. Or, might each of your Record objects have different sets of columns? (if so, you can create attributes on-the-fly when you encounter a new column, but you should probably cache the attributes you have created somewhere).
Hope that helps,
Niall (CQEngine author)

Is it okay to have type checking code when working with databases?

I'm trying to insert some code into a database. But, i have encountered a problem while working with models that are subclasses of each other. I have a list that holds all these subclases.
List<Metric> metrics = experiment.getMetrics();
for(Metric m : metrics) {
int id = m.getId();
// type checking code
}
Metric has sublcases of Rating and Quantity. Each of these in turn have there own uniquely defined tables. I am conflicted over the idea of using type checking. But I don't see any immediate solution. One alternative, which doesn't seem any better, would be to create a new column in the Metric table called metric_type. But this would lead to something quite similar to type checking. Any suggestions?
You have encountered Object-relational impedance mismatch due to mapping between not fully compatible systems. Since inheritance is not possible between tables in the relational model you will have to sacrifice something in the object model that uses inheritance. There will be edge cases no matter what you do unless you switch to an object database.
If you define a custom CRUD operations in classes that extend Metric loading entites can be tricky. What exactly will be loaded by Metric.get(id) if each table has it's own PK sequence and both Rating and Quantity can have the same numeric PK value.
You can take a look on how JPA solves this problem. It uses custom annotations e.g. #MappedSuperclass and #Entity. I guess that's a form of type checking.
I wouldn't suggest you to type check
The OOP way to solve this would be to make an insert method in the Metric class.
Then override the method both in Rating and Quality with the appropriate code that inserts the object in the respective table.
for(Metric m : metrics) {
int id = m.getId();
m.insert();
}
Inside your loop simply call insert and due to late-binding the appropriate method will be called and the right code will be executed.

Efficient way redis set member update

I have a redis set. This set can store 20 members maximum(added withSADD command).
My problem is ; I need to update that members when needed. Members need that modification maximum 10 times for every member. Set members are json as a string. There is only solutoin on my mind nor, get all members update and recreate that set again. But it seems iditoic.
I know there is ZADD sorted set with its score support it seems suitable also I need to update score like data in json , but i just wonder Is there any method updating members in efficient way, or is updating member not acceptable on redis way ?
Note: Redis datastore is using by both node.js and java clients.
Set members themselves are immutable - you can add new members or remove existing ones. That's it.
Given that a set is an unordered collection of unique members, consider the possible outcomes were set members theoretically modifiable when the new value for a member:
is identical to the old value - no change to the set
already exists in the set - equivalent to deleting that member
isn't 1 or 2 - equivalent to deleting the member and adding a new one

Java: Pattern for updating all equal objects (in the same context) that don't share the same reference

In my java application I am using equal objects multiple times at different places. That means the equals method returns true, when comparing theses objects. Now I want to update one object and make the changes to all objects that are equal. Do you know if there is a pattern for that?
My concrete use case is:
I am using JSF, JPA and CDI. A user is on web page that allows him to edit the detached entity EntityA. The page is sessionscoped. EntityA has two references to an EntityB (also detached). These objects can be same. Not the same reference, but they may be equal.
#Entity
public class EntityA {
#OneToOne()
private EntityB entity1;
#OneToOne();
private EntityB entity2;
}
The JSF view lets the uses select entity1 and entity2 from a selection list. It also shows some details of theses EntityBs and the user is allowed to edit entity1 and entity2 seperately. Everything works fine, except the user has choses the same (equal) EntityB for entity1 and entity2. Then, only the references to these objects are updated. Of course entity1 and entity2 are two different JPA entites, and are not the same reference. But I want to distribute the changes to all detached instances of EntityB. I have this situation hundreds of times in my application, so I dont want to take care about, which objects have to be updated in which situations. I need some solutation the does it for me automatically. One Idea was to keep all objects I use in this session in special list and every time a request was submitted and processed iterate over this map and change alle equal objects. But his sounds very dirty. Maybe there is a build in JPA function to make all equal objects the same reference. I dont know if this is possible. Do you have a solution for this? Thanks.
I'm going to abstract your problem out a bit here: if a change to one object requires changing a number of other objects, consider putting the field that you're changing in a separate object, and have all those objects reference it.
For example, if you have:
class MyClass {
String info;
int id;
}
and two instances of MyClass with the same 'id' should both be updated when the 'info' field changes then use this:
class myClass {
myInfoClass info;
int id
}
class myInfoClass {
String value;
}
and give all instances of myClass that are equal the same instances of myInfoClass. Changing myClass.info.value will effectively change all instances of myClass, because they all hold the same instance of myInfoClass.
Sorry if I've got the syntax slightly wrong, I jump between languages a lot.
I use this technique in a game I wrote recently where a switch activates a door- both the switch and door have a Circuit object that holds a boolean powered field. The doors 'isOpen()' method simply returned circuit.powered, and when the switch is activated I just call switch.circuit.powered = true, and the door is automatically considered 'open'. Previously, I had it searching the game's map for all doors with the same circuit id, and changing the powered field on each.
this is classic form handling logic
if the user clicks the save button manipulate the data in the database
reload the data every time you create the web page
you should not cache the data in the web session
if you need caching, activate it in the persistence layer (ex. hibernate cache)

Key-Value on top of Appengine

Although appengine already is schema-less, there still need to define the entities that needed to be stored into the Datastore through the Datanucleus persistence layer. So I am thinking of a way to get around this; by having a layer that will store Key-value at runtime, instead of compile-time Entities.
The way this is done with Redis is by creating a key like this:
private static final String USER_ID_FORMAT = "user:id:%s";
private static final String USER_NAME_FORMAT = "user:name:%s";
From the docs Redis types are: String, Linked-list, Set, Sorted set. I am not sure if there's more.
As for the GAE datastore is concerned a String "Key" and a "Value" have to be the entity that will be stored.
Like:
public class KeyValue {
private String key;
private Value value; // value can be a String, Linked-list, Set or Sorted set etc.
// Code omitted
}
The justification of this scheme is rooted to the Restful access to the datastore (that is provided by Datanucleus-api-rest)
Using this rest api, to persist a object or entity:
POST http://datanucleus.appspot.com/dn/guestbook.Greeting
{"author":null,
"class":"guestbook.Greeting",
"content":"test insert",
"date":1239213923232}
The problem with this approach is that in order to persist a Entity the actual class needs to be defined at compile time; unlike with the idea of having a key-value store mechanism we can simplify the method call:
POST http://datanucleus.appspot.com/dn/org.myframework.KeyValue
{ "class":"org.myframework.KeyValue"
"key":"user:id:johnsmith;followers",
"value":"the_list",
}
Passing a single string as "value" is fairly easy, I can use JSON array for list, set or sorted list. The real question would be how to actually persist different types of data passed into the interface. Should there be multiple KeyValue entities each representing the basic types it support: KeyValueString? KeyValueList? etc.
Looks like you're using a JSON based REST API, so why not just store Value as a JSON string?
You do not need to use the Datanucleus layer, or any of the other fine ORM layers (like Twig or Objectify). Those are optional, and are all based on the low-level API. If I interpret what you are saying properly, perhaps it already has the functionality that you want. See: https://developers.google.com/appengine/docs/java/datastore/entities
Datanucleus is a specific framework that runs on top of GAE. You can however access the database at a lower, less structured, more key/value-like level - the low-level API. That's the lowest level you can access directly.
BTW, the low-level-"GAE datastore" internally runs on 6 global Google Megastore tables, which in turn are hosted on the Google Big Table database system.
Saving JSON as a String works fine. But you will need ways to retrieve your objects other than by ID. That is, you need a way to index your data to support any kind of useful query on it.

Categories

Resources