Enforce shifts in optaplanner using .drl hardconstraint - optaplanner

I need the min and max shifts to be equal. I want to enforce 9 shifts per employee over a 14 day period. I have 12 staff each must complete 9 shifts(hardconstraint). 108 shifts in the 14 day period. Does anyone have any suggestions as to the construct of the drl to enforce this even when using continuous planning? I am able to enforce on the first period but when I advance using scoredirector etc the rule doesn’t hold

If I could be a pain. As stated above I am planning 14 day cycles using continuous planning. I have modified the code to suite however, for the next planning period if appears as though none of the rules are enforced. I must be not understanding a concept. Below is my code.
doProblemFactChange(scoreDirector -> {
NurseRoster nurseRoster = scoreDirector.getWorkingSolution();
NurseRosterParametrization nurseRosterParametrization = nurseRoster.getNurseRosterParametrization();
List<ShiftDate> shiftDateList = nurseRoster.getShiftDateList();
Shift oldLastShift = nurseRoster.getShiftList().get(nurseRoster.getShiftList().size() - 1);
long shiftId = oldLastShift.getId() + 1L;
int shiftIndex = oldLastShift.getIndex() + 1;
ShiftDate oldLastShiftDate = shiftDateList.get(shiftDateList.size() - 1);
long shiftDateId = (oldLastShiftDate.getId() + 1L);
int shiftDayIndex = (oldLastShiftDate.getDayIndex() + 1);
// long parmId = nurseRoster.getNurseRosterParametrization().getId() + 1L;
scoreDirector.beforeProblemPropertyChanged(nurseRosterParametrization);
// Add 14 days to shift date in the database for later once I figure out how to use scoredirector properly
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session = sessionFactory.openSession();
/*session.beginTransaction();
RosterParametrizationData sched = (RosterParametrizationData) session.get(RosterParametrizationData.class,
1);
String newroster = sched.getCode();
sched.setCode(newroster);
sched.setStartDate(oldLastShiftDate.getDate().plusDays(1));
sched.setEndDate(oldLastShiftDate.getDate().plusDays(14));
rosterService.updateRosterParametrizationData(sched);
session.close();*/
//Update to get the first day along with adding 14 days to the run
LocalDate startDate = (oldLastShiftDate.getDate().plusDays(1));
LocalDate endDate = (oldLastShiftDate.getDate().plusDays(14));
int maxDayIndex = Math.toIntExact(DAYS.between(startDate, endDate));
int shiftDateSize = maxDayIndex + 1;
List<ShiftDate> shiftDateList1 = new ArrayList<>(shiftDateSize);
shiftDateMap = new HashMap<>(shiftDateSize);
LocalDate date = startDate;
for (int i = 0; i < shiftDateSize; i++) {
ShiftDate shiftDate = new ShiftDate();
shiftDate.setId(shiftDateId);
shiftDate.setDayIndex(shiftDayIndex);
shiftDate.setDate(date);
shiftDate.setShiftList(new ArrayList<>());
shiftDateMap.put(date, shiftDate);
shiftDateId++;
shiftDayIndex++;
date = date.plusDays(1);
nurseRoster.getShiftDateList().add(shiftDate);
shiftDateList1.add(shiftDate);
scoreDirector.afterProblemFactAdded(shiftDate);
//TODOD I think I have to call a method here for the scoredirector
}
List<ShiftType> shiftTypeElementList = (List<ShiftType>) nurseRoster.getShiftTypeList();
List<ShiftType> shiftTypeList = new ArrayList<>(shiftTypeElementList.size());
shiftTypeMap = new HashMap<>(shiftTypeElementList.size());
int index = 0;
List<ShiftTypeSkillRequirement> shiftTypeSkillRequirementList = new ArrayList<>(
shiftTypeElementList.size() * 2);
long shiftTypeId = 5L;
for (ShiftType element : shiftTypeElementList) {
ShiftType shiftType = new ShiftType();
//long Id = element.getId();
shiftType.setId(shiftTypeId );
shiftTypeId ++;
shiftType.setCode(element.getCode());
shiftType.setIndex(index);
String startTimeString = element.getStartTimeString();
shiftType.setStartTimeString(startTimeString);
String endTimeString = element.getEndTimeString();
shiftType.setEndTimeString(endTimeString);
shiftType.setNight(startTimeString.compareTo(endTimeString) > 0);
shiftType.setDescription(element.getDescription());
shiftTypeMap.put(shiftType.getCode(), shiftType);
shiftTypeList.add(shiftType);
//nurseRoster.getShiftTypeList().add(shiftType);
index++;
scoreDirector.afterProblemFactAdded(shiftType);
}
int shiftListSize = shiftDateMap.size() * shiftTypeList.size();
List<Shift> shiftList1 = new ArrayList<>(shiftListSize);
dateAndShiftTypeToShiftMap = new HashMap<>(shiftListSize);
dayOfWeekAndShiftTypeToShiftListMap = new HashMap<>(7 * shiftTypeList.size());
for (ShiftDate shiftDate : shiftDateList1) {
for (ShiftType shiftType : shiftTypeList) {
Shift shift = new Shift();
shift.setId(shiftId);
shift.setShiftDate(shiftDate);
shiftDate.getShiftList().add(shift);
shift.setShiftType(shiftType);
shift.setIndex(shiftIndex);
shift.setRequiredEmployeeSize(0); // Filled in later
shiftList1.add(shift);
dateAndShiftTypeToShiftMap.put(Pair.of(shiftDate.getDate(), shiftType.getCode()), shift);
addShiftToDayOfWeekAndShiftTypeToShiftListMap(shiftDate, shiftType, shift);
shiftId++;
shiftIndex++;
nurseRoster.getShiftList().add(shift);
scoreDirector.afterProblemFactAdded(shift);
}
}
List<ShiftAssignment> coverRequirementElementList = (List<ShiftAssignment>) nurseRoster.getShiftAssignmentList();
for (ShiftAssignment asselement : coverRequirementElementList) {
String type = asselement.getShiftType().getCode();
DayOfWeek day = asselement.getShiftDateDayOfWeek();
int req = asselement.getShift().getRequiredEmployeeSize();
ShiftType shiftType = shiftTypeMap.get(type);
Pair<DayOfWeek, ShiftType> key = Pair.of(day, shiftType);
List<Shift> shiftList2 = dayOfWeekAndShiftTypeToShiftListMap.get(key);
for (Shift shift : shiftList2) {
shift.setRequiredEmployeeSize(req);
}
}
List<ShiftAssignment> shiftAssignmentList = new ArrayList<>(shiftList1.size());
long shiftAssignmentId = nurseRoster.getShiftAssignmentList().get(nurseRoster.getShiftAssignmentList().size() - 1).getId() + 1L;
for (Shift shift : shiftList1) {
for (int i = 0; i < shift.getRequiredEmployeeSize(); i++) {
ShiftAssignment newShiftAssignment = new ShiftAssignment();
newShiftAssignment.setId(shiftAssignmentId);
shiftAssignmentId++;
newShiftAssignment.setShift(shift);
newShiftAssignment.setIndexInShift(i);
shiftAssignmentList.add( newShiftAssignment);
nurseRoster.getShiftAssignmentList().add(newShiftAssignment);
scoreDirector.afterEntityAdded(newShiftAssignment);
}
}
//This should move the planning window
nurseRosterParametrization.setFirstShiftDate(shiftDateList1.get(0));
nurseRosterParametrization.setLastShiftDate(shiftDateList1.get(shiftDateList1.size() - 1));
nurseRosterParametrization.setPlanningWindowStart(shiftDateList1.get(0));
nurseRoster.setNurseRosterParametrization(nurseRosterParametrization);
scoreDirector.afterProblemPropertyChanged(nurseRosterParametrization);
}, true);
}

Related

top “N” rows in each group using hibernate criteria

Top / Bottom / Random "N" rows in each group using Hibernate Criteria / Projections
How to retrieve top 5 Questions for Each Sub Topic
DetachedCriteria criteria = DetachedCriteria.forClass(Question.class);
ProjectionList projList = Projections.projectionList();
projList.add(Projections.property("questionId"));
projList.add(Projections.groupProperty("subTopicId"));
criteria.setProjection(projList);
List<Object> resultList = (List<Object>) getHibernateTemplate().findByCriteria(criteria);
Iterator<Object> itr = resultList.iterator();
List<Integer> questionIdList = new ArrayList<Integer>();
while(itr.hasNext()){
Object ob[] = (Object[])itr.next();
System.out.println(ob[0]+" -- "+ob[1]);
}
I am Using the Code Below for Getting Result Temporally, Is there any solution from Hibernate using Criteria API / Any other alternate way to get the result
Set<Integer> getQuestionsBySubTopicWithLimit(Set<Integer> questionIdsSet, Integer subjectId, Integer limit, Integer status) {
DetachedCriteria criteria = DetachedCriteria.forClass(Question.class);
if(subjectId!=null && subjectId!=0){
criteria.add(Restrictions.eq("subjectId", subjectId));
}
if(status!=null){
criteria.add(Restrictions.eq("status", status));
}
if(questionIdsSet!=null && !questionIdsSet.isEmpty()){
criteria.add(Restrictions.not(Restrictions.in("questionId", questionIdsSet)));
}
ProjectionList projList = Projections.projectionList();
projList.add(Projections.property("questionId"));
projList.add(Projections.property("subTopicId"));
criteria.add(Restrictions.sqlRestriction("1=1 order by sub_topic_id, rand()"));
criteria.setProjection(projList);
List<Object> resultList = (List<Object>) getHibernateTemplate().findByCriteria(criteria);
Iterator<Object> itr = resultList.iterator();
Set<Integer> tmpQuestionIdsSet = new HashSet<Integer>();
Integer subTopicId = 0, tmpSubTopicId = 0;
Integer count = 0;
while(itr.hasNext()){
Object ob[] = (Object[])itr.next();
if(count==0){
subTopicId = (Integer) ob[1];
}
tmpSubTopicId = (Integer) ob[1];
if(tmpSubTopicId!=subTopicId){
subTopicId = tmpSubTopicId;
count = 0;
}
count++;
if(count<=limit){
tmpQuestionIdsSet.add((Integer) ob[0]);
}
}
return tmpQuestionIdsSet;
}

Constraint Program: Build employee weekly schedules using ILOG

I'm new to constraint programming. Now I try to build weekly schedules to manage employee work time and to meet the labor demand. I am using ILOG CPLEX and try to fix the problem. I think this is an easy problem but I can't wrap my head around it. Here's the problem:
• We have multiple workers (i.e.47 workers), each with some constraints (let's say day min work hours, day max work hours, week min work hours, week max work hours)
• Each worker has at least one skill to do a task, with certain level
• We have some tasks (i.e. 10 tasks) every day, each day is split to 48 slots(0~47). a half hour one slot.
• A worker can only work on one task at the same slot (a half hour)
• A task at one slot has a labor demand (may be 2, means: need two workers to do this task at this slot), a min demand(may be 1), and a max demand(may be 10).
How do we assign the tasks to the workers to meet the demand and minimize the number of workers used and assign workers with higher level to do a task?
I'm just learning CP & ILOG CPLEX for two weeks. Any ideas on how to a constraint (i.e. day min work hours)?
I write some code as below:
CP cp = new CP();
//objective
INumExpr skillMatrixSum = cp.IntExpr();
//day min work hours and so on
IList<SMAIlogStaffInfo> listStaffInfo = SMAScheduleByILogStaffInfoBusiness.GetStaffInfoList(unitId, startDate, endDate, connectionString);
//skill level
IList<SMAIlogPersonSkillMatrixInfo> listPersonSkillMatrixInfo = SMAScheduleByILogSkillMatrixInfoBusiness.GetPersonSkillMatrixInfoList(unitId, startDate, endDate, connectionString);
//demand for every half hour
IList<SMAIlogDemandInfo> listDemandInfo = SMAScheduleByILogDemandInfoBusiness.GetDemandInfoList(unitId, startDate, endDate, connectionString);
//staff unavailability (i.e. ask for a leave)
IList<SMAIlogUnvailInfo> listUnvailInfo = SMAScheduleByILogUnvailInfoBusiness.GetUnvailInfoList(unitId, startDate, endDate, connectionString);
int nbWorkers = listStaffInfo.Select(t => t.PersonId).Distinct().Count();
IList<string> listPerson = listStaffInfo.Select(t => t.PersonId).ToList();
//possible tasks by skill
List<IIntervalVar> allTasks = new List<IIntervalVar>();
List<IIntervalVar>[] workerTasks = new List<IIntervalVar>[nbWorkers];
for (int w = 0; w < nbWorkers; w++)
{
workerTasks[w] = new List<IIntervalVar>();
}
//schedule by day from sunday to saturday
for (int weekdayIndex = 0; weekdayIndex < 7; weekdayIndex++)
{
IList<SMAIlogDemandInfo> listWeekdayDemandInfo = listDemandInfo.Where(t => t.Weekday == weekdayIndex).ToList();
IList<SMAIlogUnvailInfo> listWeekdayUnvailInfo = listUnvailInfo.Where(t => t.Weekday == weekdayIndex).ToList();
SetScheduleByDay(cp, skillMatrixSum, allTasks, workerTasks, listWeekdayDemandInfo, listWeekdayUnvailInfo, listStaffInfo, listPersonSkillMatrixInfo);
}
//constraint: one worker can not do two tasks at the same time
for (int w = 0; w < nbWorkers; w++)
{
IIntervalSequenceVar seq = cp.IntervalSequenceVar(workerTasks[w].ToArray(), listPerson[w]);
cp.Add(cp.NoOverlap(seq));
}
//Minimize skill Matrix
cp.Add(cp.Minimize(skillMatrixSum));
public static void SetScheduleByDay(CP cp, INumExpr skillMatrixSum, List<IIntervalVar> allTasks, List<IIntervalVar>[] workerTasks,
IList<SMAIlogDemandInfo> listWeekdayDemandInfo, IList<SMAIlogUnvailInfo> listWeekdayUnvailInfo, IList<SMAIlogStaffInfo> listStaffInfo, IList<SMAIlogPersonSkillMatrixInfo> listPersonSkillMatrixInfo)
{
int weekdayIndex = listWeekdayDemandInfo.Select(t => t.Weekday).FirstOrDefault();
int skillCount = listWeekdayDemandInfo.Select(t => t.SkillId).Distinct().Count(); //task count
int nbTasks = listWeekdayDemandInfo.Count(); //weekday demand
int nbWorkers = listStaffInfo.Count();//workers count
//decision variables
IIntervalVar[] tasks = new IIntervalVar[nbTasks];
IIntervalVar[,] taskMatrix = new IIntervalVar[nbTasks, nbWorkers];
ICumulFunctionExpr[] arrayResourcesWorkHours = new ICumulFunctionExpr[nbWorkers];
for (int j = 0; j < nbWorkers; j++)
{
arrayResourcesWorkHours[j] = cp.CumulFunctionExpr();
}
string taskFullName;
string skillId = "";
string personId = "";
int levelId = 0;
int demand = 0;
int slot = 0;
for (int i = 0; i < nbTasks; i++)
{
slot = listWeekdayDemandInfo[i].Slot;
demand = listWeekdayDemandInfo[i].Demand;
if (demand == 0)
{
continue;
}
skillId = listWeekdayDemandInfo[i].SkillId;
List<IIntervalVar> alttasks = new List<IIntervalVar>();
for (int w = 0; w < listStaffInfo.Count(); w++)
{
personId = listStaffInfo[w].PersonId;
levelId = listPersonSkillMatrixInfo.Where(t => t.SkillId == skillId && t.PersonId == personId).ToList().ToList().FirstOrDefault().LevelId;
//this worker can do this task
if (levelId > 0)
{
taskFullName = personId + "-" + weekdayIndex + "-" + slot + "-" + skillId;
IIntervalVar wtask = cp.IntervalVar(1, taskFullName);
wtask.SetOptional(); // SetOptional
alttasks.Add(wtask);
taskMatrix[i, w] = wtask;
workerTasks[w].Add(wtask);
allTasks.Add(wtask);
listStaffInfo[w].listWorkerTasks.Add(wtask);
skillMatrixSum = cp.Sum(skillMatrixSum, cp.Prod(levelId, cp.PresenceOf(wtask)));
}
}
cp.Add(cp.Alternative(tasks[i], alttasks.ToArray()));
}
//here is my problem. the way to generalize cumulative is wrong (DayMin and DayMax,also unavailability ).because tasks is Set Optional
for (int j = 0; j < listStaffInfo.Count; j++)
{
IList<IIntervalVar> listWorkerTasks = listStaffInfo[j].listWorkerTasks;
if (listWorkerTasks.Count == 0)
{
continue;
}
int dayMin = listStaffInfo[j].DayMin;
int dayMax = listStaffInfo[j].DayMax;
IConstraint dayMinConstraint = cp.Ge(arrayResourcesWorkHours[j], dayMin);
cp.Add(dayMinConstraint);
IConstraint dayMaxConstraint = cp.Le(arrayResourcesWorkHours[j], dayMax);
cp.Add(dayMaxConstraint);
INumToNumStepFunction availablityNumStep = cp.NumToNumStepFunction();
IList<SMAIlogUnvailInfo> listWeekdayPersonUnvailInfo = listWeekdayUnvailInfo.Where(t => t.PersonId == personId).ToList();
if (listWeekdayPersonUnvailInfo.Count > 0)
{
for (int k = 0; k < listWeekdayPersonUnvailInfo.Count; k++)
{
int startSlot = listWeekdayPersonUnvailInfo[k].StartSlot;
int endSlot = listWeekdayPersonUnvailInfo[k].EndSlot;
for (int i = 0; i < listWorkerTasks.Count; i++)
{
while (startSlot <= endSlot)
{
availablityNumStep.SetValue(startSlot, startSlot + 1, 0);
//cp.Add(cp.ForbidExtent(listWorkerTasks[i], availablityNumStep));
cp.Add(cp.ForbidStart(listWorkerTasks[i], availablityNumStep));
cp.Add(cp.ForbidEnd(listWorkerTasks[i], availablityNumStep));
startSlot++;
}
}
}
}
}
}
I have a set of input data as below:
Schedule Input Data
and also I have a example of out data as below:
Schedule Output Data

C# :Group XML data by date and find min Time

I need help to group by date and find the minimum time for each date.
Here, updateTime is an XML node. My application does not support LINQ.
**UpdateTime**
2014-01-18T23:04:51.223542
2014-01-18T16:39:36.030992
2014-01-18T04:33:44.307508
2014-01-17T22:47:01.163672
2014-01-17T15:57:26.389259
2014-01-17T06:19:41.422436
I used Enumerable Collection which includes Sort() method
string input = "2014-01-18T23:04:51.223542 2014-01-18T16:39:36.030992 2014-01-18T04:33:44.307508 2014-01-17T22:47:01.163672 2014-01-17T15:57:26.389259 2014-01-17T06:19:41.422436";
string[] timeArray = input.Split(new char[] { ' ' });
List<DateTime> times = new List<DateTime>();
foreach (string time in timeArray)
{
times.Add(DateTime.Parse(time));
}
times.Sort((x, y) => x.CompareTo(y));
DateTime minTime = times[0];​
Thanks for your suggestions.I am getting the data from XML.There is DateTime and associated result.I created a list with this output and grouped the list based on date and sorted them by time.Please suggest me for better options without using LINQ.
//group result(roclis) by date and minimum time for each date
var resultDateTime = dom.SelectNodes("//b:Lab[b:TestAbbreviation='" + rocLis + "']/b:UpdateTime", mgrb);
var dtList = new System.Collections.Generic.List<Tuple<DateTime,string>>();
var dtFilteredList = new System.Collections.Generic.List<Tuple<DateTime,string>>();
for (int i = 0; i < resultDateTime.Count; i++)
{
var resultTime = resultDateTime.Item(i).InnerText;
if (resultTime == "") continue;
DateTime rsltDtTime = Convert.ToDateTime(resultTime);
var labResult = dom.SelectSingleNode("//b:Lab[b:TestAbbreviation='" + rocLis + "'][b:UpdateTime='" + resultTime + "']/b:Result", mgrb);
string result = labResult.InnerText;
dtList.Add(Tuple.Create(rsltDtTime,result));
}
for (int i = dtList.Count - 1; dtList.Count > 0; )
{
DateTime tempDate = dtList[i].Item1.Date;
var selectDates = dtList.FindAll(x => x.Item1.Date == tempDate.Date);
selectDates.Sort((a, b) => a.Item1.CompareTo(b.Item1));
dtFilteredList.Add(Tuple.Create(selectDates[0].Item1, selectDates[0].Item2));
dtList.RemoveAll(x => x.Item1.Date == tempDate.Date);
i = dtList.Count - 1;
}

How to highlight query instead of highlighting search results in lucene.net?

I am searching a lot for this but I couldn't find any solution till now. I have a large query with the combination of proximity search. I need to find out where is the exact location of results in the query. For example a part of query is "hospital"~2 "readmissio"~2
. Now Lucene retrieve the correct documents and one of them contain the correct value "hospital re-admission" but how I can highlight the "readmissio" in the query for the "re-admission" from the document.
There are some workaround like levenshtein but due to huge amount of retrieval it is not practical, I hope there is some solution within lucene to find out the position of retrieved data from the query? Please advice.
string newQueryString = "";
string querystring = "To determine whether high performing hospitals with low 30 day risk standardized hospital readmissio rates have a lower proportion of readmission";
string[] tokens = NLP.Tokenize(querystring);
for (int i = 0; i < tokens.Length; i++)
{
string token = tokens[i];
token = "\"" + token + "\"" + "~" + 2;
// add token to new string expression
newQueryString = newQueryString + " " + token;
}
query = MultiFieldQueryParser.Parse(Lucene.Net.Util.Version.LUCENE_CURRENT,
new string[] { newQueryString }
, new string[] { "TERM" },
selectedAnalyzer);
TopDocs tp = indexSearcher.Search(query, 1);
int max = tp.TotalHits;
List<Lucene.Net.Documents.Document> ids = new List<Lucene.Net.Documents.Document>();
TopScoreDocCollector collector = TopScoreDocCollector.Create(max+1, true);
indexSearcher.Search(query, collector);
ScoreDoc[] hits = collector.TopDocs().ScoreDocs;
for (int i = 0; i < hits.Length; i++)
{
int docId = hits[i].Doc;
Lucene.Net.Documents.Document doc = indexSearcher.Doc(docId);
string concept = doc.GetFieldable("TERM").StringValue;
string[] contentTerms = NLP.Tokenize(querystring);
ITermFreqVector tfvector = reader.GetTermFreqVector(docId, "TERM");
TermPositionVector tpvector = (TermPositionVector)tfvector;
for (int k = 0; k < contentTerms.Length; k++)
{
string[] terms = tfvector.GetTerms();
int termidx = tfvector.IndexOf(contentTerms[k].Trim()); /// How to have readmission/readmissions here?????
int[] termposx = tpvector.GetTermPositions(termidx);
TermVectorOffsetInfo[] tvoffsetinfo = tpvector.GetOffsets(termidx);
int offsetStart = 0;
int offsetEnd = 0;
List<Tokens> conceptList = new List<Tokens>();
for (int j = 0; j < tvoffsetinfo.Length; j++)
{
offsetStart = tvoffsetinfo[j].StartOffset;
offsetEnd = tvoffsetinfo[j].EndOffset;
string key = concept.Substring(offsetStart, offsetEnd - offsetStart);
//////////////// Code continue////////////////
}
}
}
as it shows how can I highlight the "redamissi" part in my querystring for the concept "hospital readmission". ??? or in another example if I have readmissions in my query how can i highlight it for the retrieved value of "re-admission" or "admission" ???

neo4j get a random node from index

is there any option to get a random node from a lucene index with a index.query like below?
Index<Node> index = graphDb.index().forNodes("actors");
Node rand = index.query("foo:bar").getRandom();
Thanks
jörn
My problem was gradually work through a list of nodes, but in random order.
I played a bit around end ended up with a "id cache" as a temporary solution where only nodes with a specific attribute (not used and foo=bar) are stored.
You could use the cache longer if you'll add new nodes also to the cache and delete them from the cache as well.
private ArrayList<Long> myIndexIDs = new ArrayList<Long>();
private int minCacheSize = 100;
private int maxCacheSize = 5000;
public Node getRandomNode() {
boolean found = false;
Node n = null;
int index = getMyNodeIndex();
long id = myIndexIDs.get(index);
System.out.println(String.format("found id %d at index: %d", id, index));
ExecutionResult result = search.execute("START n=node(" + id + ") RETURN n");
for (Map<String, Object> row : result) {
n = (Node) row.get("n");
found = true;
break;
}
if (found) {
myIndexIDs.remove(index);
myIndexIDs.trimToSize();
}
return n;
}
// fill the arraylist with node ids
private void createMyNodeIDs() {
System.out.println("create node cache");
IndexHits<Node> result = this.myIndex.query("used:false");
int count = 0;
while (result.hasNext() && count <= this.maxCacheSize) {
Node n = result.next();
if (!(n.hasProperty("foo") && "bar" == (String) n.getProperty("foo"))) {
myIndexIDs.add(n.getId());
count++;
}
}
result.close();
}
// returns a random index from the cache
private int getMyIndexNodeIndex() {
// create a new index if you're feeling that it became too small
if (this.myIndexIDs.size() < this.minCacheSize) {
createMyNodeIDs();
}
// the current size of the cache
System.out.println(this.myIndexIDs.size());
// http://stackoverflow.com/a/363732/520544
return (int) (Math.random() * ((this.myIndexIDs.size() - 1) + 1));
}

Resources