[jboss-svn-commits] JBL Code SVN: r27546 - in labs/jbossrules/trunk/drools-solver: drools-solver-examples/src/main/java/org/drools/solver/examples/common/swingui and 1 other directories.

jboss-svn-commits at lists.jboss.org jboss-svn-commits at lists.jboss.org
Sat Jul 4 12:33:21 EDT 2009


Author: ge0ffrey
Date: 2009-07-04 12:33:21 -0400 (Sat, 04 Jul 2009)
New Revision: 27546

Added:
   labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/move/CompositeMove.java
   labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/pas/solver/move/factory/BedDesignationPillarPartSwitchMoveFactory.java
Modified:
   labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/common/swingui/WorkflowFrame.java
Log:
BedDesignationPillarPartSwitchMoveFactory

Added: labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/move/CompositeMove.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/move/CompositeMove.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-core/src/main/java/org/drools/solver/core/move/CompositeMove.java	2009-07-04 16:33:21 UTC (rev 27546)
@@ -0,0 +1,82 @@
+package org.drools.solver.core.move;
+
+import java.util.List;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.ArrayList;
+
+import org.drools.WorkingMemory;
+import org.drools.runtime.rule.FactHandle;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+
+/**
+ * A CompositeMove is composided out of multiple other moves.
+ * <p/>
+ * Warning: one of the moveList moves should not rely on the effect on of a previous moveList move
+ * to create an uncorrupted undoMove. In other words, 
+ * @see Move
+ * @author Geoffrey De Smet
+ */
+public class CompositeMove implements Move {
+
+    protected List<Move> moveList;
+
+    public List<Move> getMoveList() {
+        return moveList;
+    }
+
+    /**
+     * @param moveList cannot be null
+     */
+    public CompositeMove(List<Move> moveList) {
+        this.moveList = moveList;
+    }
+
+    public boolean isMoveDoable(WorkingMemory workingMemory) {
+        for (Move move : moveList) {
+            if (!move.isMoveDoable(workingMemory)) {
+                return false;
+            }
+        }
+        return true;
+    }
+
+    public Move createUndoMove(WorkingMemory workingMemory) {
+        List<Move> undoMoveList = new ArrayList<Move>(moveList.size());
+        for (Move move : moveList) {
+            // Note: this undoMove doesn't have the affect of a previous move in the moveList
+            // This could be made possible by merging the methods createUndoMove and doMove...
+            Move undoMove = move.createUndoMove(workingMemory);
+            undoMoveList.add(undoMove);
+        }
+        Collections.reverse(undoMoveList);
+        return new CompositeMove(undoMoveList);
+    }
+
+    public void doMove(WorkingMemory workingMemory) {
+        for (Move move : moveList) {
+            move.doMove(workingMemory);
+        }
+    }
+
+    public boolean equals(Object o) {
+        if (this == o) {
+            return true;
+        } else if (o instanceof CompositeMove) {
+            CompositeMove other = (CompositeMove) o;
+            return moveList.equals(other.moveList);
+        } else {
+            return false;
+        }
+    }
+
+    public int hashCode() {
+        return moveList.hashCode();
+    }
+
+    public String toString() {
+        return moveList.toString();
+    }
+
+}

Modified: labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/common/swingui/WorkflowFrame.java
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/common/swingui/WorkflowFrame.java	2009-07-04 16:11:30 UTC (rev 27545)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/common/swingui/WorkflowFrame.java	2009-07-04 16:33:21 UTC (rev 27546)
@@ -7,6 +7,9 @@
 import java.io.File;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.LinkedBlockingQueue;
 import java.util.List;
 import java.util.ArrayList;
 
@@ -22,6 +25,7 @@
 import javax.swing.JScrollPane;
 import javax.swing.SwingUtilities;
 import javax.swing.JProgressBar;
+import javax.swing.JOptionPane;
 import javax.swing.filechooser.FileFilter;
 
 import org.drools.solver.examples.common.business.SolutionBusiness;
@@ -174,7 +178,12 @@
             // This should be replaced with a java 6 SwingWorker once drools's hudson is on JDK 1.6
             solvingExecutor.submit(new Runnable() {
                 public void run() {
-                    solutionBusiness.solve();
+                    try {
+                        solutionBusiness.solve();
+                    } catch (final Throwable e) {
+                        // Otherwise the newFixedThreadPool will eat the exception...
+                        logger.error("Solving failed: " + e.getMessage(), e);
+                    }
                     SwingUtilities.invokeLater(new Runnable() {
                         public void run() {
                             setSolvingState(false);

Copied: labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/pas/solver/move/factory/BedDesignationPillarPartSwitchMoveFactory.java (from rev 27519, labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/pas/solver/move/factory/BedDesignationSwitchMoveFactory.java)
===================================================================
--- labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/pas/solver/move/factory/BedDesignationPillarPartSwitchMoveFactory.java	                        (rev 0)
+++ labs/jbossrules/trunk/drools-solver/drools-solver-examples/src/main/java/org/drools/solver/examples/pas/solver/move/factory/BedDesignationPillarPartSwitchMoveFactory.java	2009-07-04 16:33:21 UTC (rev 27546)
@@ -0,0 +1,193 @@
+package org.drools.solver.examples.pas.solver.move.factory;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+
+import org.drools.solver.core.move.Move;
+import org.drools.solver.core.move.CompositeMove;
+import org.drools.solver.core.move.factory.AbstractMoveFactory;
+import org.drools.solver.core.solution.Solution;
+import org.drools.solver.examples.pas.domain.BedDesignation;
+import org.drools.solver.examples.pas.domain.PatientAdmissionSchedule;
+import org.drools.solver.examples.pas.domain.Bed;
+import org.drools.solver.examples.pas.solver.move.BedChangeMove;
+import org.apache.commons.lang.builder.CompareToBuilder;
+import org.jmock.lib.concurrent.UnsupportedSynchronousOperationException;
+
+/**
+ * @author Geoffrey De Smet
+ */
+public class BedDesignationPillarPartSwitchMoveFactory extends AbstractMoveFactory {
+
+    private boolean checkBedAllowsAdmissionPart = true;
+
+    public List<Move> createMoveList(Solution solution) {
+        PatientAdmissionSchedule patientAdmissionSchedule = (PatientAdmissionSchedule) solution;
+
+        Map<Bed, List<BedDesignation>> bedToBedDesignationList = new HashMap<Bed, List<BedDesignation>>(
+                patientAdmissionSchedule.getBedList().size());
+        for (BedDesignation bedDesignation : patientAdmissionSchedule.getBedDesignationList()) {
+            List<BedDesignation> bedDesignationListPerBed = bedToBedDesignationList.get(bedDesignation.getBed());
+            if (bedDesignationListPerBed == null) {
+                // Note: the initialCapacity is probably to high,
+                // which is bad for memory, but the opposite is bad for performance (which is worse)
+                bedDesignationListPerBed = new ArrayList<BedDesignation>(
+                        patientAdmissionSchedule.getNightList().size());
+                bedToBedDesignationList.put(bedDesignation.getBed(), bedDesignationListPerBed);
+            }
+            bedDesignationListPerBed.add(bedDesignation);
+        }
+        for (List<BedDesignation> bedDesignationListPerBed : bedToBedDesignationList.values()) {
+            Collections.sort(bedDesignationListPerBed, new Comparator<BedDesignation>() {
+                public int compare(BedDesignation a, BedDesignation b) {
+                    // This comparison is sameBedInSameNight safe.
+                    return new CompareToBuilder()
+                            .append(a.getAdmissionPart().getFirstNight(), b.getAdmissionPart().getFirstNight())
+                            .append(a.getAdmissionPart().getLastNight(), b.getAdmissionPart().getLastNight())
+                            .append(a.getAdmissionPart(), b.getAdmissionPart())
+                            .toComparison();
+                }
+            });
+        }
+
+        List<Bed> bedList = patientAdmissionSchedule.getBedList();
+        List<Move> moveList = new ArrayList<Move>();
+
+        // For every 2 distinct beds
+        for (ListIterator<Bed> leftBedIt = bedList.listIterator(); leftBedIt.hasNext();) {
+            Bed leftBed = leftBedIt.next();
+            for (ListIterator<Bed> rightBedIt = bedList.listIterator(leftBedIt.nextIndex());
+                    rightBedIt.hasNext();) {
+                Bed rightBed = rightBedIt.next();
+                List<BedDesignation> leftBedDesignationList = bedToBedDesignationList.get(leftBed);
+                if (leftBedDesignationList == null) {
+                    leftBedDesignationList = Collections.emptyList();
+                }
+                List<BedDesignation> rightBedDesignationList = bedToBedDesignationList.get(rightBed);
+                if (rightBedDesignationList == null) {
+                    rightBedDesignationList = Collections.emptyList();
+                }
+                LowestFirstNightBedDesignationIterator lowestIt = new LowestFirstNightBedDesignationIterator(
+                        leftBedDesignationList, rightBedDesignationList);
+                // For every pillar part duo
+                while (lowestIt.hasNext()) {
+                    BedDesignation pillarPartBedDesignation = lowestIt.next();
+                    // Note: the initialCapacity is probably to high,
+                    // which is bad for memory, but the opposite is bad for performance (which is worse)
+                    List<Move> moveListByPillarPartDuo = new ArrayList<Move>(
+                            leftBedDesignationList.size() + rightBedDesignationList.size());
+                    int minimumLastNightIndex = pillarPartBedDesignation.getAdmissionPart().getLastNight().getIndex();
+                    Bed otherBed = pillarPartBedDesignation.getBed().equals(leftBed) ? rightBed : leftBed;
+                    boolean allBedsAllowAdmissionPart = otherBed.allowsAdmissionPart(
+                            pillarPartBedDesignation.getAdmissionPart());
+                    moveListByPillarPartDuo.add(new BedChangeMove(pillarPartBedDesignation, otherBed));
+                    // For every BedDesignation in that pillar part duo
+                    while (lowestIt.hasNextWithMaximumFirstNightIndex(minimumLastNightIndex)) {
+                        pillarPartBedDesignation = lowestIt.next();
+                        minimumLastNightIndex = Math.max(minimumLastNightIndex,
+                                pillarPartBedDesignation.getAdmissionPart().getLastNight().getIndex());
+                        otherBed = pillarPartBedDesignation.getBed().equals(leftBed) ? rightBed : leftBed;
+                        allBedsAllowAdmissionPart = allBedsAllowAdmissionPart
+                                && otherBed.allowsAdmissionPart(pillarPartBedDesignation.getAdmissionPart());
+                        moveListByPillarPartDuo.add(new BedChangeMove(pillarPartBedDesignation, otherBed));
+                    }
+                    if (allBedsAllowAdmissionPart || !checkBedAllowsAdmissionPart) {
+                        moveList.add(new CompositeMove(moveListByPillarPartDuo));
+                    }
+                }
+            }
+        }
+        return moveList;
+    }
+
+    private class LowestFirstNightBedDesignationIterator implements Iterator<BedDesignation> {
+
+        private Iterator<BedDesignation> leftIterator;
+        private Iterator<BedDesignation> rightIterator;
+
+        private boolean leftHasNext = true;
+        private boolean rightHasNext = true;
+
+        private BedDesignation nextLeft;
+        private BedDesignation nextRight;
+
+        public LowestFirstNightBedDesignationIterator(
+                List<BedDesignation> leftBedDesignationList, List<BedDesignation> rightBedDesignationList) {
+            leftIterator = leftBedDesignationList.iterator();
+            if (leftIterator.hasNext()) {
+                nextLeft = leftIterator.next();
+            } else {
+                leftHasNext = false;
+                nextLeft = null;
+            }
+            rightIterator = rightBedDesignationList.iterator();
+            if (rightIterator.hasNext()) {
+                nextRight = rightIterator.next();
+            } else {
+                rightHasNext = false;
+                nextRight = null;
+            }
+        }
+
+        public boolean hasNext() {
+            return leftHasNext || rightHasNext;
+        }
+
+        public boolean hasNextWithMaximumFirstNightIndex(int maximumFirstNightIndex) {
+            return (leftHasNext
+                    && nextLeft.getAdmissionPart().getFirstNight().getIndex() <= maximumFirstNightIndex)
+                    || (rightHasNext
+                    && nextRight.getAdmissionPart().getFirstNight().getIndex() <= maximumFirstNightIndex);
+        }
+
+        public BedDesignation next() {
+            boolean returnLeft;
+            if (leftHasNext) {
+                if (rightHasNext) {
+                    int leftFirstNightIndex = nextLeft.getAdmissionPart().getFirstNight().getIndex();
+                    int rightFirstNightIndex = nextRight.getAdmissionPart().getFirstNight().getIndex();
+                    returnLeft = leftFirstNightIndex < rightFirstNightIndex;
+                } else {
+                    returnLeft = true;
+                }
+            } else {
+                if (rightHasNext) {
+                    returnLeft = false;
+                } else {
+                    throw new NoSuchElementException();
+                }
+            }
+            BedDesignation lowest;
+            if (returnLeft) {
+                lowest = nextLeft;
+                if (leftIterator.hasNext()) {
+                    nextLeft = leftIterator.next();
+                } else {
+                    leftHasNext = false;
+                    nextLeft = null;
+                }
+            } else {
+                lowest = nextRight;
+                if (rightIterator.hasNext()) {
+                    nextRight = rightIterator.next();
+                } else {
+                    rightHasNext = false;
+                    nextRight = null;
+                }
+            }
+            return lowest;
+        }
+
+        public void remove() {
+            throw new UnsupportedSynchronousOperationException("Remove not supported.");
+        }
+    }
+
+}
\ No newline at end of file




More information about the jboss-svn-commits mailing list