diff --git a/ea/ub8/EAUe8HohlochMutschler.zip b/ea/ub8/EAUe8HohlochMutschler.zip
new file mode 100644
index 0000000..a667262
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler.zip
Binary files differ
diff --git a/ea/ub8/EAUe8HohlochMutschler/ea8.pdf b/ea/ub8/EAUe8HohlochMutschler/ea8.pdf
new file mode 100644
index 0000000..798f6f3
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/ea8.pdf
Binary files differ
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/.classpath b/ea/ub8/EAUe8HohlochMutschler/framework/.classpath
new file mode 100644
index 0000000..233be1d
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/.classpath
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/.project b/ea/ub8/EAUe8HohlochMutschler/framework/.project
new file mode 100644
index 0000000..8f7872d
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/.project
@@ -0,0 +1,17 @@
+
+
+ EAUe8
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/.gitignore b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/.gitignore
new file mode 100644
index 0000000..90e21ff
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/.gitignore
@@ -0,0 +1,19 @@
+/DAequiDistPoints.class
+/DArea.class
+/DComponent.class
+/DContainer.class
+/DCountingPeak.class
+/DElement.class
+/DFunction.class
+/DGrid.class
+/DImage.class
+/DLine.class
+/DMeasures.class
+/DMouseZoom.class
+/DParent.class
+/DPeakSet.class
+/DPoint.class
+/DPointSet.class
+/DRectangle.class
+/PagePrinter.class
+/ScaledBorder.class
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DAequiDistPoints.java b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DAequiDistPoints.java
new file mode 100644
index 0000000..f634eb9
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DAequiDistPoints.java
@@ -0,0 +1,155 @@
+package DDrawing;
+
+
+import java.awt.Color;
+import java.awt.Graphics;
+import java.awt.Point;
+
+
+/**
+ * DAequiDistPoints represents a special kind of DPointSet with constant x-distance between the points
+ */
+public class DAequiDistPoints extends DComponent{
+ protected double minX;
+ protected double distance;
+ protected double[] y;
+ protected int size = 0;
+ protected boolean connected = false;
+
+ /**
+ * minX is the start-x-value for the set,
+ * distance the constant x-distance
+ */
+ public DAequiDistPoints( double minX, double distance ){
+ this( minX, distance, 10 );
+ }
+
+ /**
+ * minX is the start-x-value for the set,
+ * distance the constant x-distance,
+ * initial-capacity of the array
+ */
+ public DAequiDistPoints( double minX, double distance, int initial_capacity ){
+ this.minX = minX;
+ this.distance = distance;
+ y = new double[ initial_capacity ];
+ }
+
+ /**
+ * paints the points in the DContainer
+ *
+ * @param m DMeasures contains information about the current size
+ * of the parent
+ */
+ public void paint( DMeasures m ){
+ Graphics g = m.getGraphics();
+ Color old_color = g.getColor();
+ if( color != null ) g.setColor( color );
+ else g.setColor( DEFAULT_COLOR );
+ if( connected && size > 1 ){
+ Point p1, p2;
+ p1 = m.getPoint( x(0), y[0] );
+ for( int i=1; i this.y.length ){
+ int oldL = this.y.length;
+ double[] newV = new double[ oldL * 2 ];
+ System.arraycopy( this.y, 0, newV, 0, oldL );
+ this.y = newV;
+ }
+
+ this.y[ size - 1 ] = y;
+
+ if( size == 1 ) rectangle = new DRectangle( minX, y, 0, 0 );
+ else rectangle.insert( new DPoint( minX + (size-1) * distance, y ) );
+
+ repaint();
+ }
+
+ /**
+ * adds a few values to the existing, calls the parent to repaint
+ *
+ * @param newy new y-values
+ */
+ public void addValues( double[] newy ){
+ if( newy.length == 0 ) return;
+
+ double min = newy[0], max = newy[0];
+ for( int i=0; i max ) max = newy[i];
+
+ if( size + newy.length > y.length ){
+ double[] newV = new double[ size + newy.length ];
+ System.arraycopy( y, 0, newV, 0, size );
+ y = newV;
+ }
+
+ System.arraycopy( newy, 0, y, size, newy.length );
+
+ if( size == 0 ) rectangle = new DRectangle( minX, min, (newy.length-1) * distance, max - min );
+ else {
+ rectangle.insert( new DPoint( minX, min ) );
+ rectangle.insert( new DPoint( minX + (size+newy.length-1) * distance, max ) );
+ }
+
+ size += newy.length;
+
+ repaint();
+ }
+
+ /**
+ * sets the points connected or disconnected, means that either there is a
+ * line drawn between them or not
+ *
+ * @param aFlag if the points are connected by lines
+ */
+ public void setConnected( boolean aFlag ){
+ boolean changed = !( aFlag == connected );
+ connected = aFlag;
+ if( changed ) repaint();
+ }
+
+ /**
+ * removes all points of the array
+ */
+ public void removeAllPoints(){
+ size = 0;
+ repaint();
+ rectangle = DRectangle.getEmpty();
+ }
+
+ /**
+ * returns the current number of points
+ *
+ * @return the number of points
+ */
+ public int size(){ return size; }
+
+ public DPoint getDPoint( int no ){
+ if( no >= size ) return null;
+ return new DPoint( x(no), y[no] );
+ }
+
+ protected double x( int i ){ return minX + distance * i; }
+}
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DArea.java b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DArea.java
new file mode 100644
index 0000000..5535bea
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DArea.java
@@ -0,0 +1,379 @@
+package DDrawing;
+
+
+import java.awt.*;
+import java.awt.image.BufferedImage;
+import java.awt.print.*;
+import java.util.Vector;
+import javax.swing.*;
+import javax.swing.border.Border;
+
+/**
+ * DArea is the junktion of the JComponents and the DComponents. It's the DParent which can be added to JComponents
+ */
+public class DArea extends JComponent implements DParent, Printable{
+
+ /**
+ * the default minimal rectangle which is shown
+ */
+ public static final DRectangle DEFAULT_MIN_RECT = new DRectangle(-1, -1, 2, 2);
+
+ private DContainer container;
+
+ /**
+ * min_rectangle is set, when all elements are removed
+ * visible_rect is the currently visible rectangle
+ */
+ protected DRectangle min_rect = DEFAULT_MIN_RECT ;
+ /**
+ * min_rectangle is set, when all elements are removed
+ * visible_rect is the currently visible rectangle
+ */
+ protected DRectangle visible_rect = DEFAULT_MIN_RECT ;
+
+ /**
+ * whether there is a grid gris is or not
+ */
+ private DGrid grid;
+ private boolean auto_focus = false ;
+ private boolean auto_grid = false ;
+ private boolean grid_to_front = false ;
+
+ /**
+ * maximal number of grid lines
+ */
+ private int max_grid = 10;
+
+ private DMeasures measures;
+
+ /**
+ * initializes the DArea with the initial capacity of 10 components
+ */
+ public DArea(){
+ this( 10 );
+ }
+
+ /**
+ * initializes the DArea with the specialized initial capacity of components
+ * (@see java.util.Vector)
+ *
+ * @param the initial capacity
+ */
+ public DArea( int initial_capacity ){
+ container = new DContainer();
+ container.setDParent( this );
+ grid = new DGrid( visible_rect, 1, 1 );
+ grid.setVisible( false );
+ grid.setDParent( this );
+ measures = new DMeasures( this );
+ }
+
+ /**
+ * returns the currently visible rectangle in DArea coordinates
+ *
+ * @return DRectangle the size and position of the visible area
+ */
+ public DRectangle getDRectangle(){
+ return (DRectangle)visible_rect.clone();
+ }
+
+ /**
+ * switches the auto focus of this DArea on or off
+ *
+ * @param b on or off
+ */
+ public void setAutoFocus( boolean b ){
+ boolean old = auto_focus;
+ auto_focus = b;
+ if( old != b ) repaint();
+ }
+
+ /**
+ * returns whether the DArea's auto focus is on or not
+ *
+ * @return true or false
+ */
+ public boolean isOnAutoFocus(){ return auto_focus; }
+
+ /**
+ * sets the visible rectangle to this size
+ *
+ * @param x the x coordinate of the left border
+ * @param y the y coordinate of the bottom border
+ * @param width the width of the area
+ * @param height the height of the area
+ */
+ public void setVisibleRectangle( double x, double y, double width, double height ){
+ //System.out.println("DArea.setVisibleRectangle(...)");
+ setVisibleRectangle( new DRectangle( x, y, width, height ) );
+ }
+
+ /**
+ * sets the visible rectangle
+ *
+ * @param rect the visible DRectangle in DArea coordinates
+ */
+ public void setVisibleRectangle( DRectangle rect ){
+ //System.out.println("DArea.setVisibleRectangle(DRectangle)");
+ if( rect == null || rect.isEmpty() ) rect = (DRectangle)min_rect.clone();
+ if( !rect.equals( visible_rect ) && rect.width > 0 && rect.height > 0 ){
+ auto_focus = false;
+ visible_rect = (DRectangle)rect.clone();
+ repaint();
+ }
+ }
+
+ /**
+ * sets the minimal rectangle
+ *
+ * @param x
+ * @param y
+ * @param width
+ * @param height
+ */
+ public void setMinRectangle( double x, double y, double width, double height ){
+ setMinRectangle( new DRectangle( x, y, width, height ) );
+ }
+
+ /**
+ * sets the minimal rectangle
+ *
+ * @param rect the visible DRectangle in DArea coordinates
+ */
+ public void setMinRectangle( DRectangle rect ){
+ if( rect == null || rect.isEmpty() ) min_rect = DEFAULT_MIN_RECT;
+ else min_rect = (DRectangle)rect.clone();
+ }
+
+ /**
+ * paints the DArea by a Graphics object
+ *
+ * @param g the java.awt.Graphics object
+ */
+ public void paint( Graphics g ){
+ //System.out.println("DArea.paint(Graphics)");
+ if( auto_focus ) {
+ container.restore();
+ visible_rect = (DRectangle)container.getRectangle().clone();
+ }
+ if( visible_rect.isEmpty() ) visible_rect = (DRectangle)min_rect.clone();
+ super.paint( g );
+
+ measures.setGraphics( g );
+ if( grid.isVisible() && !grid_to_front ) paintGrid( measures );
+ paintElements( measures );
+ if( grid.isVisible() && grid_to_front ) paintGrid( measures );
+ }
+
+ /**
+ * repaints a part of the visible area
+ *
+ * @param r the rectangle to repaint
+ */
+ public void repaint( DRectangle r ){
+ //System.out.println("DArea.repaint(DRectangle)");
+ if( r == null ) throw
+ new IllegalArgumentException("Cannot repaint a null DRectangle");
+ if( r.isAll() || auto_focus ) repaint();
+ else{
+ Point p1 = measures.getPoint( r.x, r.y ),
+ p2 = measures.getPoint( r.x + r.width, r.y + r.height);
+ super.repaint( p1.x, p2.y, p2.x - p1.x + 1, p1.y - p2.y + 1);
+ }
+ }
+
+ /**
+ * adds a new component to the area
+ *
+ * @param e the new DElement
+ */
+ public void addDElement( DElement e ){
+ container.addDElement( e );
+ }
+
+ /**
+ * removes a certain element from the area
+ *
+ * @param e the element to remove
+ */
+ public boolean removeDElement( DElement e ){
+ return container.removeDElement( e );
+ }
+
+ /**
+ * removes all elements from the area
+ */
+ public void removeAllDElements(){
+ visible_rect = (DRectangle)min_rect.clone();
+ container.removeAllDElements();
+ }
+
+ /**
+ * sets the grid visible or not
+ *
+ * @param aFlag visible or not
+ */
+ public void setGridVisible( boolean aFlag ){
+ grid.setVisible( aFlag );
+ }
+
+ /**
+ * returns if the grid is visible
+ * true if the grid is visible or false if not
+ *
+ * @return true or false
+ */
+ public boolean isGridVisible(){
+ return grid.isVisible();
+ }
+
+ /**
+ * sets the grid to the front
+ * that means that the grid is painted as last element
+ * default value is false
+ *
+ * @param aFlag grid t front or not
+ */
+ public void setGridToFront( boolean aFlag ){
+ boolean old = grid_to_front;
+ grid_to_front = aFlag;
+ if( old != aFlag && grid.isVisible() ) repaint();
+ }
+
+ /**
+ * sets the grid's horizontal and vertical distance
+ * that means that the grid's lines will have these distances
+ * in area coordinates
+ *
+ * @param hor_dist the horizontal distance
+ * @param ver_dist the vertical distance
+ */
+ public void setGrid( double hor_dist, double ver_dist ){
+ grid = new DGrid( visible_rect, hor_dist, ver_dist );
+ grid.setDParent( this );
+ auto_grid = false;
+ repaint();
+ }
+
+ /**
+ * sets tha auto grid on or off
+ * if it's on, the grid's distances (@see #setGrid(double, double))
+ * are automatically calculated that it looks pretty nice
+ *
+ * @param b auto grid on or not
+ */
+ public void setAutoGrid( boolean b ){
+ if( b ) grid.setVisible( true );
+ if( b == auto_grid ) return;
+ auto_grid = b;
+ repaint();
+ }
+
+ /**
+ * returns if the auto grid is switched on
+ *
+ * @return true if the grid is on, else false
+ */
+ public boolean hasAutoGrid(){ return auto_grid; }
+
+ /**
+ * sets the color of the grid
+ *
+ * @param java.awt.Color
+ */
+ public void setGridColor( Color color ){
+ grid.setColor( color );
+ }
+
+ /**
+ * sets the maximal number of grid lines
+ * default value is 10
+ *
+ * @param no maximal number of grid lines
+ */
+ public void setMaxGrid( int no ){
+ if( no < 1 ) return;
+ int old = max_grid;
+ max_grid = no;
+ if( old != no ) repaint();
+ }
+
+ /**
+ * prints the area and it's content
+ * @see java.awt.print.Printable and
+ * @see java.awt.print.PrintJob
+ *
+ * @param g the Graphics object
+ * @param pf the @see java.awt.print.PageFormat
+ * @param pi the page index
+ *
+ * @return int @see java.awt.print.Printable
+ */
+ public int print( Graphics g, PageFormat pf, int pi ){
+ //System.out.println("DArea.print(...)");
+ if( pi > 0 ) return Printable.NO_SUCH_PAGE;
+
+ Border sb = getBorder();
+ if( !(sb instanceof ScaledBorder) ) sb = null;
+ else ( (ScaledBorder)sb ).show_outer_border = false;
+ PagePrinter printer = new PagePrinter( this, g, pf );
+ int ret = printer.print();
+ if( sb != null ) ( (ScaledBorder)sb ).show_outer_border = true;
+ return ret;
+ }
+
+ public void setXScale( DFunction x_s ){
+ if( x_s == null && measures.x_scale == null ) return;
+ measures.x_scale = x_s;
+ repaint();
+ }
+
+ public void setYScale( DFunction y_s ){
+ if( y_s == null && measures.y_scale == null ) return;
+ measures.y_scale = y_s;
+ repaint();
+ }
+
+ public DMeasures getDMeasures(){
+ return measures;
+ }
+
+ /**
+ * method paints the grid
+ * how the method paints the grid depends on whether the area is wrapped in a
+ * ScaledBorder or not and on the auto_grid option
+ */
+ private void paintGrid( DMeasures m ){
+ //System.out.println("DArea.paintGrid(Measures)");
+ grid.rectangle = visible_rect;
+ if( auto_grid ){
+ Border border = getBorder();
+ if( border instanceof ScaledBorder ){
+ ScaledBorder sb = (ScaledBorder)border;
+ FontMetrics fm = m.getGraphics().getFontMetrics();
+ Dimension d = getSize();
+ DRectangle r = measures.getSourceOf( visible_rect );
+ grid.hor_dist = sb.getSrcdX(fm, d, r.x, r.x + r.width);
+ grid.ver_dist = sb.getSrcdY(fm, d, r.y, r.y + r.height);
+ }
+ else{
+ grid.hor_dist = ScaledBorder.aBitBigger( visible_rect.width / max_grid );
+ grid.ver_dist = ScaledBorder.aBitBigger( visible_rect.height / max_grid );
+ }
+ }
+ grid.paint( m );
+ }
+
+ /**
+ * this method asks the elements to paint themselves in the area if they
+ * really lie in it and if they are visible
+ */
+ private void paintElements( DMeasures m ){
+ //System.out.println("DArea.paintElements(Measures)");
+ for( int i=0; iDComponent is the mother of all objects which can be displayed by a DArea object, even when it would be also enough to implement the DElement interface to an class DComponent is abstract because the paint method has to be overridden
+ */
+public abstract class DComponent implements DElement{
+ protected Color color;
+ protected DRectangle rectangle;
+ protected DParent parent;
+ private boolean visible = true;
+
+ DComponent(boolean is_rect){}
+
+ public DComponent(){ rectangle = DRectangle.getEmpty(); }
+
+ /**
+ * returns the rectangle in which the object lies
+ */
+ public DRectangle getRectangle(){
+ //if( rectangle == null ) rectangle = new DRectangle( DRectangle.EMPTY );
+ return (DRectangle)rectangle.clone();
+ }
+
+ /**
+ * sets the parent of the component, which should take care of painting the
+ * component to the right time
+ */
+ public void setDParent( DParent parent ){
+ if( this.parent != null && this.parent != parent ){
+ this.parent.removeDElement( this );
+ this.parent.repaint( getRectangle() );
+ }
+ this.parent = parent;
+ }
+
+ /**
+ * returns the parent of the component
+ */
+ public DParent getDParent(){ return parent; }
+
+ /**
+ * invoces the parent to repaint the rectangle in which the component lies
+ */
+ public void repaint(){
+ //System.out.println("DComponent.repaint()");
+ if( parent != null ) parent.repaint( getRectangle() );
+ }
+
+ /**
+ * sets the color of the component
+ */
+ public void setColor( Color color ){
+ if( this.color == null || !color.equals( this.color ) ) {
+ this.color = color;
+ repaint();
+ }
+ }
+
+ /**
+ * returns the color of the component
+ */
+ public Color getColor(){ return color; }
+
+ /**
+ * sets the component visible or not
+ */
+ public void setVisible( boolean aFlag ){
+ boolean changed = ( aFlag != visible );
+ visible = aFlag;
+ if( changed ) repaint();
+ }
+
+ /**
+ * returns if the component should be visible when the parent shows the right
+ * area
+ */
+ public boolean isVisible(){ return visible; }
+
+}
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DContainer.java b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DContainer.java
new file mode 100644
index 0000000..4fa471d
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DContainer.java
@@ -0,0 +1,94 @@
+package DDrawing;
+
+
+import java.util.Vector ;
+
+
+public class DContainer extends DComponent implements DParent{
+ Vector elements = new Vector();
+
+// implementing DParent:
+ public void repaint( DRectangle r ){
+ DParent parent = getDParent();
+ if( parent != null ) parent.repaint( r );
+ }
+
+ public void addDElement( DElement e ){
+ if( elements.contains( e ) ) return;
+ if( e instanceof DParent ){
+ DParent he = (DParent)e, me = (DParent)this;
+ if( he == me ) throw new
+ IllegalArgumentException("Adding DParent to itself");
+ me = getDParent();
+ while( me != null ){
+ if( he == me )throw new
+ IllegalArgumentException("Adding DContainer's parent to itself");
+ if( me instanceof DElement )
+ me = ((DElement)me).getDParent();
+ else me = null;
+ }
+ }
+ elements.add( e );
+ e.setDParent( this );
+ DRectangle r = e.getRectangle();
+ if( r != null ){
+ adjustRect( r );
+ if( e.isVisible() ) repaint( r );
+ }
+ }
+
+ public boolean removeDElement( DElement e ){
+ if( elements.removeElement( e ) ){
+ repaint( e.getRectangle() );
+ restore();
+ return true;
+ }
+ return false;
+ }
+
+ public void removeAllDElements(){
+ elements.removeAllElements();
+ rectangle = null;
+ repaint();
+ }
+
+// implementing DComponent:
+ public void paint( DMeasures m ){
+ DElement e;
+ for( int i=0; iDMeasures object to paint the grid
+ */
+ public void paint( DMeasures m ){
+ Graphics g = m.getGraphics();
+ Color old_color = g.getColor();
+ if( color != null ) g.setColor( color );
+ else g.setColor( DEFAULT_COLOR );
+ double minX, minY, pos;
+ DPoint p1, p2;
+ DLine l;
+
+ minX = (int)( rectangle.x / hor_dist );
+ if( minX * hor_dist <= rectangle.x ) minX++;
+ minX *= hor_dist;
+ minY = (int)( rectangle.y / ver_dist );
+ if( minY * ver_dist <= rectangle.y ) minY++;
+ minY *= ver_dist;
+
+ p1 = new DPoint( 0, rectangle.y );
+ p2 = new DPoint( 0, rectangle.y + rectangle.height );
+ for( pos = minX; pos<=rectangle.x + rectangle.width; pos += hor_dist ){
+ p1.x = p2.x = pos;
+ l = new DLine( p1, p2, color );
+ l.paint( m );
+ }
+
+ p1.x = rectangle.x;
+ p2.x = p1.x + rectangle.width;
+ for( pos = minY; pos<=rectangle.y + rectangle.height; pos += ver_dist ){
+ p1.y = p2.y = pos;
+ l = new DLine( p1, p2, color );
+ l.paint( m );
+ }
+
+ g.setColor( old_color );
+ }
+
+ public String toString(){
+ return "DDrawing.DGrid[ hor: "+hor_dist+", ver: "+ver_dist+" ]";
+ }
+}
+
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DImage.java b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DImage.java
new file mode 100644
index 0000000..2afc690
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DImage.java
@@ -0,0 +1,36 @@
+package DDrawing;
+
+
+import java.awt.Graphics;
+import java.awt.Image;
+import java.awt.Point;
+import java.awt.image.ImageObserver;
+
+
+/**
+ * @author mkron
+ */
+public class DImage extends DRectangle{
+ Image image;
+ ImageObserver observer;
+
+ public DImage( double x, double y, double width, double height, ImageObserver observer ){
+ super( x, y, width, height );
+ this.observer = observer;
+ }
+
+ public void paint( DMeasures m ){
+ Graphics g = m.getGraphics();
+ DParent parent = getDParent();
+ Point p1 = m.getPoint( x, y ),
+ p2 = m.getPoint( x + width, y + height );
+ if( image == null ) g.drawRect( p1.x, p2.y, p2.x - p1.x, p1.y - p2.y );
+ else g.drawImage( image, p1.x, p2.y, p2.x - p1.x, p1.y - p2.y, observer );
+ }
+
+ public void setImage( Image img ){
+ if( img.equals( image ) ) return;
+ image = img;
+ repaint();
+ }
+}
\ No newline at end of file
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DLine.java b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DLine.java
new file mode 100644
index 0000000..e230b6d
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DLine.java
@@ -0,0 +1,54 @@
+package DDrawing;
+
+
+import java.awt.*;
+
+
+/**
+ * @author mkron
+ */
+public class DLine extends DComponent{
+ DPoint start;
+ DPoint end;
+
+ public DLine( double x1, double y1, double x2, double y2 ){
+ this( new DPoint( x1, y1 ), new DPoint( x2, y2 ) );
+ }
+
+ public DLine( DPoint start, DPoint end ){
+ this.start = start;
+ this.end = end;
+ }
+ public DLine( double x1, double y1, double x2, double y2, Color color ){
+ this( new DPoint( x1, y1 ), new DPoint( x2, y2 ), color );
+ }
+
+ public DLine( DPoint start, DPoint end, Color color ){
+ this.start = start;
+ this.end = end;
+ this.color = color;
+ }
+
+ public DRectangle getRectangle(){
+ double x = start.x, y = start.y, width = end.x - x, height = end.y - y;
+ if( width < 0 ) { x += width; width *= -1; }
+ if( height < 0 ) { y += height; height *= -1; }
+ return new DRectangle( x, y, width, height );
+ }
+
+ public void paint( DMeasures m ){
+ //System.out.println("DLine.paint(Measures): "+this);
+ Graphics g = m.getGraphics();
+ Color old_color = g.getColor();
+ if( color != null ) g.setColor( color );
+ else g.setColor( DEFAULT_COLOR );
+ Point p1 = m.getPoint( start ),
+ p2 = m.getPoint( end ) ;
+ g.drawLine( p1.x, p1.y, p2.x, p2.y );
+ g.setColor( old_color );
+ }
+
+ public String toString(){
+ return "DLine[("+start.x+","+start.y+") --> ("+end.x+","+end.y+", color: "+color+"]";
+ }
+}
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DMeasures.java b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DMeasures.java
new file mode 100644
index 0000000..20f7e70
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DMeasures.java
@@ -0,0 +1,219 @@
+package DDrawing;
+
+
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Insets;
+import java.awt.Point;
+
+/**
+ * @author mkron
+ */
+public class DMeasures {
+ // when in use for a DArea:
+ Graphics g;
+ // when in use for a ScaledBorder:
+ ScaledBorder sb;
+ // for both:
+ DFunction x_scale;
+ // for both:
+ DFunction y_scale;
+ Component comp;
+ Insets insets;
+
+ /**
+ * package private constructor for the DMeasures object
+ * the object can be obtained by calling the method getDMeasures of an DArea
+ * object
+ *
+ * @param area the DArea object
+ */
+ DMeasures( DArea area ){
+ comp = area;
+ }
+
+ DMeasures( ScaledBorder sb ){
+ this.sb = sb;
+ }
+
+ /**
+ * method returns the pixel-point which belongs to the DPoint in the
+ * D-coordinates
+ * it says where to paint a certain DPoint
+ *
+ * @param p the DPoint
+ * @return the coresponding pixel Point
+ */
+ public Point getPoint( DPoint p ){
+ //System.out.println("DMeasures.getPoint :"+org );
+ return getPoint( p.x, p.y );
+ }
+
+ /**
+ * method returns the pixel-point which belongs to the given D-coordinates
+ * it says where to paint a certain DPoint
+ *
+ * @param x the double x D-coordinate
+ * @param y the double y D-coordinate
+ * @return the coresponding pixel Point
+ */
+ public Point getPoint( double x, double y ){
+ DRectangle rect = getSourceOf( getDRectangle() );
+ if( x_scale != null ) x = x_scale.getSourceOf( x );
+ if( y_scale != null ) y = y_scale.getSourceOf( y );
+ Point dp = new Point();
+ Dimension dim = getInner();
+ Insets insets = getInsets();
+ dp.x = (int)( dim.width * (x - rect.x)/(double)rect.width ) + insets.left;
+ dp.y = (int)( dim.height * (1 - (y - rect.y)/(double)rect.height)) + insets.top;
+ return dp;
+ }
+
+ /**
+ * method returns the point in D-coordinates which corresponds to the
+ * given pixel-point
+ *
+ * @param p Point in pixel coordinates
+ * @return the coresponding DPoint
+ */
+ public DPoint getDPoint( Point p ){
+ return getDPoint( p.x, p.y );
+ }
+
+ /**
+ * method returns the point in D-coordinates which corresponds to the
+ * given pixel-coordinates
+ *
+ * @param x x-pixel coordinate
+ * @param y y-pixel coordinate
+ * @return the coresponding DPoint
+ */
+ public DPoint getDPoint( int x, int y ){
+ DRectangle rect = getSourceOf( getDRectangle() );
+ Dimension dim = getInner();
+ Insets insets = getInsets();
+ x -= insets.left;
+ y -= insets.top;
+ double dx, dy;
+ dx = rect.x + rect.width * x/(double)dim.width;
+ dy = rect.y + rect.height * (1 - y/(double)dim.height );
+ if( x_scale != null ) dx = x_scale.getImageOf( dx );
+ if( y_scale != null ) dy = y_scale.getImageOf( dy );
+ return new DPoint( dx, dy );
+ }
+
+ /**
+ * returns the visible rectangle in D-coordinates of the shown component
+ *
+ * return the visible rectangle
+ */
+ public DRectangle getDRectangle(){
+ if( sb != null )
+ return getImageOf(
+ new DRectangle( sb.src_minx, sb.src_miny,
+ sb.src_maxx - sb.src_minx,
+ sb.src_maxy - sb.src_miny )
+ );
+ return ((DArea)comp).getDRectangle();
+ }
+
+ /**
+ * returns the current Graphics object, which might be used by components to
+ * paint themselves
+ * the method sets the clipping area of the Graphics object to the currently
+ * visible rectangle
+ *
+ * @return the Graphics object ( or null if no object was set )
+ */
+ public Graphics getGraphics(){
+ if( g != null ){
+ Dimension d = comp.getSize();
+ Insets insets = getInsets();
+ g.setClip( insets.left + 1, // dann sieht man noch was von der linken Achse
+ insets.top,
+ d.width - insets.left - insets.right,
+ d.height - insets.top - insets.bottom);
+ }
+ return g;
+ }
+
+ /**
+ * used by DArea to set a new Graphics object
+ */
+ void setGraphics( Graphics g ){ this.g = g; }
+
+ /**
+ * used by ScaledBorder to update the DMeasures object
+ *
+ * @param c the parent component the border
+ */
+ void update( Component c, Insets insets ){
+ this.comp = c;
+ this.insets = insets;
+ x_scale = sb.x_scale;
+ y_scale = sb.y_scale;
+ }
+
+ private Dimension getInner(){
+ Dimension d = comp.getSize();
+ Insets insets = getInsets();
+ d.width -= insets.left + insets.right;
+ d.height -= insets.top + insets.bottom;
+ return d;
+ }
+
+
+ /**
+ * method returns the source rectangle of the given rectangle
+ * they differ if there are scale functions selected which are not the identity
+ *
+ * @param rect the image rectangle
+ * @return the source of it
+ */
+ DRectangle getSourceOf( DRectangle rect ){
+ if( x_scale == null && y_scale == null ) return rect;
+ if( rect.isEmpty() ) return (DRectangle)rect.clone();
+ DPoint p1 = new DPoint( rect.x, rect.y ),
+ p2 = new DPoint( rect.x + rect.width, rect.y + rect.height );
+
+ if( x_scale != null ){
+ p1.x = x_scale.getSourceOf( p1.x );
+ p2.x = x_scale.getSourceOf( p2.x );
+ }
+ if( y_scale != null ){
+ p1.y = y_scale.getSourceOf( p1.y );
+ p2.y = y_scale.getSourceOf( p2.y );
+ }
+ return new DRectangle( p1.x, p1.y, p2.x - p1.x, p2.y - p1.y );
+ }
+ /**
+ * method returns the image rectangle of the given rectangle
+ * they differ if there are scale functions selected which are not the identity
+ *
+ * @param rect the source rectangle
+ * @return the source of it
+ */
+ DRectangle getImageOf( DRectangle rect ){
+ if( x_scale == null && y_scale == null ) return rect;
+ if( rect.isEmpty() ) return (DRectangle)rect.clone();
+ DPoint p1 = new DPoint( rect.x, rect.y ),
+ p2 = new DPoint( rect.x + rect.width, rect.y + rect.height );
+
+ if( x_scale != null ){
+ p1.x = x_scale.getImageOf( p1.x );
+ p2.x = x_scale.getImageOf( p2.x );
+ }
+ if( y_scale != null ){
+ p1.y = y_scale.getImageOf( p1.y );
+ p2.y = y_scale.getImageOf( p2.y );
+ }
+ return new DRectangle( p1.x, p1.y, p2.x - p1.x, p2.y - p1.y );
+ }
+
+ private Insets getInsets(){
+ if( sb != null ) return insets;
+ return ((DArea)comp).getInsets();
+ }
+}
\ No newline at end of file
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DMouseZoom.java b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DMouseZoom.java
new file mode 100644
index 0000000..3bdccb7
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DMouseZoom.java
@@ -0,0 +1,105 @@
+package DDrawing;
+
+
+import java.awt.*;
+import java.awt.event.*;
+
+
+/**
+ * @author mkron
+ */
+public class DMouseZoom extends DRectangle implements MouseMotionListener, MouseListener{
+ DArea area;
+ private DPoint start;
+
+ public DMouseZoom( DArea area ) {
+ super( 0, 0, 0, 0 );
+ setVisible( false );
+ this.area = area;
+ area.addMouseListener( this );
+ area.addMouseMotionListener( this );
+ color = Color.yellow;
+ }
+ /**
+ * Invoked when the mouse has been clicked on a component.
+ */
+ public void mouseClicked(MouseEvent e) {
+ DRectangle r = area.getDRectangle();
+ if( ( e.getModifiers() & InputEvent.BUTTON1_MASK ) > 0 ){
+ DMeasures m = area.getDMeasures();
+ DPoint c = m.getDPoint( e.getPoint() );
+ r.x = c.x - r.width * .5;
+ r.y = c.y - r.height * .5;
+ }
+ else {
+ r.x -= r.width * .5;
+ r.y -= r.height * .5;
+ r.width *= 2;
+ r.height *= 2;
+ }
+ area.setVisibleRectangle( r );
+ }
+
+ /**
+ * Invoked when a mouse button has been pressed on a component.
+ */
+ public void mousePressed(MouseEvent e) {
+ setVisible( true );
+ DMeasures m = area.getDMeasures();
+ DPoint p = m.getDPoint( e.getPoint() );
+ start = new DPoint( p.x, p.y );
+ x = p.x;
+ y = p.y;
+ width = 0;
+ height = 0;
+ area.addDElement( this );
+ }
+
+ /**
+ * Invoked when a mouse button has been released on a component.
+ */
+ public void mouseReleased(MouseEvent e) {
+ if( isVisible() )
+ area.setVisibleRectangle( (DRectangle)this.clone() );
+ setVisible( false );
+ area.removeDElement( this );
+ }
+
+ public void mouseExited( MouseEvent e ){
+ setVisible( false );
+ }
+
+ public void mouseEntered( MouseEvent e ){
+ setVisible( true );
+ }
+
+ /**
+ * Invoked when a mouse button is pressed on a component and then
+ * dragged. Mouse drag events will continue to be delivered to
+ * the component where the first originated until the mouse button is
+ * released (regardless of whether the mouse position is within the
+ * bounds of the component).
+ */
+ public void mouseDragged(MouseEvent e){
+ if( !isVisible() ) return;
+ DMeasures m = area.getDMeasures();
+ DPoint p = m.getDPoint( e.getPoint() );
+ width = p.x - start.x;
+ height = p.y - start.y;
+ if( width < 0 ){
+ x = p.x;
+ width *= -1;
+ }
+ if( height < 0 ){
+ y = p.y;
+ height *= -1;
+ }
+ area.repaint();
+ }
+
+ /**
+ * Invoked when the mouse button has been moved on a component
+ * (with no buttons no down).
+ */
+ public void mouseMoved(MouseEvent e){}
+}
\ No newline at end of file
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DParent.java b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DParent.java
new file mode 100644
index 0000000..a04b538
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DParent.java
@@ -0,0 +1,8 @@
+package DDrawing;
+
+
+public interface DParent{
+ void addDElement( DElement e );
+ boolean removeDElement( DElement e );
+ void repaint( DRectangle r );
+}
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DPeakSet.java b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DPeakSet.java
new file mode 100644
index 0000000..43c19ee
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DPeakSet.java
@@ -0,0 +1,98 @@
+
+
+package DDrawing;
+
+import java.awt.Color;
+import java.util.Vector ;
+
+
+public class DPeakSet extends DContainer{
+ private double width;
+ private Vector peaks;
+ private Color fill_color = Color.lightGray;
+
+ public DPeakSet( double width ){
+ this( width, 5 );
+ }
+
+ public DPeakSet( double width, int initial_capacity ) {
+ if( width <= 0 ) throw
+ new IllegalArgumentException("The width of the peaks has to be a positive value");
+ this.width = width;
+ peaks = new Vector( initial_capacity );
+ }
+
+ public void setColor( Color color ){
+ super.setColor( color );
+ for( int i=0; i rectangle.height ) {
+ rectangle.height = p.height;
+ repaint();
+ }
+ }
+ }
+ if( found ) return;
+ double min = (int)( v / width );
+ DCountingPeak p = new DCountingPeak( min, width );
+ peaks.add( p );
+ p.addValue();
+ addDElement( p );
+ }
+
+ public void paint( DMeasures m ){
+ for( int i=0; i= x && v < x + width ){
+ height += 1;
+ repaint();
+ return true;
+ }
+ return false;
+ }
+
+ public void reset(){
+ if( height == 0 ) return;
+ height = 0;
+ repaint();
+ }
+}
\ No newline at end of file
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DPoint.java b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DPoint.java
new file mode 100644
index 0000000..240b8cb
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DPoint.java
@@ -0,0 +1,44 @@
+package DDrawing;
+
+import java.awt.* ;
+
+
+public class DPoint extends DComponent{
+ public double x;
+ public double y;
+ public String label;
+
+ public DPoint( double x, double y ){
+ this.x = x;
+ this.y = y;
+ rectangle = new DRectangle( x, y, 0, 0 );
+ }
+
+ public void paint( DMeasures m ){
+ Graphics g = m.getGraphics();
+ Color old_color = g.getColor();
+ if( color != null ) g.setColor( color );
+ else g.setColor( DEFAULT_COLOR );
+ Point dp = m.getPoint( this );
+ g.drawRect( dp.x, dp.y, 1, 1 );
+ if( label != null ){
+ FontMetrics fm = g.getFontMetrics();
+ g.drawString( label,
+ dp.x - fm.stringWidth( label ) / 2,
+ dp.y + fm.getAscent()
+ );
+ }
+ g.setColor( old_color );
+ }
+ public Object clone(){
+ DPoint copy = new DPoint( x, y );
+ copy.color = color;
+ return copy;
+ }
+ public String toString(){
+ String text = "DPoint[";
+ if( label != null ) text += label+", ";
+ text += "x: "+x+", y: "+y+", color: "+color+"]";
+ return text;
+ }
+}
\ No newline at end of file
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DPointSet.java b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DPointSet.java
new file mode 100644
index 0000000..91ed6f1
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/DPointSet.java
@@ -0,0 +1,94 @@
+package DDrawing;
+
+import java.awt.*;
+
+
+/**
+ * @author mkron
+ */
+public class DPointSet extends DComponent{
+ private double[] x;
+ private double[] y;
+ private boolean connected = false;
+ private int size = 0;
+
+ public DPointSet( int initial_capacity ){
+ if( initial_capacity < 1 ) initial_capacity = 1;
+ x = new double[ initial_capacity ];
+ y = new double[ initial_capacity ];
+ }
+
+ public void paint( DMeasures m ){
+ Graphics g = m.getGraphics();
+ Color old_color = g.getColor();
+ if( color != null ) g.setColor( color );
+ else g.setColor( DEFAULT_COLOR );
+ if( connected && size > 1 ){
+ Point p1, p2;
+ p1 = m.getPoint( x[0], y[0] );
+ for( int i=1; i10000.) {
+ System.err.println("refusing y="+y);
+ return;
+ }
+ if( ++size > this.x.length ){
+ int oldL = this.x.length;
+ double[] newV = new double[ oldL * 2 ];
+ System.arraycopy( this.x, 0, newV, 0, oldL );
+ this.x = newV;
+ newV = new double[ oldL * 2 ];
+ System.arraycopy( this.y, 0, newV, 0, oldL );
+ this.y = newV;
+ }
+ this.x[ size - 1 ] = x;
+ this.y[ size - 1 ] = y;
+
+ if( size == 1 ) rectangle = new DRectangle( x, y, 0, 0 );
+ else rectangle.insert( new DPoint( x, y ) );
+
+ repaint();
+ }
+
+ public void setConnected( boolean aFlag ){
+ boolean changed = !( aFlag == connected );
+ connected = aFlag;
+ if( changed ) repaint();
+ }
+
+ public void removeAllPoints(){
+ size = 0;
+ repaint();
+ rectangle = DRectangle.getEmpty();
+ }
+
+ public String toString(){
+ String text = "dPointSet[size:"+size;
+ for( int i=0; i= 0");
+ this.width = width;
+ if( height < 0 ) throw
+ new IllegalArgumentException("Height of a DRectangle has to be >= 0");
+ this.height = height;
+ status = PART;
+ }
+
+ public DRectangle getRectangle(){ return this; }
+
+ public void paint( DMeasures m ){
+ if( status != PART ) return;
+ Graphics g = m.getGraphics();
+ Color old_color = g.getColor();
+ Point p1 = m.getPoint( x, y ),
+ p2 = m.getPoint( x + width, y + height );
+ if( fillColor != null ){
+ g.setColor( fillColor );
+ g.fillRect( p1.x, p2.y, p2.x - p1.x, p1.y - p2.y );
+ }
+ if( color != null ) g.setColor( color );
+ else g.setColor( DEFAULT_COLOR );
+ g.drawRect( p1.x, p2.y, p2.x - p1.x, p1.y - p2.y );
+ g.setColor( old_color );
+ }
+
+ public boolean contains( DPoint p ){
+ if( status == ALL ) return true;
+ if( status == EMPTY ) return false;
+ if( p.x < x ) return false;
+ if( p.y < y ) return false;
+ if( p.x > x + width ) return false;
+ if( p.y > y + height ) return false;
+ return true;
+ }
+
+ public boolean contains( DRectangle rect ){
+ if( status == ALL ) return true;
+ if( status == EMPTY ) return false;
+ if( !contains( new DPoint( rect.x, rect.y ) ) ) return false;
+ if( !contains( new DPoint( rect.x + rect.width, rect.y + rect.height ) ) ) return false;
+ return true;
+ }
+
+ public DRectangle getIntersection( DRectangle r ){
+ if( status == ALL ) return (DRectangle)r.clone();
+ if( status == EMPTY ) return DRectangle.getEmpty();
+ if( r == null ) return null;
+ DRectangle s = (DRectangle)this.clone();
+ if( s.x < r.x ){
+ s.x = r.x;
+ s.width -= r.x - s.x;
+ }
+ if( s.y < r.y ){
+ s.y = r.y;
+ s.height -= r.y - s.y;
+ }
+ if( s.x + s.width > r.x + r.width )
+ s.width = r.x + r.width - s.x;
+ if( s.y + s.height > r.y + r.height )
+ s.height = r.y + r.height - s.y;
+ if( s.width < 0 || s.height < 0 ) return null;
+ else return s;
+ }
+
+ /**
+ * method resizes the rectangle to insert p
+ *
+ * @param the dPoint p to insert
+ * @return true when the size of the rectangle changed
+ */
+ public boolean insert( DPoint p ){
+ if( status == ALL ) return false;
+ if( contains( p ) ) return false;
+ if( isEmpty() ){
+ x = p.x; y = p.y; width = height = 0;
+ status = PART;
+ return true;
+ }
+ if( p.x < x ) {
+ width += x - p.x;
+ x = p.x;
+ }
+ else if( p.x > x + width ) width = p.x - x;
+ if( p.y < y ) {
+ height += y - p.y;
+ y = p.y;
+ }
+ else if( p.y > y + height ) height = p.y - y;
+ return true;
+ }
+
+ public boolean insert( DRectangle rect ){
+ if( status == ALL ) return false;
+ if( status == EMPTY ){
+ if( rect.isEmpty() ) return false;
+ if( rect.isAll() ){ status = ALL; return true; }
+ x = rect.x; y = rect.y; width = rect.width; height = rect.height;
+ status = PART;
+ return true;
+ }
+ boolean changed = false;
+ changed = insert( new DPoint( rect.x, rect.y ) );
+ changed = insert( new DPoint( rect.x + rect.width, rect.y + rect.height ) )? true : changed;
+ return changed;
+ }
+
+ public Object clone(){
+ DRectangle copy = new DRectangle( x, y, width, height );
+ copy.status = status;
+ if( color != null ) copy.color = new Color( color.getRGB() );
+ return copy;
+ }
+
+ public String toString(){
+ String text = "DRectangle[";
+ switch( status ){
+ case ALL : text += "all ]"; break;
+ case EMPTY : text += "empty ]"; break;
+ case PART : text += x+","+y+","+width+","+height+"]";
+ }
+ return text;
+ }
+
+ public boolean equals( DRectangle r ){
+ if( r == null ) return false;
+ if( r.status != status ) return true;
+ if( r.x != x ) return false;
+ if( r.y != y ) return false;
+ if( r.width != width ) return false;
+ if( r.height != height ) return false;
+ return true;
+ }
+
+ public void setFillColor( Color fill_color ){
+ if( fillColor == null || !fillColor.equals( fill_color ) ){
+ fillColor = fill_color;
+ repaint();
+ }
+ }
+
+ public Color getFillColor(){
+ return fillColor;
+ }
+
+ public static DRectangle getAll(){ return new DRectangle( ALL ); }
+ public boolean isAll(){ return status == ALL; }
+ public static DRectangle getEmpty(){ return new DRectangle( EMPTY ); }
+ public boolean isEmpty(){ return status == EMPTY; }
+}
+
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/PagePrinter.java b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/PagePrinter.java
new file mode 100644
index 0000000..2637cf2
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/PagePrinter.java
@@ -0,0 +1,142 @@
+package DDrawing;
+
+import java.awt.* ;
+import java.awt.print.* ;
+import java.awt.image.BufferedImage ;
+import javax.swing.* ;
+
+public class PagePrinter {
+ Component c;
+ Graphics g;
+ PageFormat pf;
+ public boolean fit_in_possible = true;
+
+ public PagePrinter( Component c, Graphics g, PageFormat pf ) {
+ this.c = c;
+ this.g = g;
+ this.pf = pf;
+ }
+
+ public synchronized int print(){
+ //System.out.println("PagePrinter.print()");
+ Dimension old = c.getSize();
+
+ int x = (int)pf.getImageableX() + 1,
+ y = (int)pf.getImageableY() + 1;
+
+ double w = (int)pf.getImageableWidth(),
+ h = (int)pf.getImageableHeight();
+
+ if( old.width > w || old.height > h ){
+ boolean rec_turn = false, rec_fit_in = false;
+ if( ( old.width > old.height && h > w ) ||
+ ( old.width < old.height && h < w ) ) {
+ rec_turn = true;
+ if( old.width > h || old.height > w ) rec_fit_in = true;
+ }
+ else rec_fit_in = true;
+
+ JLabel[] text = new JLabel[4];
+ text[0] = new JLabel("The component which should be printed");
+ text[1] = new JLabel("is too large.");
+ text[2] = new JLabel("You can choose if the component should be");
+ JCheckBox cbFitIn = new JCheckBox("fitted-in", rec_fit_in),
+ cbTurn = new JCheckBox("turned", rec_turn );
+ text[3] = new JLabel("(Recommended choice is pre-selected)");
+
+ if( !fit_in_possible ){
+ cbFitIn.setEnabled( false );
+ cbFitIn.setSelected( false );
+ }
+
+ GridBagLayout gbl = new GridBagLayout();
+ JPanel panel = new JPanel( gbl );
+ GridBagConstraints gbc = new GridBagConstraints();
+ gbc.gridx = gbc.gridy = 0;
+ gbc.weightx = gbc.weighty = .5;
+
+ gbc.gridwidth = 2;
+ gbl.setConstraints( text[0], gbc );
+ panel.add( text[0] );
+
+ gbc.gridy++;
+ gbl.setConstraints( text[1], gbc );
+ panel.add( text[1] );
+
+ gbc.gridy++;
+ gbl.setConstraints( text[2], gbc );
+ panel.add( text[2] );
+
+ gbc.gridy++;
+ gbc.gridwidth = 1;
+ gbl.setConstraints( cbFitIn, gbc );
+ panel.add( cbFitIn );
+
+ gbc.gridx++;
+ gbl.setConstraints( cbTurn, gbc );
+ panel.add( cbTurn );
+ gbc.gridx = 0;
+ gbc.gridwidth = 2;
+ gbc.gridy++;
+ gbl.setConstraints( text[3], gbc);
+ panel.add( text[3] );
+
+ int choice = JOptionPane.showOptionDialog( c, panel, "Fit-in",
+ JOptionPane.OK_CANCEL_OPTION,
+ JOptionPane.QUESTION_MESSAGE,
+ null, null, null );
+
+ if( choice == JOptionPane.CANCEL_OPTION || choice == JOptionPane.CLOSED_OPTION )
+ return Printable.NO_SUCH_PAGE;
+
+ else if( choice == JOptionPane.OK_OPTION ){
+ g.translate( x, y );
+
+ if( cbTurn.isSelected() ){
+ BufferedImage img;
+ if( cbFitIn.isSelected() ){
+ double m = Math.min( h / (double)old.width, w / (double)old.height );
+ img = (BufferedImage)c.createImage( (int)( old.height * m ), (int)( old.width * m ) );
+ Graphics2D g2 = img.createGraphics();
+ g2.rotate( Math.toRadians( 90 ) );
+ g2.translate( 0, - old.height * m );
+ c.setSize( (int)( old.width * m ), (int)( old.height * m ) );
+ c.paint( g2 );
+ c.setSize( old );
+ }
+ else{
+ img = (BufferedImage)c.createImage( old.height, old.width );
+ Graphics2D g2 = img.createGraphics();
+ g2.rotate( Math.toRadians( 90 ) );
+ g2.translate( 0, - old.height );
+ c.paint( g2 );
+ }
+ g.drawImage( img, 0, 0, c.getBackground(), c );
+ }
+
+ else{
+ if( cbFitIn.isSelected() ){
+ double m = Math.min( w / (double)old.width, h / (double)old.height );
+ //img = (BufferedImage)c.createImage( (int)( old.width * m ), (int)( old.height * m ) );
+ //Graphics g2 = img.createGraphics();
+ c.setSize( (int)( old.width * m ), (int)( old.height * m ) );
+ c.paint( g );
+ c.setSize( old );
+ }
+ else {
+ //img = (BufferedImage)c.createImage( old.width, old.height );
+ //Graphics g2 = img.createGraphics();
+ c.paint( g );
+ }
+ }
+ }
+ }
+ else {
+ //img = (BufferedImage)c.createImage( old.width, old.height );
+ //Graphics g2 = img.createGraphics();
+ c.paint( g );
+ }
+ //g.drawImage( img, 0, 0, c.getBackground(), c );
+ return Printable.PAGE_EXISTS;
+ }
+}
\ No newline at end of file
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/ScaledBorder.java b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/ScaledBorder.java
new file mode 100644
index 0000000..750a091
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/DDrawing/ScaledBorder.java
@@ -0,0 +1,479 @@
+package DDrawing;
+
+import java.awt.*;
+import java.awt.geom.AffineTransform;
+import javax.swing.BorderFactory;
+import javax.swing.border.*;
+
+/*---------------------- class declaration -----------------------------------*/
+/**
+ * ScaledBorder puts an border around Components ( especially around DrawingAreas ) with scaled and labeled x- and y-axes
+ */
+public class ScaledBorder implements Border{
+ private boolean under_construction = false;
+
+ /**
+ * length of the distance markers on the axes in pixels
+ */
+ int marker_length = 2;
+
+ /**
+ * length in pixels of the arrows at the ends of the axes
+ */
+ int arrow_length = 10;
+
+ /**
+ * a flag if the arrows should be visible
+ */
+ public boolean show_arrows = true;
+
+ /**
+ * distance between the x-values in digits
+ */
+ int x_value2value = 2;
+
+ /**
+ * distance between y-label and y-values in digit width
+ */
+ int y_label2values = 1;
+
+ /**
+ * distance between y-values and y-axis markers in parts of the digit width
+ */
+ int y_values2marker = 2;
+
+ /**
+ * distance between values and arrows in pixels
+ */
+ int x_values2arrow = 10 ;
+ /**
+ * distance between values and arrows in pixels
+ */
+ int y_values2arrow = 10 ;
+
+ /**
+ * distance between arrows and outer border
+ */
+ int axis2border = 4;
+
+ /**
+ * distance between labels and the border in pixels
+ */
+ public int x_label2border = 6 ;
+ /**
+ * distance between labels and the border in pixels
+ */
+ public int y_label2border = 6 ;
+
+ /**
+ * the size of the shown rectangle
+ */
+ double src_minx = 0 ;
+ /**
+ * the size of the shown rectangle
+ */
+ double src_maxx = 1 ;
+ /**
+ * the size of the shown rectangle
+ */
+ double src_miny = 0 ;
+ /**
+ * the size of the shown rectangle
+ */
+ double src_maxy = 1 ;
+
+ /**
+ * the minimal increment of the scales
+ */
+ public double minimal_increment = 0;
+
+ /**
+ * the displayed labels
+ */
+ public String x_label;
+ /**
+ * the displayed labels
+ */
+ public String y_label;
+
+ /**
+ * foreground and background colors
+ */
+ public Color foreground;
+ /**
+ * foreground and background colors
+ */
+ public Color background;
+
+ /**
+ * the border which is shown around the scaled border
+ */
+ Border outer_border;
+
+ /**
+ * flag if the outer border should be displayed
+ */
+ boolean show_outer_border = true;
+
+ public DFunction x_scale = null ;
+ public DFunction y_scale = null ;
+
+ private double src_dX = - 1 ;
+ private double src_dY = - 1 ;
+
+ private boolean do_refresh;
+
+ private Insets old_insets;
+
+ private DMeasures m;
+
+ /**
+ * constructor creates a default ScaledBorder inside of a lowered BevelBorder
+ */
+ public ScaledBorder(){
+ this(
+ BorderFactory.createBevelBorder(
+ BevelBorder.LOWERED,
+ Color.white,
+ Color.lightGray,
+ Color.black,
+ Color.lightGray
+ )
+ );
+ }
+ /**
+ * constructor creates a new ScaledBorder
+ * surrounded by the specified Border
+ */
+ public ScaledBorder( Border outer ){
+ outer_border = outer;
+ m = new DMeasures( this );
+ }
+
+ public void paintBorder(Component c, Graphics g, int x, int y, int width, int height){
+ if( under_construction ) System.out.println("ScaledBorder.paintBorder()");
+ if( foreground == null ) foreground = c.getForeground();
+ if( background == null ) background = c.getBackground();
+ Color old_color = g.getColor();
+ g.setColor( background );
+ g.fillRect( x, y, width, height );
+ g.setColor( old_color );
+
+ Insets outer_insets = new Insets( 0, 0, 0, 0);// insets of the outer border
+ if( show_outer_border ) {
+ outer_border.paintBorder( c, g, x, y, width, height );
+ outer_insets = outer_border.getBorderInsets( c );
+ }
+
+ do_refresh = true;
+ Insets inner_insets = getBorderInsets(c);
+
+ Dimension d = c.getSize(),
+ cd = new Dimension( d.width - inner_insets.left - inner_insets.right,
+ d.height - inner_insets.top - inner_insets.bottom );
+ FontMetrics fm = g.getFontMetrics();
+ int fontAsc = fm.getAscent();
+ do_refresh = false;
+
+ m.update(c, inner_insets);
+
+ // axes
+ g.setColor( foreground );
+ g.drawLine( inner_insets.left, inner_insets.top,
+ inner_insets.left, inner_insets.top + cd.height );
+ g.drawLine( inner_insets.left, inner_insets.top + cd.height,
+ inner_insets.left + cd.width, inner_insets.top + cd.height );
+
+ if( show_arrows ){
+ g.drawLine( inner_insets.left, inner_insets.top,
+ inner_insets.left, inner_insets.top - y_values2arrow );
+ g.drawLine( inner_insets.left - marker_length, inner_insets.top - y_values2arrow,
+ inner_insets.left, inner_insets.top - y_values2arrow - arrow_length );
+ g.drawLine( inner_insets.left + marker_length, inner_insets.top - y_values2arrow,
+ inner_insets.left, inner_insets.top - y_values2arrow - arrow_length);
+ g.drawLine( inner_insets.left - marker_length, inner_insets.top - y_values2arrow,
+ inner_insets.left + marker_length, inner_insets.top - y_values2arrow );
+
+ g.drawLine( inner_insets.left + cd.width , inner_insets.top + cd.height,
+ inner_insets.left + cd.width + x_values2arrow, inner_insets.top + cd.height );
+ g.drawLine( inner_insets.left + cd.width + x_values2arrow,
+ inner_insets.top + cd.height - marker_length,
+ inner_insets.left + cd.width + x_values2arrow + arrow_length,
+ inner_insets.top + cd.height );
+ g.drawLine( inner_insets.left + cd.width + x_values2arrow,
+ inner_insets.top + cd.height + marker_length,
+ inner_insets.left + cd.width + x_values2arrow + arrow_length,
+ inner_insets.top + cd.height );
+ g.drawLine( inner_insets.left + cd.width + x_values2arrow,
+ inner_insets.top + cd.height - marker_length,
+ inner_insets.left + cd.width + x_values2arrow,
+ inner_insets.top + cd.height + marker_length );
+ }
+
+ if( y_label != null ) {
+ Dimension yld = new Dimension(fm.getAscent()+fm.getDescent(), fm.stringWidth(y_label));
+ AffineTransform T = new AffineTransform(0, -1, 1, 0, 0, 0);
+ Font old = g.getFont(), f = old.deriveFont( T );
+ g.setFont( f );
+ g.drawString( y_label, y_label2border + fm.getAscent(), inner_insets.top + ( cd.height + yld.height )/ 2 );
+ g.setFont( old );
+ }
+
+ if( x_label != null )
+ g.drawString(
+ x_label, inner_insets.left + ( cd.width - fm.stringWidth( x_label ) ) / 2,
+ d.height - outer_insets.bottom - x_label2border - fm.getDescent() );
+
+ if( src_minx == 0 && src_miny == 0 ){
+ int v2m = fm.stringWidth("0") / y_values2marker;
+ g.drawString( "0", inner_insets.left - fm.stringWidth( "0" ) - v2m - marker_length,
+ inner_insets.top + cd.height + fontAsc );
+ g.drawLine( inner_insets.left, inner_insets.top + cd.height + fm.getAscent(),
+ inner_insets.left, inner_insets.top + cd.height);
+ g.drawLine( inner_insets.left, inner_insets.top + cd.height,
+ inner_insets.left - fm.stringWidth( "0" ) - v2m - marker_length,
+ inner_insets.top + cd.height );
+ }
+
+ drawYValues( g, inner_insets, src_miny, src_maxy, cd );
+ drawXValues( g, inner_insets, src_minx, src_maxx, cd );
+
+ g.setColor( old_color );
+ }
+
+ private void drawYValues( Graphics g, Insets insets, double src_miny, double src_maxy, Dimension cd ){
+ if( under_construction ) System.out.println("ScaledBorder.drawYValues()");
+
+ FontMetrics fm = g.getFontMetrics();
+ int n, fontAsc = fm.getAscent(), v2m = fm.stringWidth("0") / y_values2marker;
+
+ n = (int)( src_miny / src_dY );
+ if( n * src_dY < src_miny || ( src_minx == 0 && src_miny == 0 ) ) n++;
+
+ int decs;
+ if( y_scale != null ) decs = getDecs( y_scale.getImageOf( src_dY ) );
+ else decs = getDecs( src_dY );
+
+ double v;
+ while( (v = n * src_dY) <= src_maxy ){
+ if( y_scale != null ) v = y_scale.getImageOf( v );
+ v = cutDec(v, decs);
+ Point p = m.getPoint( 0, v );
+ String text = stringOf(v);
+ g.drawString( text,
+ insets.left - fm.stringWidth( text ) - v2m - marker_length,
+ p.y + fontAsc / 2 );
+ g.drawLine( insets.left - marker_length, p.y, insets.left, p.y );
+ n++;
+ }
+ }
+
+ public double getSrcdY( FontMetrics fm, Dimension cd, double src_miny, double src_maxy ){
+ if( under_construction ) System.out.println("ScaledBorder.getSrcdY()");
+ if( !do_refresh && src_dY != -1 ) return src_dY;
+ int max = cd.height / fm.getHeight();
+ double minsrc_dY = 2 * ( src_maxy - src_miny ) / (double)max; // die 2 einfach mal so eingesetzt <--------------------------
+ src_dY = aBitBigger( minsrc_dY );
+ if( src_dY < minimal_increment ) src_dY = minimal_increment;
+ return src_dY;
+ }
+
+ private void drawXValues( Graphics g, Insets insets, double src_minx, double src_maxx, Dimension cd ){
+ if( under_construction ) System.out.println("ScaledBorder.drawXValues()");
+
+ FontMetrics fm = g.getFontMetrics();
+ double mx = cd.width / ( src_maxx - src_minx );
+ int n, labelX, decs,
+ xnull = insets.left + (int)( - src_minx * mx );
+
+ if( x_scale != null ) decs = getDecs( x_scale.getImageOf( src_dX ) );
+ else decs = getDecs( src_dX );
+
+ n = (int)( src_minx / src_dX );
+ if( n * src_dX < src_minx || ( src_minx == 0 && src_miny == 0 ) ) n++;
+
+ int fontAsc = fm.getAscent(), xLineY = insets.top + cd.height;
+ labelX = xnull + (int)(n * src_dX * mx);
+ while( n * src_dX <= src_maxx ){
+ double v = n * src_dX;
+ if( x_scale != null ) v = x_scale.getImageOf(v);
+ v = cutDec(v, decs);
+ String text = stringOf(v);
+ int strW = fm.stringWidth( text );
+ g.drawString( text, labelX - strW / 2, xLineY + fontAsc );
+ g.drawLine( labelX, xLineY, labelX, xLineY + marker_length );
+ n++;
+ labelX = xnull + (int)( n * src_dX * mx);
+ }
+ }
+
+ public double getSrcdX( FontMetrics fm, Dimension cd, double src_minx, double src_maxx ){
+ if( under_construction ) System.out.println("ScaledBorder.getSrcdX()");
+ if( !do_refresh && src_dX != - 1 ) return src_dX;
+ int digit_width = fm.stringWidth("0"),
+ max = cd.width / ( digit_width * ( x_value2value + 1 ) );
+ src_dX = ( src_maxx - src_minx ) / (double)max;
+ int n, labelX, olsrc_dX;
+
+ boolean ok = false;
+ while( !ok ){
+ src_dX = aBitBigger( src_dX );
+
+ n = (int)( src_minx / src_dX );
+ if( n * src_dX < src_minx ) n++;
+
+ int decs;
+ if( x_scale != null ) decs = getDecs( x_scale.getImageOf( src_dX ) );
+ else decs = getDecs( src_dX );
+ olsrc_dX = 0;
+
+ boolean suits = true, first = true;
+ while( suits && n * src_dX <= src_maxx ){
+ double v = n * src_dX;
+ if( x_scale != null ) v = x_scale.getImageOf( v );
+ String text = stringOf( cutDec( v, decs ) );
+ int strW = fm.stringWidth( text );
+ labelX = (int)((( n * src_dX - src_minx ) / ( src_maxx - src_minx ) ) * cd.width ) - strW / 2;
+ if( !first && labelX <= olsrc_dX + digit_width * x_value2value ) suits = false;
+ else{
+ olsrc_dX = labelX + strW;
+ n++;
+ }
+ first = false;
+ }
+ if( !suits ) ok = false;
+ else ok = true;
+ }
+ if( src_dX < minimal_increment ) src_dX = minimal_increment;
+ return src_dX;
+ }
+
+ /**
+ * method returns to a certain minimal value the next higher value which can be
+ * displayed, which looks a bit nicer
+ * it returns values like ... 0.05, 0.1, 0.2, 0.5, 1, 2, 5, 10, ...
+ *
+ * @param the double value next to which the displayable value should be found
+ * @return the displayable value
+ */
+ public static double aBitBigger( double min ){
+ if( min <= 0 ) return 1;
+ double d = 1;
+ if( min < d ){
+ while( d * .5 > min ) {
+ d *= .5;
+ if( d * .4 > min ) d *= .4;
+ if( d * .5 > min ) d *= .5;
+ }
+ }
+ else{
+ while( d <= min ) {
+ d *= 2;
+ if( d <= min ) d *= 2.5;
+ if( d <= min ) d *= 2;
+ }
+ }
+ return d;
+ }
+
+ public boolean isBorderOpaque(){
+ return outer_border.isBorderOpaque();
+ }
+
+ private String stringOf( double v ){
+ if( (int)v == v ) return String.valueOf( (int)v );
+ return String.valueOf( v );
+ }
+
+ private double cutDec( double v, int dec ){
+ if( dec < 1 ){
+ String s = String.valueOf( v );
+ int index = s.indexOf(".");
+ if( index == -1 ) return Double.parseDouble(s);
+ return Double.parseDouble(s.substring(0, index));
+ }
+ double pot = Math.pow( 10, dec );
+ v = (int)( v * pot );
+ v /= pot;
+ if( v == (int)v ) return (int)v;
+ return v;
+ }
+
+ public Insets getBorderInsets(Component c){
+ if( under_construction ) System.out.println("ScaledBorder.getBorderInsets()");
+ if( !do_refresh && old_insets != null ) return old_insets;
+
+ Graphics g = c.getGraphics();
+
+ Insets insets = new Insets(0, 0, 0, 0);
+ if( show_outer_border ) insets = outer_border.getBorderInsets( c );
+
+ if( g == null ) return insets;
+
+ FontMetrics fm = g.getFontMetrics();
+ int fontAsc = fm.getAscent(),
+ fontHeight = fm.getHeight(),
+ digit_width = fm.stringWidth("0");
+
+ if( c instanceof DArea ){
+ DArea area = (DArea)c;
+ DMeasures m = area.getDMeasures();
+ DRectangle rect = m.getSourceOf( area.getDRectangle() );
+ src_minx = rect.x;
+ src_maxx = rect.x + rect.width;
+ src_miny = rect.y;
+ src_maxy = rect.y + rect.height;
+ x_scale = area.getDMeasures().x_scale;
+ y_scale = area.getDMeasures().y_scale;
+ }
+
+ // left:
+ if( y_label != null ) insets.left += fm.getAscent() + fm.getDescent();
+ insets.left += y_label2values * digit_width;
+ getSrcdY( fm, c.getSize(), src_miny, src_maxy );
+ int n, maxWidth = 0, decs;
+ if( y_scale != null ) decs = getDecs( y_scale.getImageOf( src_dY ) );
+ else decs = getDecs( src_dY );
+ n = (int)( src_miny / src_dY );
+ if( n * src_dY < src_miny ) n++;
+ while( n * src_dY <= src_maxy ){
+ double v = n * src_dY;
+ if( y_scale != null ) v = y_scale.getImageOf( v );
+ int w = fm.stringWidth( String.valueOf(cutDec( v, decs )) );
+ if( w > maxWidth ) maxWidth = w;
+ n++;
+ }
+ insets.left += 1 + y_label2border + maxWidth + digit_width / y_values2marker + marker_length;
+
+ // bottom:
+ insets.bottom += 1 + fontHeight + x_label2border;
+ if( x_label != null ) insets.bottom += fontHeight;
+
+ // top:
+ if( show_arrows ) insets.top += y_values2arrow + arrow_length;
+ insets.top += axis2border;
+
+ // right:
+ if( show_arrows ) insets.right += x_values2arrow + arrow_length;
+ insets.right += axis2border;
+ getSrcdX( fm, c.getSize(), src_minx, src_maxx );
+ decs = getDecs( src_dX );
+ n = (int)( src_maxx / src_dX );
+ if( n < 0 ) n ++;
+ int w = fm.stringWidth( String.valueOf(cutDec( n * src_dX, decs )) );
+ if( w / 2 > insets.right ) insets.right = w / 2;
+
+ old_insets = insets;
+ return insets;
+ }
+
+ private int getDecs( double v ){
+ if( under_construction ) System.out.println("ScaledBorder.getDecs()");
+ int decs = 0;
+ while( !( Math.pow( v / (int)v, 2 ) < 1.001 ) ) {
+ decs++;
+ v *= 10;
+ }
+ return decs;
+ }
+}
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/gp/.gitignore b/ea/ub8/EAUe8HohlochMutschler/framework/gp/.gitignore
new file mode 100644
index 0000000..98d05ee
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/gp/.gitignore
@@ -0,0 +1,15 @@
+/AlgorithmInterface.class
+/DummyGPIndividual.class
+/EaGui$1.class
+/EaGui$LogFct.class
+/EaGui.class
+/EaGuiCallback.class
+/EvolutionaryAlgorithm.class
+/GPIndividual.class
+/GPTree.class
+/InterfaceIndividual.class
+/RandomNumberGenerator.class
+/RatedIndividual.class
+/Selection.class
+/SelectionEnum.class
+/RegrIndividual.class
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/gp/AlgorithmInterface.java b/ea/ub8/EAUe8HohlochMutschler/framework/gp/AlgorithmInterface.java
new file mode 100644
index 0000000..77d7e06
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/gp/AlgorithmInterface.java
@@ -0,0 +1,7 @@
+package gp;
+
+public interface AlgorithmInterface extends Runnable {
+ public void start(int muu, int tmax, double pcross, double pmut, SelectionEnum selM, double selP);
+ public void stop();
+ public void setCallback(EaGuiCallback g);
+}
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/gp/DummyGPIndividual.java b/ea/ub8/EAUe8HohlochMutschler/framework/gp/DummyGPIndividual.java
new file mode 100644
index 0000000..8e6c547
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/gp/DummyGPIndividual.java
@@ -0,0 +1,110 @@
+package gp;
+
+public class DummyGPIndividual extends GPTree implements InterfaceIndividual {
+ static int maxHeight = 5;
+ // dont start with full height to allow for smaller trees. theyll grow by
+ // themselves.
+ static int initHeight = 3;
+ static int modeCreate = MODE_GROW;
+ static int modeMutate = MODE_GROW;
+
+ // /// The constructors will just call GPTree
+ public DummyGPIndividual(int h, int mode) {
+ super(null, h, mode);
+ }
+
+ public DummyGPIndividual(DummyGPIndividual y) {
+ super(y);
+ }
+
+ public DummyGPIndividual(DummyGPIndividual parent, int h, int mode) {
+ super(parent, h, mode);
+ }
+
+ // /// The following methods might look very similar in any implementation
+ @Override
+ public DummyGPIndividual clone() {
+ return new DummyGPIndividual(this);
+ }
+
+ @Override
+ public DummyGPIndividual makeRandomSubtree(int h, int mode) {
+
+ return new DummyGPIndividual(this, h - 1, mode);
+
+ }
+
+ @Override
+ public DummyGPIndividual copyTree(GPTree tree) {
+ return new DummyGPIndividual((DummyGPIndividual) tree);
+ }
+
+ @Override
+ public void crossover(InterfaceIndividual y) {
+ super.crossover((DummyGPIndividual) y, maxHeight);
+ }
+
+ @Override
+ public void mutate(double pMut) {
+ super.mutate(pMut, maxHeight, modeMutate);
+ }
+
+ public double distanceTo(InterfaceIndividual b) {
+ // not implemented
+ return 0;
+ }
+
+ @Override
+ public String getStringRepresentation() {
+ return super.toString();
+ }
+
+ @Override
+ public void defaultInit() {
+ initRandomTree(null, initHeight, modeCreate);
+ }
+
+ // ///// the following methods are problem specific, just dummies here
+ @Override
+ public int getBinaryCount() {
+ return 1;
+ }
+
+ @Override
+ public String getBinarySymbol(int i) {
+ return "o";
+ }
+
+ @Override
+ public int getTermCount() {
+ return 1;
+ }
+
+ @Override
+ public String getTermSymbol(int i) {
+ return ".";
+ }
+
+ @Override
+ public int getUnaryCount() {
+ return 1;
+ }
+
+ @Override
+ public String getUnarySymbol(int i) {
+ return "-";
+ }
+
+ @Override
+ public double evaluate() {
+ // what should a fit dummy look like?
+ return Math.pow(2, 1 + maxHeight) - nodeCount;
+ }
+
+ @Override
+ public double evalTreeAt(Object o) {
+ // TODO Auto-generated method stub
+ return 0;
+ }
+
+}
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/gp/EaGui.java b/ea/ub8/EAUe8HohlochMutschler/framework/gp/EaGui.java
new file mode 100644
index 0000000..18aea6a
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/gp/EaGui.java
@@ -0,0 +1,281 @@
+package gp;
+
+
+import java.awt.Color;
+import java.awt.Container;
+import java.awt.Dimension;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+import javax.swing.JButton;
+import javax.swing.JCheckBox;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JTextField;
+
+import DDrawing.DArea;
+import DDrawing.DFunction;
+import DDrawing.DPointSet;
+import DDrawing.ScaledBorder;
+
+/**
+ * @author mkron
+ */
+public class EaGui extends JFrame implements ActionListener, EaGuiCallback
+{
+ JButton pbStartStop;
+ JButton pbEnde;
+ DArea output;
+ JTextField tfMu;
+ JTextField tfTmax;
+ JTextField tfPcross;
+ JTextField tfPmut;
+ JCheckBox cbLog;
+ JCheckBox cbCompare;
+ boolean bAlgoRunning = false;
+ AlgorithmInterface algo;
+ DFunction logf = new LogFct();
+ public double mingz;
+ final int nFitCurves = 8;
+ DPointSet[] fitCurve = new DPointSet[nFitCurves];
+ final Color[] fitCurveColor = {Color.blue, Color.green,
+ Color.red, Color.cyan, Color.magenta, Color.black, Color.pink, Color.gray};
+ int nFitCurve = -1;
+
+ class LogFct extends DFunction
+ {
+ public boolean isDefinedOn( double source ){ return true; }
+ public double getImageOf( double source ){ return Math.exp( source ); }
+ public double getSourceOf( double target )
+ { if (target<=0) return Math.log(mingz/10); else return Math.log( target ); }
+ }
+
+ /**
+ * Define which algorithm to load.
+ */
+ protected void initAlgo() {
+ algo = new EvolutionaryAlgorithm(this);
+ algo.setCallback(this);
+ }
+
+ public EaGui()
+ {
+ super("Evolutionary Algorithms - GUI");
+
+ Container cp = getContentPane();
+ JLabel lb;
+ GridBagLayout gbl = new GridBagLayout();
+ GridBagConstraints gbc = new GridBagConstraints();
+
+ setBackground(Color.lightGray);
+ cp.setLayout(gbl);
+
+ gbc.gridx = 0; gbc.gridy = 0;
+ gbc.gridwidth = 1; gbc.gridheight = 1;
+ gbc.weightx = 1; gbc.weighty = 1;
+ gbc.insets = new Insets(5,5,5,5);
+ gbc.anchor = GridBagConstraints.EAST;
+ gbc.fill = GridBagConstraints.NONE;
+ lb = new JLabel("Mu");
+ gbl.setConstraints(lb, gbc);
+ cp.add(lb);
+ lb = new JLabel("tMax");
+ gbc.gridy = 1;
+ gbl.setConstraints(lb, gbc);
+ cp.add(lb);
+ lb = new JLabel("pCross");
+ gbc.gridy = 2;
+ gbl.setConstraints(lb, gbc);
+ cp.add(lb);
+ lb = new JLabel("pMut");
+ gbc.gridy = 3;
+ gbl.setConstraints(lb, gbc);
+ cp.add(lb);
+
+ lb = new JLabel("yScale");
+ gbc.gridy = 7;
+ gbl.setConstraints(lb, gbc);
+ cp.add(lb);
+ lb = new JLabel("Mode");
+ gbc.gridy = 8;
+ gbl.setConstraints(lb, gbc);
+ cp.add(lb);
+
+
+ tfMu = new JTextField("100",5);
+ gbc.gridx = 1; gbc.gridy = 0;
+ gbc.anchor = GridBagConstraints.EAST;
+ gbl.setConstraints(tfMu, gbc);
+ cp.add(tfMu);
+ tfTmax = new JTextField("50",5);
+ gbc.gridy = 1;
+ gbl.setConstraints(tfTmax, gbc);
+ cp.add(tfTmax);
+ tfPcross = new JTextField("0.9",5);
+ gbc.gridy = 2;
+ gbl.setConstraints(tfPcross, gbc);
+ cp.add(tfPcross);
+ tfPmut = new JTextField("0.01",5);
+ gbc.gridy = 3;
+ gbl.setConstraints(tfPmut, gbc);
+ cp.add(tfPmut);
+
+ cbLog = new JCheckBox("log");
+ cbLog.addActionListener(this);
+ gbc.gridy = 7;
+ gbl.setConstraints(cbLog, gbc);
+ cp.add(cbLog);
+ cbCompare = new JCheckBox("compare");
+ cbCompare.addActionListener(this);
+ gbc.gridy = 8;
+ gbl.setConstraints(cbCompare, gbc);
+ cp.add(cbCompare);
+
+ pbStartStop = new JButton("Start");
+ pbStartStop.addActionListener(this);
+ gbc.gridx = 0;
+ gbc.gridy = 9;
+ gbc.gridwidth = 2;
+ gbc.anchor = GridBagConstraints.CENTER;
+ gbl.setConstraints(pbStartStop, gbc);
+ cp.add(pbStartStop);
+ pbEnde = new JButton("Ende");
+ pbEnde.addActionListener(this);
+ gbc.gridy = 10;
+ gbl.setConstraints(pbEnde, gbc);
+ cp.add(pbEnde);
+
+ output = new DArea();
+ output.setBackground(Color.white);
+ output.setPreferredSize(new Dimension(400,400));
+ output.setMinRectangle( 0, 0, 100, 1 );
+ output.setAutoFocus(true);
+
+ gbc.gridx = 2; gbc.gridy = 0;
+ gbc.gridwidth = 10; gbc.gridheight = 10;
+ gbc.weightx = 5; gbc.weighty = 5;
+ gbc.fill = GridBagConstraints.BOTH;
+ gbl.setConstraints(output, gbc);
+ cp.add(output);
+
+ addWindowListener(
+ new WindowAdapter() {
+ public void windowClosing(WindowEvent e)
+ { dispose(); System.exit(0); }
+ }
+ );
+
+ for (int i=0;i=0); else
+ {
+ if (nFitCurve>=0)
+ {
+ for(int i=0;i0 && vmin matingPool;
+ long lastMillis = System.currentTimeMillis();
+
+ bStop = false;
+ while (!bStop) {
+ if (System.currentTimeMillis() > (lastMillis + 500)) {
+ try {
+ Thread.sleep(5);
+ } catch (InterruptedException e) {
+ }
+ }
+
+ try {
+ matingPool = selection.generateMatingPool(parents); // Selection
+
+ for (i = 0; i < mu; i++) // Replication
+ {
+ j = rand.nextInt(matingPool.size());
+ offsprings[i] = (InterfaceIndividual) (matingPool
+ .elementAt(j)).clone();
+ matingPool.removeElementAt(j);
+ }
+
+ for (i = 0; i < (mu - 1); i += 2) {
+ if (rand.nextDouble() < pCross) {
+ offsprings[i].crossover(offsprings[i + 1]);
+ }
+ }
+
+ for (i = 0; i < mu; i++) {
+ offsprings[i].mutate(pMut); // Mutation
+ }
+
+ parents = offsprings.clone();
+ } catch (Exception e) {
+ System.err.println(e.getMessage());
+ e.printStackTrace();
+ bStop = true;
+ }
+ if ((t++) >= tMax) {
+ bStop = true;
+ }
+ }
+
+ best = selection.findBest(parents);
+ if (gcb != null) {
+ gcb.algoStop(best);
+ }
+ // if ((gcb != null) && (best instanceof RegrIndividualSol)) {
+ // gcb.clearFun();
+ // gcb.plotFun(((RegrIndividualSol) best).trueFct());
+ // gcb.plotFun(((RegrIndividualSol) best).regFct());
+ // }
+ if (gcb == null) {
+ System.out.println(best.getStringRepresentation());
+ }
+ }
+}
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/gp/GPIndividual.java b/ea/ub8/EAUe8HohlochMutschler/framework/gp/GPIndividual.java
new file mode 100644
index 0000000..a76e322
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/gp/GPIndividual.java
@@ -0,0 +1,104 @@
+package gp;
+
+/**
+ * Define function sets using String arrays for simple configuration.
+ *
+ * @author mkron
+ *
+ */
+public abstract class GPIndividual extends GPTree implements
+ InterfaceIndividual {
+ // Vererbung niemals als abstraktion der allgemeinheit... wo habt ihr oo
+ // programmieren gelernt?
+ static String term[] = {};
+ static String unary[] = {};
+ static String binary[] = {};
+
+ // keine getter und setter... und dann auch noch package privat...
+ int maxHeight = 5;
+ int initHeight = 4;
+ int modeCreate = MODE_GROW;
+ int modeMutate = MODE_GROW;
+
+ public GPIndividual(GPIndividual y) {
+ super(y);
+ maxHeight = y.maxHeight;
+ initHeight = y.initHeight;
+ modeCreate = y.modeCreate;
+ modeMutate = y.modeMutate;
+ }
+
+ public GPIndividual(int initH, int maxH, int createMode, int mutateMode) {
+ super(null, initH, createMode);
+ init(initH, maxH, createMode, mutateMode);
+ }
+
+ public GPIndividual(GPIndividual parent, int h, int mode) {
+ super(parent, h, mode);
+ init(h, h, mode, mode);
+ }
+
+ // also wenn schon init dann verwendet sie bitte auch in allen
+ // konstruktoren.
+ protected void init(int initH, int maxH, int createMode, int mutateMode) {
+ this.maxHeight = maxH;
+ this.initHeight = initH;
+ this.modeCreate = createMode;
+ this.modeMutate = mutateMode;
+ }
+
+ @Override
+ public abstract Object clone();
+
+ protected void setFunctionSets(String term[], String unary[],
+ String binary[]) {
+ GPIndividual.term = term;
+ GPIndividual.unary = unary;
+ GPIndividual.binary = binary;
+ }
+
+ @Override
+ public int getTermCount() {
+ return term.length;
+ }
+
+ @Override
+ public int getUnaryCount() {
+ return unary.length;
+ }
+
+ @Override
+ public int getBinaryCount() {
+ return binary.length;
+ }
+
+ @Override
+ public void mutate(double pMut) {
+ super.mutate(pMut, maxHeight, modeMutate);
+ }
+
+ @Override
+ public String getTermSymbol(int i) {
+ return term[i];
+ }
+
+ @Override
+ public String getUnarySymbol(int i) {
+ return unary[i];
+ }
+
+ @Override
+ public String getBinarySymbol(int i) {
+ return binary[i];
+ }
+
+ @Override
+ public String getStringRepresentation() {
+ return super.toString();
+ }
+
+ @Override
+ public void defaultInit() {
+ initRandomTree(null, initHeight, modeCreate);
+ }
+}
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/gp/GPTree.java b/ea/ub8/EAUe8HohlochMutschler/framework/gp/GPTree.java
new file mode 100644
index 0000000..1da7f1e
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/gp/GPTree.java
@@ -0,0 +1,371 @@
+package gp;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Random;
+
+/**
+ * A Generic GP tree implementation.
+ *
+ * @author mkron
+ *
+ */
+public abstract class GPTree {
+ public static int MODE_FULL = 0;
+ public static int MODE_GROW = 1;
+
+ public Random ran = new Random();
+ // schonmal was von Javadoc für public Felder gehört?? Ihr könnt doch
+ // Schnittstellen nicht unkommentiert lassen.
+ public int arity; // Stelligkeit des Knotens aha!
+ protected int type; // Knotentyp . Schon mal was von Enums gehört...
+ public int height; // Hoehe des Baumes
+ public int nodeCount; // Knotenanzahl in diesem Baum
+ public GPTree up, left, right; // Zeiger auf Eltern- und Unterknoten
+
+ /**
+ * Constructor with tree initialization.
+ *
+ * @param rand
+ * @param parent
+ * @param h
+ * maximum height of the tree
+ * @param mode
+ * 0 is "full", 1 is "grow"
+ */
+ public GPTree(GPTree parent, int h, int mode) {
+ initRandomTree(parent, h, mode);
+ if (!this.isValid()) {
+ System.err.println("Error, invalid initialization!");
+ }
+ }
+
+ /**
+ * Copy constructor
+ *
+ * @param tree
+ * the other tree
+ */
+ public GPTree(GPTree tree) {
+ /*
+ * Dieser Konstruktor erzeugt mit Hilfe von copyTree() eine tiefe Kopie
+ * des Baumes tree.
+ */
+ if (!tree.isValid()) {
+ throw new RuntimeException("not valid tree to copy");
+ }
+ this.arity = tree.arity;
+ this.type = tree.type;
+ this.height = tree.height;
+ this.nodeCount = tree.nodeCount;
+ this.up = tree.up;
+ if (tree.left != null) {
+ left = copyTree(tree.left);
+ left.up = this;
+ }
+ if (tree.right != null) {
+ right = copyTree(tree.right);
+ right.up = this;
+ }
+ if (!this.isValid()) {
+ throw new RuntimeException("after copy no valid tree");
+ }
+ }
+
+ /**
+ * Random tree initialization.
+ *
+ * @param parent
+ * @param maxH
+ * maximum height of the new tree
+ * @param mode
+ * 0 is "full", 1 is "grow"
+ */
+ public void initRandomTree(GPTree parent, int maxH, int mode) {
+ /*
+ * Erzeugen Sie mit Hilfe von makeRandomSubtree() einen zufaelligen
+ * Baum. Verwenden Sie nicht direkt rekursiv den Konstruktor von GPTree,
+ * da sonst abgeleitete Typen mit dem Typ GPTree vermischt werden kann.
+ */
+ // :-D :-D whooo das kommentar ist der hammer, da hat einer Vererbung
+ // und Typen einfach nicht verstanden
+
+ this.up = parent;
+ makeRandomSubtree(maxH, mode);
+
+ }
+
+ private int getFunctionCount() {
+ return getTermCount() + getUnaryCount() + getBinaryCount();
+ }
+
+ // ************* abstract methods
+ // these two are abstract so that the subtypes can return the right type
+ // they should again use GPTree's (copy) constructor!
+
+ // na wie wärs den mit Javadoc ???
+ public abstract GPTree makeRandomSubtree(int h, int mode);
+
+ public abstract GPTree copyTree(GPTree tree);
+
+ public abstract double evalTreeAt(Object o);
+
+ public abstract int getTermCount(); // return number of terminals
+
+ public abstract int getUnaryCount(); // return number of unary functions //
+ // Toller Javadoc, so als
+ // Kommentar...
+
+ public abstract int getBinaryCount(); // return number of binary functions
+
+ public abstract String getTermSymbol(int i); // return String for a terminal
+
+ public abstract String getUnarySymbol(int i); // return String for a unary
+ // function
+
+ public abstract String getBinarySymbol(int i); // return String for a binary
+ // function
+
+ // ************* abstract methods end
+
+ @Override
+ public String toString() {
+ /*
+ * Stellt den Baum durch eine Zeichenkette dar.
+ */
+ switch (arity) {
+ case 0:
+ return getTermSymbol(type);
+ case 1:
+ return getUnarySymbol(type) + "(" + left.toString() + ")";
+ case 2:
+ return getBinarySymbol(type) + "(" + left.toString() + ","
+ + right.toString() + ")";
+ }
+ System.err.println("Invalid arity in GPTree!"); // Exceptions ? **
+ return "";
+ }
+
+ // Hilfsfunktion zum Testen des Baumes auf Konsistenz
+ private boolean isValid() {
+ if (getFunctionCount() == 0) {
+ return true; // assume correctness for an empty function set
+ }
+ switch (arity) {
+ case 0:
+ boolean a = ((left == null) && (right == null) && (height == 0) && (nodeCount == 1));
+ if (!a) {
+ System.out.println(a + "case 0");
+ System.out.println(left);
+ System.out.println(right);
+ System.out.println(height);
+ System.out.println(nodeCount);
+ System.out.println("_________");
+ }
+ return a;
+ case 1:
+ boolean b = ((left != null)
+ && (right == null)
+ && (height == (left.height + 1))
+ /* && (nodeCount == (left.nodeCount + 1)) */&& left
+ .isValid() && (left.up == this));
+ if (!b) {
+ System.out.println(b + "case1");
+ System.out.println("left" + left);
+ System.out.println("right " + right);
+ System.out
+ .println("height " + height + " " + (left.height + 1));
+ System.out.println("nodecount " + nodeCount + " "
+ + (left.nodeCount + 1));
+ System.out.println("parent " + (left.up == this));
+ System.out.println("_________");
+ }
+ return b;
+ case 2:
+ boolean c = ((left != null) && (right != null)
+ && (height == (Math.max(left.height, right.height) + 1))
+ /* && (nodeCount == (left.nodeCount + right.nodeCount + 1)) */
+ && left.isValid() && right.isValid() && (left.up == this) && (right.up == this));
+ if (!c) {
+ System.out.println(c + "case2");
+ System.out.println("left" + left);
+ System.out.println("right " + right);
+ System.out.println("height " + height + " "
+ + (Math.max(left.height, right.height) + 1));
+ System.out.println("nodecount " + nodeCount + " "
+ + (left.nodeCount + right.nodeCount + 1));
+ System.out.println("parent " + (left.up == this));
+ System.out.println("_________");
+ }
+ return c;
+ }
+ return false;
+ }
+
+ /**
+ * Perform a GP crossover between two binary trees.
+ *
+ * @param otherTree
+ * the crossover partner
+ * @param h
+ * the maximal height
+ */
+ public void crossover(GPTree otherTree, int h) {
+ /*
+ * Crossover zwischen den Baeumen this und tree wird ausgefuehrt.
+ *
+ * Hinweis: wählen Sie zuerst zwei zufällige Teilbäume von this und
+ * otherTree. Dabei kann eine Vorstellung der Numerierung der
+ * Unterknoten helfen.
+ *
+ * ist die maximale höhe der teilbäume gemeint? nichtmal gescheite
+ * javadoc gibts..
+ */
+
+ if (!this.isValid()) {
+
+ throw new RuntimeException(" this not valid before crossover");
+ }
+ if (!otherTree.isValid()) {
+
+ throw new RuntimeException(" othertree not valid before crossover");
+ }
+
+ List thisTrees = new ArrayList();
+ List otherTrees = new ArrayList();
+ getAllTreesSameOrLower(this, h, thisTrees);
+ GPTree ts = null;
+ GPTree os = null;
+ if ((thisTrees.size() > 0)) {
+ ts = thisTrees.get(ran.nextInt(thisTrees.size()));
+ } else {
+ return;
+ }
+ getAllTreesSameHight(otherTree, ts.height, otherTrees);
+ if ((otherTrees.size() > 0)) {
+ os = otherTrees.get(ran.nextInt(otherTrees.size()));
+ } else {
+ return;
+ }
+ if (os.up != null) {
+ os.up.nodeCount -= os.nodeCount;
+ os.up.nodeCount += ts.nodeCount;
+
+ if (os.up.left.equals(os)) {
+ os.up.left = ts;
+ } else {
+ os.up.right = ts;
+ }
+ }
+ if (ts.up != null) {
+ ts.up.nodeCount -= ts.nodeCount;
+ ts.up.nodeCount += os.nodeCount; // todo notecount der eltern
+ // anpassen --> das wird jetzt
+ // echt zu viel code für die
+ // paar punkte . Wir ignorieren
+ // jetzt einfach den nodecount
+ // bei der prüfung braucht man
+ // eh nie
+ if (ts.up.left.equals(ts)) {
+ ts.up.left = os;
+ } else {
+ ts.up.right = os;
+ }
+ }
+ GPTree op = os.up;
+ os.up = ts.up;
+ ts.up = op;
+ if (!this.isValid()) {
+ throw new RuntimeException("this is not valid after crossover");
+ }
+ if (!otherTree.isValid()) {
+ throw new RuntimeException(
+ "other tree is not valid after crossover");
+ }
+
+ }
+
+ private void getAllTreesSameOrLower(GPTree start, int h, List result) {
+ if (start.height >= 0) {
+ if (start.height <= h) {
+ result.add(start);
+ }
+ if (start.left != null) {
+ getAllTreesSameOrLower(start.left, h, result);
+ }
+ if (start.right != null) {
+ getAllTreesSameOrLower(start.right, h, result);
+ }
+ }
+ };
+
+ private void getAllTreesSameHight(GPTree start, int h, List result) {
+ if (start.height >= h) {
+ if (start.height == h) {
+ result.add(start);
+ return;
+ }
+ if (start.left != null) {
+ getAllTreesSameHight(start.left, h, result);
+ }
+ if (start.right != null) {
+ getAllTreesSameHight(start.right, h, result);
+ }
+ }
+ };
+
+ /**
+ * @param pMut
+ * propability of mutation
+ * @param h
+ * hight of the random subtree
+ * @param mode
+ * 0 is "full", 1 is "grow"
+ */
+ public void mutate(double pMut, int h, int mode) {
+ /*
+ * Der Baum wird mit einer Wahrscheinlichkeit von pMut mutiert und an
+ * einer zufaelligen Stelle durch einen zufaelligen Baum ersetzt.
+ */
+
+ // Wie ist das zu verstehen? eine zufällige Stelle dieses Teilbaums?
+
+ if (ran.nextDouble() <= pMut) {
+ GPTree sub = null;
+ GPTree ne = null;
+ List treesOfSameHight = new ArrayList();
+ getAllTreesSameHight(this, h, treesOfSameHight);
+ if (treesOfSameHight.size() <= 0) {
+ return;
+ }
+ sub = treesOfSameHight.get(ran.nextInt(treesOfSameHight.size()));
+ ne = makeRandomSubtree(h, mode); // es wird immer nur ein Baum mit
+ // wieder der gleichen höhe
+ // erstellt wie der vorherige
+ // Hier funktioniert unser code nicht da makeRandom subtree nur this
+ // ändert und wir ja hier nicht auf subtypen casten können.
+ // So und hier geben wir es auf die Aufgabe zu lösen, mit der
+ // Hoffnung dass ihr uns nie wieder so schlecht kommentierten und so
+ // häufig gegen Java-Spezifikationen verstoßenden Code gebt wie
+ // diesen.
+
+ ne.up = sub.up;
+ if (ne.up != null) {
+ sub.up.nodeCount -= sub.nodeCount;
+ sub.up.nodeCount += ne.nodeCount;
+ if (sub.up.left.equals(sub)) {
+ sub.up.left = ne;
+ } else {
+ sub.up.right = ne;
+ }
+ sub.up = null;
+ }
+
+ }
+ if (!this.isValid()) {
+ System.err.println(this.toString() + " not valid mutation");
+ throw new RuntimeException("");
+ }
+ }
+
+}
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/gp/InterfaceIndividual.java b/ea/ub8/EAUe8HohlochMutschler/framework/gp/InterfaceIndividual.java
new file mode 100644
index 0000000..971f024
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/gp/InterfaceIndividual.java
@@ -0,0 +1,43 @@
+package gp;
+
+public interface InterfaceIndividual {
+ /**
+ * Evaluate the individual and return the fitness.
+ *
+ * @return the individual fitness
+ */
+ public double evaluate();
+
+ /**
+ * A crossover operator.
+ *
+ * @param y
+ */
+ public void crossover(InterfaceIndividual y);
+
+ /**
+ * This method performs a randomized mutation of every gene.
+ *
+ * @param pMut
+ */
+ public void mutate(double pMut);
+
+ /**
+ * The replication operator. WTF!!
+ *
+ * @return
+ */
+ public Object clone();
+
+ /**
+ * Return a String representing the individual.
+ *
+ * @return a String representing the individual
+ */
+ public String getStringRepresentation();
+
+ /**
+ * This method initializes the genotype randomly
+ */
+ public void defaultInit();
+}
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/gp/RandomNumberGenerator.java b/ea/ub8/EAUe8HohlochMutschler/framework/gp/RandomNumberGenerator.java
new file mode 100644
index 0000000..d0d9fe4
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/gp/RandomNumberGenerator.java
@@ -0,0 +1,283 @@
+package gp;
+
+import java.util.ArrayList;
+import java.util.Random;
+
+/**
+ * A collection of static functions concerned with pseudo random numbers.
+ *
+ */
+public class RandomNumberGenerator extends Random {
+ private static Random random;
+ private static long randomSeed;
+ /**
+ *
+ */
+ static {
+ randomSeed=System.currentTimeMillis();
+ random=new Random(randomSeed);
+ }
+ /**
+ *
+ */
+ public static void setRandomSeed(long new_seed){
+ //counter++;
+ randomSeed=new_seed;
+ if (randomSeed == 0) setRandomSeed();
+ else random.setSeed(randomSeed);
+ }
+
+ /**
+ * Set the random seed without replacing zero with current system time.
+ */
+ public static void setRandomSeedStrict(long new_seed){
+ randomSeed=new_seed;
+ random.setSeed(randomSeed);
+ }
+ /**
+ *
+ */
+ public static void setRandomSeed() {
+ randomSeed=System.currentTimeMillis();
+ random=new Random(randomSeed);
+ }
+ /**
+ *
+ */
+ public static void setRandom(Random base_random) {
+ random=base_random;
+ }
+ /**
+ *
+ */
+ public static long getRandomSeed() {
+ return randomSeed;
+ }
+
+ /**
+ * Returns 0 or 1 evenly distributed.
+ */
+ public static int randomInt() {
+ return randomInt(0,1);
+ }
+
+ /**
+ * Returns an evenly distributes int value between zero and
+ * upperLim-1.
+ * @param upperLim upper exclusive limit of the random int
+ */
+ public static int randomInt(int upperLim) {
+ return randomInt(0,upperLim-1);
+ }
+
+ /** This method returns a evenly distributed int value.
+ * The boundarys are included.
+ * @param lo Lower bound.
+ * @param hi Upper bound.
+ * @return int
+ */
+ public static int randomInt(int lo,int hi) {
+ if (hi hi)) {
+ System.err.println("Error in RNG.randomInt!");
+ result = Math.abs(random.nextInt()%(hi-lo+1))+lo;
+ }
+ return result;
+ }
+
+ /**
+ *
+ */
+ public static long randomLong() {
+ return random.nextLong();
+ }
+ /**
+ *
+ */
+ public static long randomLong(long lo,long hi) {
+ return (Math.abs(random.nextLong())%(hi-lo+1))+lo;
+ }
+
+ /**
+ * This method returns a random permutation of n int values
+ * @param length The number of int values
+ * @return The permutation [0-length-1]
+ */
+ public static int[] randomPerm(int length) {
+ ArrayList intList = new ArrayList(length);
+ int[] result = new int[length];
+ for (int i = 0; i < length; i++) {
+ intList.add(new Integer(i));
+ }
+ for (int i = 0; i < length-1; i++) {
+ int index = randomInt(intList.size());
+ result[i] = intList.get(index);
+ intList.remove(index);
+
+ }
+ if (intList.size()>1) System.err.println("Error in randomPerm!");
+ result[length-1] = intList.get(0);
+ return result;
+ }
+
+ /**
+ *
+ */
+ public static float randomFloat() {
+ return random.nextFloat();
+ }
+ /**
+ *
+ */
+ public static float randomFloat(float lo,float hi) {
+ return (hi-lo)*random.nextFloat()+lo;
+ }
+ /**
+ * A random double value between 0 and 1.
+ */
+ public static double randomDouble() {
+ return random.nextDouble();
+ }
+ /**
+ *
+ */
+ public static double randomDouble(double lo,double hi) {
+ return (hi-lo)*random.nextDouble()+lo;
+ }
+
+ /**
+ * Create a uniform random vector within the given bounds.
+ */
+ public static double[] randomDoubleArray(double[] lo,double[] hi) {
+ double[] xin = new double[lo.length];
+ for (int i=0;i 0) { // letzter Knoten hat höhe 0
+ if ((mode == 0)) {
+ this.arity = ran.nextInt(2) + 1;
+ } else {
+ this.arity = ran.nextInt(3);
+ }
+ } else {
+ this.arity = 0;
+ }
+
+ switch (arity) {
+ case 0:
+ type = ran.nextInt(3);
+ nodeCount = 1;
+ height = 0;
+ left = null;
+ right = null;
+ break;
+ case 1:
+ type = ran.nextInt(3);
+ left = new RegrIndividual(this, h - 1, mode);
+ left.up = this;
+ right = null;
+ nodeCount = left.nodeCount + 1;
+ height = left.height + 1;
+ break;
+ case 2:
+ type = ran.nextInt(3);
+ left = new RegrIndividual(this, h - 1, mode);
+ left.up = this;
+ right = new RegrIndividual(this, h - 1, mode);
+ right.up = this;
+ nodeCount = right.nodeCount + left.nodeCount + 1;
+ height = left.height > right.height ? left.height + 1
+ : right.height + 1;
+ break;
+ }
+ return this;
+ }
+
+ @Override
+ public GPTree copyTree(GPTree tree) {
+ return new RegrIndividual((RegrIndividual) tree);
+ }
+
+ @Override
+ public double evalTreeAt(Object o) {
+ RegrIndividual a = (RegrIndividual) o;
+ double sum = 0;
+ for (int i = -100; i < 101; i++) {
+ Math.pow(2, a.getY(i) - a.getF(i));
+ }
+ return sum;
+ }
+
+ @Override
+ public int getTermCount() {
+ return term.length;
+ }
+
+ @Override
+ public int getUnaryCount() {
+ return unary.length;
+ }
+
+ @Override
+ public int getBinaryCount() {
+ return binary.length;
+ }
+
+ @Override
+ public String getTermSymbol(int i) {
+ return term[i];
+ }
+
+ @Override
+ public String getUnarySymbol(int i) {
+ return unary[i];
+ }
+
+ @Override
+ public String getBinarySymbol(int i) {
+ return binary[i];
+ }
+
+ private double getY(double x) {
+ return x + Math.pow(2, x) + Math.pow(3, x) + Math.pow(4, x);
+ }
+
+ private double getF(double x) {
+ RegrIndividual l = (RegrIndividual) left;
+ RegrIndividual r = (RegrIndividual) right;
+ // System.out.println(this);
+ switch (arity) {
+ case 0:
+ switch (getTermSymbol(type)) {
+ case "1":
+ return 1;
+ case "x":
+ return x;
+ case "pi":
+ return Math.PI;
+ }
+ break;
+ case 1:
+ switch (getUnarySymbol(type)) {
+ case "exp":
+ return Math.exp(l.getF(x));
+ case "sin":
+ return Math.sin(l.getF(x));
+ case "cos":
+ return Math.cos(l.getF(x));
+
+ }
+ break;
+ case 2:
+ switch (getBinarySymbol(type)) {
+ case "+":
+ return l.getF(x) + r.getF(x);
+ case "-":
+ return l.getF(x) - r.getF(x);
+ case "*":
+ return l.getF(x) * r.getF(x);
+
+ }
+ break;
+
+ }
+ throw new RuntimeException("wrong arity" + arity);
+
+ }
+}
diff --git a/ea/ub8/EAUe8HohlochMutschler/framework/gp/Selection.java b/ea/ub8/EAUe8HohlochMutschler/framework/gp/Selection.java
new file mode 100644
index 0000000..725ee7a
--- /dev/null
+++ b/ea/ub8/EAUe8HohlochMutschler/framework/gp/Selection.java
@@ -0,0 +1,220 @@
+package gp;
+
+import java.util.Arrays;
+import java.util.Random;
+import java.util.Vector;
+
+class RatedIndividual implements Comparable
+{
+ public InterfaceIndividual indy;
+ public double val;
+
+ public RatedIndividual(InterfaceIndividual individual, double value)
+ {
+ indy = individual;
+ val = value;
+ }
+
+ public int compareTo(RatedIndividual y)
+ {
+ double w = y.val;
+ if (valw) return 1;
+ else return 0;
+ }
+ }
+}
+
+enum SelectionEnum {
+ best, nonlinRank;
+}
+
+/**
+ * Selection class.
+ */
+public class Selection {
+ // Selection enthaelt Selektionsmethoden fuer den Algorithmus EvolutionaryAlgorithm.java.
+ // Die Auswahl wird ueber das GUI getroffen und als Parameter an den Konstruktor uebergeben.
+ static double worstFit=Math.pow(10,100);
+
+ double selParam;
+ double sigmaShare;
+ EaGuiCallback gcb;
+ int tAct;
+ SelectionEnum method;
+ boolean doSharing;
+
+ public Selection(SelectionEnum meth, double selP, Random random, EaGuiCallback g, boolean doShare, double sigShare)
+ {
+ // Initialisiert ein Selection-Objekt mit Hilfe der von der GUI übergebenen Parameter.
+ init(meth, selP, random, g, doShare, sigShare);
+ }
+
+ public Selection(SelectionEnum meth, double selP, Random random, EaGuiCallback g)
+ {
+ // Initialisiert ein Selection-Objekt mit Hilfe der von der GUI übergebenen Parameter.
+ init(meth, selP, random, g, false, 1);
+ }
+
+ protected void init(SelectionEnum meth, double selP, Random random, EaGuiCallback g, boolean doShare, double sigShare) {
+ selParam = selP;
+ gcb = g;
+ tAct = 0;
+ method = meth;
+ doSharing = false;
+ sigmaShare = 10.;
+ }
+
+ public Vector generateMatingPool(InterfaceIndividual[] pop)
+ {
+ // Gibt einen Vektor aus Individual zurueck, abhaengig von der gewaehlten Methode.
+ switch (method)
+ {
+ case best: return best(pop);
+ case nonlinRank: return nonlinRanking(pop);
+ }
+ System.err.println("Selection method not implemented!");
+ return null;
+ }
+
+
+ public InterfaceIndividual findBest(InterfaceIndividual[] pop)
+ {
+ // Gibt das beste Individuum aus pop zurueck.
+ RatedIndividual a[] = scanPopulation(pop);
+ return a[0].indy;
+ }
+
+ public void printBest(InterfaceIndividual[] pop, int n)
+ {
+ // Gibt das beste Individuum aus pop zurueck.
+
+ RatedIndividual a[] = scanPopulation(pop);
+ for (int i=0; i stochasticUniversalSampling(RatedIndividual[] a) {
+ // Gibt einen Vektor aus Individual zurueck, erzeugt nach der Methode Stochastic Universal Sampling.
+ // Grundlegend ist, dass die Summe der Bewertungen a[i].v gleich der Populationsgroesse n ist.
+ // Dann werden n Individuen ausgewaehlt. z wird zufaellig initialisiert und spiegelt die Position
+ // des ersten Zeigers wieder. Alle anderen Zeiger folgen im Abstand 1. Fuer jeden Abschnitt a[i].v
+ // des Gluecksrads wird geprueft, wie viele Zeiger darauf zeigen.
+ double s=0, z=RandomNumberGenerator.randomDouble();
+ int i, n=a.length;
+ Vector matingPool = new Vector();
+
+ for (i=0; iz) {matingPool.add(a[i].indy); z++;}
+ }
+ return matingPool;
+ }
+
+ RatedIndividual[] scanPopulation(InterfaceIndividual[] pop)
+ {
+ // Erzeugt ein sortiertes RatedIndividual-Array aus einem Individual-Array,
+ // indem fuer jedes Individual seine Funktion eval() ausgewertet wird.
+ // Ausserdem werden bester, mittlerer und schlechtester Fitnesswert in der GUI dargestellt.
+
+ int i, n=pop.length;
+ double fit, sum=0;
+ double worst=Double.NEGATIVE_INFINITY;
+
+ RatedIndividual a[] = new RatedIndividual[n];
+ for (i=0; i worst) worst = fit;
+ }
+
+ Arrays.sort(a);
+ if (gcb!=null) {
+ if (tAct == 0) System.out.println("t Best Mean Worst");
+ gcb.plotFit(tAct++,a[0].val,sum/n,a[n-1].val, a[0].indy);
+ }
+ else System.out.println(tAct + " " + a[0].val + " " + sum/n + " " + a[n-1].val);
+ return a;
+ }
+
+
+ Vector dummy(InterfaceIndividual[] pop)
+ {
+ int i, n=pop.length;
+ RatedIndividual a[] = scanPopulation(pop);
+ Vector matingPool = new Vector();
+
+ for (i=0; i best(InterfaceIndividual[] pop)
+ {
+ int i, n=pop.length;
+ RatedIndividual a[] = scanPopulation(pop);
+ Vector matingPool = new Vector();
+
+ for (i=0; i linRanking(InterfaceIndividual[] pop) {
+ // Gibt einen Vektor aus Individual zurueck gemaess linearem Ranking.
+ // Der Parameter selemParam aus der GUI entspricht eta^+ im Abschnitt 5.6.3 des Skripts.
+ // (eta^+)-(eta^-) ist somit 2*(selParam-1).
+ // Die -1 im Skript fuer den Index i entfaellt aufgrund des Startwerts 0.
+ // Der Faktor 1/lambda im Skript entfaellt aufgrund der Reskalierung, bei der
+ // die Bewertungen mit der Populationsgroesse multipliziert werden.
+ int i, n=pop.length;
+ RatedIndividual a[] = scanPopulation(pop);
+ double Ediff = 2*(selParam-1)/(n-1);
+
+ for (i=0; i nonlinRanking2(InterfaceIndividual[] pop) {
+ // Gibt einen Vektor aus Individual zurueck gemaess nichtlinearem Ranking, Variante, die
+ // keine Reskalierung benötigt.
+ // Die Bewertungen der Individuen wird dazu fuer stochasticUniversalSampling() skaliert.
+ int i, n=pop.length;
+ RatedIndividual a[] = scanPopulation(pop);
+ double s = n/Math.pow(n,selParam);
+
+ for (i=0; i nonlinRanking(InterfaceIndividual[] pop) {
+ int i, n=pop.length;
+ RatedIndividual a[] = scanPopulation(pop);
+ double sum = 0.;
+
+ // Compute expected number of descendants for each individual based on its rank
+ for (i=0; i$0.05. Ab t=45 wird die Lösung nahezu erreicht.
Daraufhin wird sie schlechter.\\
"Runs performed: 25, reached target 0 times with threshold 0.001, rate 0.0