001package org.cpsolver.ifs.example.jobshop;
002
003import java.util.ArrayList;
004import java.util.List;
005
006import org.cpsolver.ifs.model.Variable;
007
008
009/**
010 * Operation. <br>
011 * <br>
012 * Each operation has its number, job, machine and processing time
013 * 
014 * @version IFS 1.3 (Iterative Forward Search)<br>
015 *          Copyright (C) 2006 - 2014 Tomáš Müller<br>
016 *          <a href="mailto:muller@unitime.org">muller@unitime.org</a><br>
017 *          <a href="http://muller.unitime.org">http://muller.unitime.org</a><br>
018 * <br>
019 *          This library is free software; you can redistribute it and/or modify
020 *          it under the terms of the GNU Lesser General Public License as
021 *          published by the Free Software Foundation; either version 3 of the
022 *          License, or (at your option) any later version. <br>
023 * <br>
024 *          This library is distributed in the hope that it will be useful, but
025 *          WITHOUT ANY WARRANTY; without even the implied warranty of
026 *          MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
027 *          Lesser General Public License for more details. <br>
028 * <br>
029 *          You should have received a copy of the GNU Lesser General Public
030 *          License along with this library; if not see
031 *          <a href='http://www.gnu.org/licenses/'>http://www.gnu.org/licenses/</a>.
032 */
033public class Operation extends Variable<Operation, Location> {
034    private Job iJob = null;
035    private Machine iMachine = null;
036    private int iProcessingTime = 0;
037    private int iOperationNumber = 0;
038
039    /**
040     * Constructor
041     * 
042     * @param job
043     *            job
044     * @param machine
045     *            machine
046     * @param operationNumber
047     *            operation number
048     * @param processingTime
049     *            processing time
050     */
051    public Operation(Job job, Machine machine, int operationNumber, int processingTime) {
052        super(null);
053        iJob = job;
054        iMachine = machine;
055        iProcessingTime = processingTime;
056        iOperationNumber = operationNumber;
057    }
058
059    /** Get job 
060     * @return job
061     **/
062    public Job getJob() {
063        return iJob;
064    }
065
066    /** Get job number
067     * @return job number
068     **/
069    public int getJobNumber() {
070        return iJob.getJobNumner();
071    }
072
073    /** Get operation number 
074     * @return operation number
075     **/
076    public int getOperationNumber() {
077        return iOperationNumber;
078    }
079
080    /** Get machine 
081     * @return machine
082     **/
083    public Machine getMachine() {
084        return iMachine;
085    }
086
087    /** Get machine number 
088     * @return machine number
089     **/
090    public int getMachineNumber() {
091        return iMachine.getMachineNumber();
092    }
093
094    /** Get processing time
095     * @return processing time
096     **/
097    public int getProcessingTime() {
098        return iProcessingTime;
099    }
100
101    /** Get the preceding operation (if any)
102     * @return preceding operation
103     **/
104    public Operation getPrecedingOperation() {
105        return (iOperationNumber == 0 ? null : iJob.getOperation(iOperationNumber - 1));
106    }
107
108    /** Get the subsequent operation (if any)
109     * @return subsequent operation
110     **/
111    public Operation getSubsequentOperation() {
112        return (iOperationNumber + 1 == iJob.countOperations() ? null : iJob.getOperation(iOperationNumber + 1));
113    }
114
115    /** Get minimal starting time
116     * @return minimal starting time
117     **/
118    public int getMinStartTime() {
119        if (iOperationNumber == 0)
120            return 0;
121        else
122            return getPrecedingOperation().getMinStartTime() + iProcessingTime;
123    }
124
125    /** Get maximal starting time
126     * @return maximal starting time
127     **/
128    public int getMaxStartTime() {
129        if (iOperationNumber + 1 == iJob.countOperations())
130            return ((JobShopModel) getModel()).getTotalNumberOfSlots() - iProcessingTime;
131        else
132            return getSubsequentOperation().getMaxStartTime() - iProcessingTime;
133    }
134
135    /** Compares two operations -- job number and operation number must match */
136    @Override
137    public boolean equals(Object o) {
138        if (o == null || !(o instanceof Operation))
139            return false;
140        Operation op = (Operation) o;
141        return getJobNumber() == op.getJobNumber() && getOperationNumber() == op.getOperationNumber();
142    }
143
144    /** Initialozation -- fills the variable's domain */
145    public void init() {
146        setValues(computeValues());
147    }
148
149    private List<Location> computeValues() {
150        List<Location> ret = new ArrayList<Location>();
151        for (int i = getMinStartTime(); i <= getMaxStartTime(); i++)
152            ret.add(new Location(this, i));
153        return ret;
154    }
155
156    /** string representation -- for debuging and printing purposes */
157    @Override
158    public String toString() {
159        return getName();
160    }
161
162    /**
163     * Operation's name (e.g., O[2,4] where 2 is the job number and 4 is the
164     * operation number
165     */
166    @Override
167    public String getName() {
168        return "O[" + getJobNumber() + "," + getOperationNumber() + "]";
169    }
170}