// 
// $Log: PhysicalGraph.java,v $
// Revision 1.2  1996/02/27  00:37:00  jaf
// Added comments musing over possible ways to make these data structures
// usable for problem instances where the allowable switch locations are
// a discrete set, or a continuous region.
//
// Revision 1.1  1996/02/26  23:20:42  jaf
// Initial revision
//
// 


// In thinking about how to make this tool easy to adapt to different
// optimizers, it seems that it would be nice to be able to "add
// fields dynamically" to places, conduits, switches, links, etc.  For
// example, an optimizater that always creates a tree structure might
// want to return as part of its result a "parent pointer" for each
// switch, i.e., for each switch, the identity of another switch that
// is its parent in the tree structure.  As another example, we might
// want to make an optimizer some day that takes as input a fixed
// startup cost to use a conduit, which is independent of the number
// of cables that will be placed there.

// It would be foolhardy to try to include all such fields in the
// class at the beginning of development on this tool.  It could be
// pandemonium to continually add new ones, and recompile things
// frequently.

// An elegant solution is to associate a "property list" with each
// such extensible object.  Then the GUI would have a way to create a
// new field for every conduit, called "StartupCost", which is a
// floating point number.  The user could specify a different number
// for each conduit, and then when running the optimizer which uses
// this value, they could tell the optimizer to look in the property
// named "StartupCost" to find this value.  Similarly, the optimizer
// that produces a tree network result could be told (before executing
// it), to place the identity of the parent switch of each node into a
// property named "Parent".

// It would be convenient if each such optimizer had default property
// names that they used, with explanatory names.  It could also be
// useful to allow the user to change the property name used.  In this
// way, they could have different sets of values stored in the same
// design under different property names, and choose which one was
// used when starting an optimizer.

// Each optimizer might have its own internal data structures that it
// uses, instead of the one presented here, which will most likely not
// need this extensibility feature.  They would copy the properties
// needed from the extensible classes into their local data
// structures, run the optimization algorithm, and then copy any local
// results back into specified properties of these extensible classes.

// The GUI would be able to display the values of all of these
// properties in a window when clicking on a switch or link, and it
// might also have nice built-in ways to display certain kinds of
// properties.  For example, the GUI might be instructed to display
// "parent pointer arrows" based on the value in the "Parent" property
// of each switch.

// The scheme above is good for representing fairly simple data about
// a single object, but probably wouldn't be good at representing more
// complex relationships between objects like traffic requirements (in
// their most general form as constraints on the traffic between a
// pair of place sets), but hopefully most of these more complex
// relationships will be built into the data structures from the
// start.

// As far as Java implementation goes, there is a class called
// Hashtable in the java.util package that looks perfect for the job.
// It maps arbitrary objects to other objects.  We can use it to map
// strings (i.e., property names) to arbitrary objects.

// There is also a class called Properties that has nice methods for
// printing out its contents as text, and initializing its value by
// reading in a printed representation.  It would be nice to create
// such methods for our property lists, to make it easy to save and
// load files in the program.  Perhaps we should make a new subclass
// of Hashtable that adds these methods.  I'll use the name
// GeneralProperties for now, since it is similar in idea to the
// Properties class, but it doesn't restrict you to map from and to
// objects of type String.  We might want to restrict it to map from
// and to some interface type that has read and print methods, perhaps
// called IOable ("input/output-able").

// I'd also like to make a subclass of HashTable called Set, just so
// it has a name that is the way we intend to use it.

// The previous version of this file checked in is somewhat biased
// towards representing problems with a "discrete physical graph", in
// which there is a discrete set of places where switches can be
// installed.  It would be nice if the same data structure were useful
// for those kinds of problem instances, as well as ones in which
// switches can be installed anywhere in the plane (anywhere in
// n-dimensional Euclidean space seems a bit like overkill, even for
// n=3).

// One possible way to achieve this is to generalize the notion of a
// place from a single point in the plane to a region in the plane.
// Then a Euclidean instance would just have one big place, which is
// the whole plane, and switches may be placed anywhere inside of it.
// The discrete version can be represented by making the region
// associated with a place one discrete point.

// In such a Euclidean instance, where there is one Place containing
// the whole plane (or, more likely, a large portion of the plane,
// outside of which it wouldn't make sense to put switches), we need a
// way to specify where the sources and sinks of traffic are.  This
// could be done by creating "discrete places" for these points, and
// then the "region place" where switches may be placed contains a
// large rectangular region in the plane.

// Note that such an instance has _no_ conduits.  When a place
// contains a region, it is assumed that multiple switches may be put
// inside of it, and they are connected by straight-line links, using
// the Euclidean distance between them.

// What if we _wanted_ to have multiple Places, where each was a
// rectangular region in the plane that didn't overlap any of the
// others, and there were conduits between them.  In this case, we
// need to know more about where the conduit is physically located in
// relationship to the Place.  I won't include code that could specify
// such a situation yet, but we might want to plan it for the future.




// A Place might be somewhere that a switch can be installed, such as
// a communications closet or computer room, or it might just be
// somewhere that cables can be routed through, to which more than two
// Conduit's are incident, such as a "T" intersection in a tunnel.

// Note: In the GUI, we might want to associate an icon with the
// Place, which could be different from one Place to another.

// SwitchAllowed is true iff a switch may be installed in the Place.
// I can imagine wanting to make this more general, like a number of
// switches that can be installed at the Place (0 if none allowed).

// It seems reasonable to make the name and coordinates be in every
// instance of the Place data sturcture, but SwitchAllowed seems more
// natural to put into the extensible part.

class Place {
	String name;

	// "Discrete" version: switch put in this Place must be at
	// these coordinates.
	float x,y;

	// "Continuous" version: switch put in this Place can be at
	// any x,y coordinates that fall in the Region reg.
	Region reg;

	GeneralProperties prop;
}



// A Conduit is any location where a cable may be installed.  It
// connects two Place's, arbitrarily denoted l and r, for left and
// right.  It has a length, which is at least as large as the
// straight-line distance between the two Place's, but could be larger
// (e.g., a Conduit between two Place's might make several right-angle
// turns).

// In a GUI, it would perhaps be nifty to represent a Conduit by
// something other than just a straight line between them.  For
// example, a steam tunnel between two buildings might not be a
// straight line.  This is not a high-priority item on my list of
// things to implement, however.

// The installation cost seems like a reasonable thing to add, even if
// most algorithms we develop never use it.  It is the fixed cost of
// laying any cable at all on the path, e.g., trench-digging cost,
// right-of-way cost.

// Fixed part: name, l, r, length
// Extensible part: install_cost

// Possibility to add in the future: a way to specify more about the
// geometry of the conduit, when the Place's that it connects are
// regions within the plane, instead of only discrete points.

class Conduit {
	String name;
	Place l, r;
	float length;
	GeneralProperties prop;
}



// A PlaceSet is just a named collection of Place's and (optionally)
// other PlaceSet's.  It could be used to help specify traffic
// constraints, or just as a convenient way to group a set of Place's
// in the GUI.

// It would be nice when specifying traffic to have an easy way to
// take the complement of a PlaceSet.  One way to do this would be to
// automatically create a PlaceSet called "everything but X" every
// time a PlaceSet called "X" is created or modified.  Just a thought.
// There may be a better way.

class PlaceSet {
	String name;  // e.g., "Engineering School", "Computer Science"
	set of Place's and/or PlaceSet's.
	GeneralProperties prop;
}



// A PhysicalGraph is a collection of Place's, some pairs of which are
// connected by Conduit's.  When installing a new cable between a pair
// of Place's, we assume that we always take the shortest path in the
// PhysicalGraph between those two Place's.

// I've also stuck in a set of PlaceSet's here, just because someone
// who created a PhysicalGraph using the GUI would probably want to
// save the PlaceSet's with it.  This doesn't mean they have to be
// members of the same class, but it seems reasonable to do so.

// GUI note: we'd like also to have things that JST suggested like a
// scale parameter with a unit name, and a background image.  These
// might better be placed somewhere else than in the PhysicalGraph
// class.

class PhysicalGraph {
	Set places;
	Set conduits;
	Set placeSets;
	GeneralProperties prop;
}



// A single set pair constraint specifies the maximum traffic that may
// be simultaneously present from all nodes in set a to all nodes in
// set b.

class SetPairConstraint {
	PlaceSet a, b;
	float limit;
}



// Traffic requirements are an arbitrary collection of
// SetPairConstraint's.  Such a collection is general enough to
// specify alpha,omega type constraints, both for individual nodes and
// for sets of nodes, and it can specify a constraint from one node
// (or set of nodes) to another single node (or set of nodes), thus
// giving a "traffic matrix" style of specification.  You can also mix
// and match these two styles.

class TrafficRequirements {
	Set setPairConstraints;
}



// A LinkType would be something like "2.4 Gb/s link", with a raw
// capacity of 2400 (if expressed in Mb/s), a termination cost of
// $7000, and a cost per unit distance of whatever a single multi-mode
// fiber costs, plus perhaps installation costs.  Accurately modeling
// installation costs could be a nightmare, or even modeling the
// different kinds of multi-fiber cables commercially available.

class LinkType {
	String name;
	float rawCapacity;
	float terminationCost;
	float costPerUnitDistance;
	GeneralProperties prop;
}
