<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <meta content="text/html; charset=ISO-8859-1"
      http-equiv="Content-Type">
    <title></title>
  </head>
  <body text="#000000" bgcolor="#ffffff">
    Op 27-05-11 22:39, Michael Anstis schreef:
    <blockquote
      cite="mid:BANLkTimd5wLfJT5Ki1ktKmVn6aibFYtZCA@mail.gmail.com"
      type="cite">Phew! I made it to the end of the email ;)<br>
      <br>
      All very interest Geoffrey, but have you explained the purpose of
      the annotations? Why must I now annotate things, what value is it
      bringing?<br>
    </blockquote>
    The real value will be explained in the manual later and visible
    when we build stuff on this :)<br>
    This mail is mainly to rattle people's cages:<br>
    &nbsp; <b>can you live with the bad side of these changes or not?</b><br>
    Speak up now, before I go further on this path and there's no going
    back.<br>
    <br>
    <blockquote
      cite="mid:BANLkTimd5wLfJT5Ki1ktKmVn6aibFYtZCA@mail.gmail.com"
      type="cite"><br>
      I don't, personally, have any problem with them - there are many
      libraries that use them - but their purpose is well understood:
      e.g. @Entity, @Resource etc<br>
    </blockquote>
    Good point that I need to explain it better to open up the
    discussion.<br>
    Basically, Planner needs to know what are you planning variables (of
    the planning entity classes) and what are allowed values of each
    planning variable (ignoring the non-build-in constraints).<br>
    It's also the first step to declarative moves.<br>
    <blockquote
      cite="mid:BANLkTimd5wLfJT5Ki1ktKmVn6aibFYtZCA@mail.gmail.com"
      type="cite">
      <br>
      Perhaps I missed something?<br>
      <br>
      With kind regards<br>
      <br>
      Mike<br>
      <br>
      <div class="gmail_quote">On 27 May 2011 11:13, Geoffrey De Smet <span
          dir="ltr">&lt;<a moz-do-not-send="true"
            href="mailto:ge0ffrey.spam@gmail.com">ge0ffrey.spam@gmail.com</a>&gt;</span>
        wrote:<br>
        <blockquote class="gmail_quote" style="margin: 0pt 0pt 0pt
          0.8ex; border-left: 1px solid rgb(204, 204, 204);
          padding-left: 1ex;">
          <div text="#000000" bgcolor="#ffffff"> Hi guys<br>
            <br>
            For Drools Planner 5.3.0 (not the upcoming release)<br>
            I am working on a separate branch [1] to allow Planner to
            understand your domain model better.<br>
            <b>This will force some big changes upon you as a user</b>,
            but it will also allow many new features.<br>
            Reading and replying to this mail is your chance to steer
            those changes, and verify that they are a good thing for
            your implementation too.<br>
            I'll push those changes to master in a day or 2 ... unless
            someone finds a good reason not too.<br>
            <br>
            Any feed-back, especially on concept names, is welcome.<br>
            <br>
            <b>The Bad News</b><br>
            <br>
            You'd have to do some serious upgrading changes. Although I
            am confident this can be done in an hour or 2.<br>
            Here is the upgrading recipe as in github. Please go through
            to this list to understand the impact of these changes.<br>
            Once the changes are on master, I 'll update the reference
            manual.<br>
            <br>
            <br>
            [MAJOR] You need to define your solution class in the
            configuration now:<br>
            Before in *SolverConfig.xml and *BenchmarkConfig.xml:<br>
            &nbsp;&nbsp;&nbsp; &lt;localSearchSolver&gt;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;scoreDrl&gt;...&lt;/scoreDrl&gt;<br>
            After in *SolverConfig.xml and *BenchmarkConfig.xml:<br>
            &nbsp;&nbsp;&nbsp; &lt;localSearchSolver&gt;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;solutionClass&gt;org.drools.planner.examples.curriculumcourse.domain.CurriculumCourseSchedule&lt;/solutionClass&gt;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;scoreDrl&gt;...&lt;/scoreDrl&gt;<br>
            <br>
            [RECOMMENDED] Understand the concept of a "planning entity"
            class.<br>
            The class (or classes) that change during planning (and do
            not implement Solution) are a planning entity.<br>
            For example: ShiftAssignment, BedDesignation, Queen,
            CloudAssignment, ...<br>
            The other domain classes are considered normal planning
            facts,<br>
            for example Shift, Employee, Bed, Room, Department, ...<br>
            They do not change during planning (at least not without
            pausing the solver).<br>
            Read the manual to understand the "planning entity" concept
            better.<br>
            <br>
            [MAJOR] You need to define your planning entity class(es) in
            the configuration now:<br>
            Before in *SolverConfig.xml and *BenchmarkConfig.xml:<br>
            &nbsp;&nbsp;&nbsp; &lt;localSearchSolver&gt;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;solutionClass&gt;....&lt;/solutionClass&gt;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;scoreDrl&gt;...&lt;/scoreDrl&gt;<br>
            After in *SolverConfig.xml and *BenchmarkConfig.xml:<br>
            &nbsp;&nbsp;&nbsp; &lt;localSearchSolver&gt;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;solutionClass&gt;....&lt;/solutionClass&gt;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
&lt;planningEntityClass&gt;org.drools.planner.examples.curriculumcourse.domain.Lecture&lt;/planningEntityClass&gt;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;scoreDrl&gt;...&lt;/scoreDrl&gt;<br>
            <br>
            [MAJOR] You need to annotate your planning entity class(es)
            with the @PlanningEntity annotation<br>
            Before in *.java:<br>
            &nbsp;&nbsp;&nbsp; public class Lecture ... {<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            &nbsp;&nbsp;&nbsp; }<br>
            After in *.java:<br>
            &nbsp;&nbsp;&nbsp; @PlanningEntity<br>
            &nbsp;&nbsp;&nbsp; public class Lecture ... {<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            &nbsp;&nbsp;&nbsp; }<br>
            <br>
            [RECOMMENDED] Understand the concept of a "planning
            variable" property.<br>
            The property (or properties) on a planning entity class that
            are changed (through their setter) during planning<br>
            are planning variables.<br>
            For example: ShiftAssignment.getEmployee(),
            BedDesignation.getBed(), Queen.getY(), ...<br>
            Note that most planning entities have 1 property which
            defines the planning entity<br>
            and that property is NOT a planning variable.<br>
            For example: ShiftAssignment.getShift(),
            BedDesignation.getAdmissionPart(), Queen.getX(), ...<br>
            Read the manual to understand the "planning variable"
            concept better.<br>
            <br>
            [MAJOR] You need to annotate your planning variable
            property(ies) with the @PlanningVariable annotation.<br>
            Furthermore, you need to annotate a @ValueRange* annotation
            on to define the allowed values.<br>
            Commonly, you 'll use @ValueRangeFromSolutionProperty which
            specifies a property name on the solution<br>
            which returns a collection of the allowed values for that
            variable.<br>
            Before in *.java:<br>
            &nbsp;&nbsp;&nbsp; @PlanningEntity<br>
            &nbsp;&nbsp;&nbsp; public class Lecture ... {<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Course course;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private int lectureIndexInCourse;<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Changed by moves, between score calculations.<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Period period;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Room room;<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Course getCourse() {...}<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setCourse(Course course) {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int getLectureIndexInCourse() {...}<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setLectureIndexInCourse(int
            lectureIndexInCourse) {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Period getPeriod() {...}<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setPeriod(Period period) {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Room getRoom() {...}<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setRoom(Room room) {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int getStudentSize() {<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return course.getStudentSize();<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Day getDay() {<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return period.getDay();<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
            <br>
            &nbsp;&nbsp;&nbsp; }<br>
            After in *.java:<br>
            &nbsp;&nbsp;&nbsp; @PlanningEntity<br>
            &nbsp;&nbsp;&nbsp; public class Lecture ... {<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Course course;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private int lectureIndexInCourse;<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Changed by moves, between score calculations.<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Period period;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private Room room;<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // This is not a PlanningVariable: it defines the
            planning entity<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Course getCourse() {...}<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setCourse(Course course) {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // This is not a PlanningVariable: it defines the
            planning entity<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int getLectureIndexInCourse() {...}<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setLectureIndexInCourse(int
            lectureIndexInCourse) {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @PlanningVariable<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @ValueRangeFromSolutionProperty(propertyName =
            "periodList")<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Period getPeriod() {...}<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setPeriod(Period period) {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @PlanningVariable<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @ValueRangeFromSolutionProperty(propertyName =
            "roomList")<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Room getRoom() {...}<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setRoom(Room room) {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // This is not a PlanningVariable: no setter<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public int getStudentSize() {<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return course.getStudentSize();<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // This is not a PlanningVariable: no setter<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Day getDay() {<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return period.getDay();<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
            <br>
            &nbsp;&nbsp;&nbsp; }<br>
            <br>
            [MAJOR] Annotate every property on your Solution that
            returns a collection of planning entities<br>
            with @PlanningEntityCollectionProperty.<br>
            Before in *.java:<br>
            &nbsp;&nbsp;&nbsp; public class CurriculumCourseSchedule ... implements
            Solution&lt;...&gt; {<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private List&lt;Lecture&gt; lectureList;<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public List&lt;Lecture&gt; getLectureList() {...}<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setLectureList(List&lt;Lecture&gt;
            lectureList) {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp; }<br>
            After in *.java:<br>
            &nbsp;&nbsp;&nbsp; public class CurriculumCourseSchedule ... implements
            Solution&lt;...&gt; {<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private List&lt;Lecture&gt; lectureList;<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @PlanningEntityCollectionProperty<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public List&lt;Lecture&gt; getLectureList() {...}<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void setLectureList(List&lt;Lecture&gt;
            lectureList) {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp; }<br>
            <br>
            [MAJOR] The method getFacts() has been removed from the
            Solution interface.<br>
            Annotate every property that returns a fact or fact
            collection with the @PlanningFactProperty<br>
            or @PlanningFactCollectionProperty annotation respectively,<br>
            except those already annotated with
            @PlanningEntityCollectionProperty.<br>
            Properties annotated with these annotations are inserted
            into the working memory as facts:<br>
            - @PlanningFactProperty<br>
            - @PlanningFactCollectionProperty: each element in the
            collection<br>
            - @PlanningEntityCollectionProperty: each planning entity in
            the collection that is initialized<br>
            Remove the getFacts() method.<br>
            Before in *.java:<br>
            &nbsp;&nbsp;&nbsp; public class ... implements Solution&lt;...&gt; {<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private InstitutionalWeighting
            institutionalWeighting;<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private List&lt;Teacher&gt; teacherList;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private List&lt;Curriculum&gt; curriculumList;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private List&lt;UnavailablePeriodConstraint&gt;
            unavailablePeriodConstraintList;<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private List&lt;Lecture&gt; lectureList;<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private HardAndSoftScore score;<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getName() {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public InstitutionalWeighting
            getInstitutionalWeighting() {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public List&lt;Teacher&gt; getTeacherList() {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public List&lt;Curriculum&gt; getCurriculumList()
            {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public List&lt;UnavailablePeriodConstraint&gt;
            getUnavailablePeriodConstraintList() {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @PlanningEntityCollectionProperty<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public List&lt;Lecture&gt; getLectureList() {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public ...Score getScore() {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public Collection&lt;? extends Object&gt; getFacts()
            {<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List&lt;Object&gt; facts = new
            ArrayList&lt;Object&gt;();<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; facts.addAll(teacherList);<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; facts.addAll(curriculumList);<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; facts.addAll(unavailablePeriodConstraintList);<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (isInitialized()) {<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; facts.addAll(lectureList);<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; facts.addAll(calculateTopicConflictList());<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return facts;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public List&lt;TopicConflict&gt;
            calculateTopicConflictList() {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp; }<br>
            After in *.java:<br>
            &nbsp;&nbsp;&nbsp; public class ... implements Solution&lt;...&gt; {<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private InstitutionalWeighting
            institutionalWeighting;<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private List&lt;Teacher&gt; teacherList;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private List&lt;Curriculum&gt; curriculumList;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private List&lt;UnavailablePeriodConstraint&gt;
            unavailablePeriodConstraintList;<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private List&lt;Lecture&gt; lectureList;<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private HardAndSoftScore score;<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // This is not a PlanningFactProperty: the name is
            inserted into the working memory<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public String getName() {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @PlanningFactProperty<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public InstitutionalWeighting
            getInstitutionalWeighting() {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @PlanningFactCollectionProperty<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public List&lt;Teacher&gt; getTeacherList() {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @PlanningFactCollectionProperty<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public List&lt;Curriculum&gt; getCurriculumList()
            {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @PlanningFactCollectionProperty<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public List&lt;UnavailablePeriodConstraint&gt;
            getUnavailablePeriodConstraintList() {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // This is not a PlanningFactCollectionProperty: it
            is a PlanningEntityCollectionProperty<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @PlanningEntityCollectionProperty<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public List&lt;Lecture&gt; getLectureList() {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // This is not a PlanningFactProperty: the score is
            inserted into the working memory<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public ...Score getScore() {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // renamed from calculateTopicConflictList because
            these are also facts needed in the working memory<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @PlanningFactCollectionProperty<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public List&lt;TopicConflict&gt;
            getTopicConflictList() {...}<br>
            <br>
            &nbsp;&nbsp;&nbsp; }<br>
            <br>
            [RECOMMEND] A planning entity is considered uninitialized if
            one if at least on of its planning variables is null.<br>
            Therefor it's now possible to start from a partially
            initialized solution,<br>
            for example during real-time re-planning as new facts events
            come in.<br>
            <br>
            [MAJOR] The StartingSolutionInitializer no longer has a
            isSolutionInitialized(AbstractSolverScope) method<br>
            Before in *StartingSolutionInitializer.java:<br>
            &nbsp;&nbsp;&nbsp; public class ...StartingSolutionInitializer extends
            AbstractStartingSolutionInitializer {<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; @Override<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public boolean
            isSolutionInitialized(AbstractSolverScope
            abstractSolverScope) {<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            <br>
            &nbsp;&nbsp;&nbsp; }<br>
            After in *StartingSolutionInitializer.java:<br>
            &nbsp;&nbsp;&nbsp; public class ...StartingSolutionInitializer extends
            AbstractStartingSolutionInitializer {<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            <br>
            &nbsp;&nbsp;&nbsp; }<br>
            <br>
            [MAJOR] The planning entity collection in the Solution can
            never be null,<br>
            but some (or all) of its planning entity's can be
            uninitialized.<br>
            So create them before setting the starting solution, instead
            of in your StartingSolutionInitializer.<br>
            Before in *.java:<br>
            &nbsp;&nbsp;&nbsp; public class ... {<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void ...() {<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CurriculumCourseSchedule schedule = new
            CurriculumCourseSchedule();<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; schedule.setTeacherList(teacherList);<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; schedule.setCourseList(courseList);<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; solver.setStartingSolution(schedule);<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
            <br>
            &nbsp;&nbsp;&nbsp; }<br>
            After in *.java:<br>
            &nbsp;&nbsp;&nbsp; public class ... {<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public void ...() {<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CurriculumCourseSchedule schedule = new
            CurriculumCourseSchedule();<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; schedule.setTeacherList(teacherList);<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; schedule.setCourseList(courseList);<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            schedule.setLectureList(createLectureList(schedule.getCourseList()));<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; solver.setStartingSolution(schedule);<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; private List&lt;Lecture&gt;
            createLectureList(List&lt;Course&gt; courseList) {<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; List&lt;Lecture&gt; lectureList = new
            ArrayList&lt;Lecture&gt;(courseList.size());<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; long id = 0L;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (Course course : courseList) {<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0; i &lt;
            course.getLectureSize(); i++) {<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Lecture lecture = new Lecture();<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lecture.setId((long) id);<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id++;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lecture.setCourse(course);<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Make sure to set all non
            PlanningVariable properties<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lecture.setLectureIndexInCourse(i);<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Notice that we lave the
            PlanningVariable properties on null<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lectureList.add(lecture);<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return lectureList;<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
            <br>
            &nbsp;&nbsp;&nbsp; }<br>
            <br>
            [RECOMMENDED] Remove the isInitialized() from Solution if
            you copied that from the examples.<br>
            Before in *.java:<br>
            &nbsp;&nbsp;&nbsp; public class ... implements Solution&lt;...&gt; {<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public boolean isInitialized() {<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (lectureList != null);<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            <br>
            &nbsp;&nbsp;&nbsp; }<br>
            After in *.java:<br>
            &nbsp;&nbsp;&nbsp; public class ... implements Solution&lt;...&gt; {<br>
            <br>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ...<br>
            <br>
            &nbsp;&nbsp;&nbsp; }<br>
            <br>
            <b><br>
              The Good News</b><br>
            <br>
            I already have written a brute force solver (only useful for
            very very small toy problems of course).<br>
            In time, I 'll write a branch and bound solver (only useful
            for very small toy problems of course).<br>
            <br>
            I 'll write generic, high-quality
            StartingSolutionInitializers that work on any program,<br>
            such as First Fit Decreasing and Cheapest Insertion.<br>
            A good StartingSolutionInitializer is really important to
            get a good result from Planner.<br>
            Currently writing a StartingSolutionInitializer was a bit of
            a black art.<br>
            Some users use a highly under optimized version or - even
            worse - none at all.<br>
            <br>
            Phasing. This will be fun.<br>
            You 'll be able to do configure this really easily:<br>
            &nbsp; Phase 1 = First Fit Decreasing (for initialization)<br>
            &nbsp; Phase 2 = Simulated Annealing (after initialization)<br>
            &nbsp; Phase 3 = Tabu search (when things get really hard)<br>
            Notice that a StartingSolutionInitializer is just a phase.<br>
            <br>
            [1] <a moz-do-not-send="true"
              href="https://github.com/droolsjbpm/drools-planner/pull/2/files"
              target="_blank">https://github.com/droolsjbpm/drools-planner/pull/2/files</a>
            <pre cols="72">-- 
With kind regards,
Geoffrey De Smet</pre>
          </div>
          <br>
          _______________________________________________<br>
          rules-dev mailing list<br>
          <a moz-do-not-send="true"
            href="mailto:rules-dev@lists.jboss.org">rules-dev@lists.jboss.org</a><br>
          <a moz-do-not-send="true"
            href="https://lists.jboss.org/mailman/listinfo/rules-dev"
            target="_blank">https://lists.jboss.org/mailman/listinfo/rules-dev</a><br>
          <br>
        </blockquote>
      </div>
      <br>
      <pre wrap="">
<fieldset class="mimeAttachmentHeader"></fieldset>
_______________________________________________
rules-dev mailing list
<a class="moz-txt-link-abbreviated" href="mailto:rules-dev@lists.jboss.org">rules-dev@lists.jboss.org</a>
<a class="moz-txt-link-freetext" href="https://lists.jboss.org/mailman/listinfo/rules-dev">https://lists.jboss.org/mailman/listinfo/rules-dev</a>
</pre>
    </blockquote>
    <br>
    <pre class="moz-signature" cols="72">-- 
With kind regards,
Geoffrey De Smet</pre>
  </body>
</html>