001 package net.sf.cpsolver.studentsct.model; 002 003 import java.util.Enumeration; 004 import java.util.HashSet; 005 import java.util.Vector; 006 007 /** 008 * Representation of a scheduling subpart. Each scheduling subpart contains id, instructional type, name, 009 * instructional offering configuration, and a list of sections. Optionally, parent-child relation between 010 * subparts can be defined. 011 * <br><br> 012 * 013 * @version 014 * StudentSct 1.1 (Student Sectioning)<br> 015 * Copyright (C) 2007 Tomáš Müller<br> 016 * <a href="mailto:muller@unitime.org">muller@unitime.org</a><br> 017 * Lazenska 391, 76314 Zlin, Czech Republic<br> 018 * <br> 019 * This library is free software; you can redistribute it and/or 020 * modify it under the terms of the GNU Lesser General Public 021 * License as published by the Free Software Foundation; either 022 * version 2.1 of the License, or (at your option) any later version. 023 * <br><br> 024 * This library is distributed in the hope that it will be useful, 025 * but 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. 028 * <br><br> 029 * You should have received a copy of the GNU Lesser General Public 030 * License along with this library; if not, write to the Free Software 031 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 032 */ 033 public class Subpart implements Comparable { 034 private long iId = -1; 035 private String iInstructionalType = null; 036 private String iName = null; 037 private Vector iSections = new Vector(); 038 private Config iConfig = null; 039 private Subpart iParent = null; 040 041 /** Constructor 042 * @param id scheduling subpart unique id 043 * @param itype instructional type 044 * @param name subpart name 045 * @param config instructional offering configuration to which this subpart belongs 046 * @param parent parent subpart, if parent-child relation is defined between subparts 047 */ 048 public Subpart(long id, String itype, String name, Config config, Subpart parent) { 049 iId = id; 050 iInstructionalType = itype; 051 iName = name; 052 iConfig = config; 053 iParent = parent; 054 iConfig.getSubparts().addElement(this); 055 } 056 057 /** Subpart id */ 058 public long getId() { 059 return iId; 060 } 061 062 /** Instructional type, e.g., Lecture, Recitation or Laboratory */ 063 public String getInstructionalType() { 064 return iInstructionalType; 065 } 066 067 /** Subpart name */ 068 public String getName() { 069 return iName; 070 } 071 072 /** Instructional offering configuration to which this subpart belongs */ 073 public Config getConfig() { 074 return iConfig; 075 } 076 077 /** List of sections */ 078 public Vector getSections() { 079 return iSections; 080 } 081 082 /** Parent subpart, if parent-child relation is defined between subparts */ 083 public Subpart getParent() { 084 return iParent; 085 } 086 087 public String toString() { 088 return getName(); 089 } 090 091 /** True, if this subpart is parent (or parent of a parent etc.) of the given subpart */ 092 public boolean isParentOf(Subpart subpart) { 093 if (subpart.getParent()==null) return false; 094 if (subpart.getParent().equals(this)) return true; 095 return isParentOf(subpart.getParent()); 096 } 097 098 /** Compare two subparts: put parents first, use ids if there is no parent-child relation*/ 099 public int compareTo(Object o) { 100 if (o==null || !(o instanceof Subpart)) { 101 return -1; 102 } 103 Subpart s = (Subpart)o; 104 if (isParentOf(s)) return -1; 105 if (s.isParentOf(this)) return 1; 106 int cmp = getInstructionalType().compareTo(s.getInstructionalType()); 107 if (cmp!=0) return cmp; 108 return Double.compare(getId(),s.getId()); 109 } 110 111 /** List of available choices of the sections of this subpart. */ 112 public HashSet getChoices() { 113 HashSet choices = new HashSet(); 114 for (Enumeration e=getSections().elements();e.hasMoreElements();) { 115 choices.add(((Section)e.nextElement()).getChoice()); 116 } 117 return choices; 118 } 119 120 /** Minimal penalty from {@link Section#getPenalty()} */ 121 public double getMinPenalty() { 122 double min = Double.MAX_VALUE; 123 for (Enumeration e=getSections().elements();e.hasMoreElements();) { 124 Section section = (Section)e.nextElement(); 125 min = Math.min(min, section.getPenalty()); 126 } 127 return (min==Double.MAX_VALUE?0.0:min); 128 } 129 130 /** Maximal penalty from {@link Section#getPenalty()} */ 131 public double getMaxPenalty() { 132 double max = Double.MIN_VALUE; 133 for (Enumeration e=getSections().elements();e.hasMoreElements();) { 134 Section section = (Section)e.nextElement(); 135 max = Math.max(max, section.getPenalty()); 136 } 137 return (max==Double.MIN_VALUE?0.0:max); 138 } 139 140 /** Return children subparts*/ 141 public Vector getChildren() { 142 Vector ret = new Vector(getConfig().getSubparts().size()); 143 for (Enumeration e=getConfig().getSubparts().elements();e.hasMoreElements();) { 144 Subpart s = (Subpart)e.nextElement(); 145 if (this.equals(s.getParent())) ret.add(s); 146 } 147 return ret; 148 } 149 }