[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