001    package ifs.example.jobshop;
002    
003    import ifs.model.*;
004    import java.util.*;
005    
006    /**
007     * Operation.
008     * <br><br>
009     * Each operation has its number, job, machine and processing time
010     *
011     * @author <a href="mailto:muller@ktiml.mff.cuni.cz">Tomáš Müller</a>
012     * @version 1.0
013     */
014    public class Operation extends Variable {
015        private Job iJob = null;
016        private Machine iMachine = null;
017        private int iProcessingTime = 0;
018        private int iOperationNumber = 0;
019        
020        /**
021         * Constructor
022         * @param job job
023         * @param machine machine
024         * @param operationNumber operation number
025         * @param processingTime processing time
026         */
027        public Operation(Job job, Machine machine, int operationNumber, int processingTime) {
028            super(null);
029            iJob = job;
030            iMachine = machine;
031            iProcessingTime = processingTime;
032            iOperationNumber = operationNumber;
033        }
034        
035        /** Get job */
036        public Job getJob() { return iJob; }
037        
038        /** Get job number */
039        public int getJobNumber() { return iJob.getJobNumner(); }
040        
041        /** Get operation number */
042        public int getOperationNumber() { return iOperationNumber; }
043        
044        /** Get machine */
045        public Machine getMachine() { return iMachine; }
046        
047        /** Get machine number */
048        public int getMachineNumber() { return iMachine.getMachineNumber(); }
049        
050        /** Get processing time */
051        public int getProcessingTime() { return iProcessingTime; }
052        
053        /** Get the preceeding operation (if any) */
054        public Operation getPrecedingOperation() { return (iOperationNumber==0?null:iJob.getOperation(iOperationNumber-1)); }
055        
056        /** Get the subsequent operation (if any) */
057        public Operation getSubsequentOperation() { return (iOperationNumber+1==iJob.countOperations()?null:iJob.getOperation(iOperationNumber+1)); }
058        
059        /** Get minimal starting time */
060        public int getMinStartTime() {
061            if (iOperationNumber==0) return 0;
062            else return getPrecedingOperation().getMinStartTime()+iProcessingTime;
063        }
064        
065        /** Get maximal starting time */
066        public int getMaxStartTime() {
067            if (iOperationNumber+1==iJob.countOperations()) return ((JobShopModel)getModel()).getTotalNumberOfSlots()-iProcessingTime;
068            else return getSubsequentOperation().getMaxStartTime()-iProcessingTime;
069        }
070        
071        /** Compares two operations -- job number and operation number must match */
072        public boolean equals(Object o) {
073            if (o==null || !(o instanceof Operation)) return false;
074            Operation op = (Operation)o;
075            return getJobNumber()==op.getJobNumber() && getOperationNumber()==op.getOperationNumber();
076        }
077        
078        /** Initialozation -- fills the variable's domain */
079        public void init() {
080            setValues(computeValues());
081        }
082        
083        private Vector computeValues() {
084            Vector ret = new Vector();
085            for (int i=getMinStartTime();i<=getMaxStartTime();i++)
086                ret.addElement(new Location(this,i));
087            return ret;
088        }
089        
090        /** string representation -- for debuging and printing purposes */
091        public String toString() { return getName(); }
092    
093        /** Operation's name (e.g., O[2,4] where 2 is the job number and 4 is the operation number */
094        public String getName() { return "O["+getJobNumber()+","+getOperationNumber()+"]"; }
095    }