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