001    // GraphLab Project: http://graphlab.sharif.edu
002    // Copyright (C) 2008 Mathematical Science Department of Sharif University of Technology
003    // Distributed under the terms of the GNU General Public License (GPL): http://www.gnu.org/licenses/
004    package graphlab.plugins.graphgenerator.generators;
005    
006    import graphlab.graph.graph.EdgeModel;
007    import graphlab.graph.graph.GraphModel;
008    import graphlab.graph.graph.VertexModel;
009    import graphlab.platform.lang.ArrayX;
010    import graphlab.platform.parameter.Parameter;
011    import graphlab.platform.parameter.Parametrizable;
012    import graphlab.plugins.graphgenerator.GraphGenerator;
013    import graphlab.plugins.graphgenerator.core.PositionGenerators;
014    import graphlab.plugins.graphgenerator.core.SimpleGeneratorInterface;
015    import graphlab.plugins.graphgenerator.core.extension.GraphGeneratorExtension;
016    
017    import java.awt.*;
018    
019    /**
020     * @author azin azadi, Hoshmand Hasannia
021     */
022    //@CommandAttitude(name = "generate_tree" , abbreviation = "_g_t"
023    //        ,description = "generate a tree with depth and degree")
024    public class TreeGenerator implements GraphGeneratorExtension, Parametrizable, SimpleGeneratorInterface {
025        @Parameter(name = "Height")
026        public static Integer depth = 3;
027        @Parameter(name = "Degree")
028        public static Integer degree = 3;
029        @Parameter(name = "Positioning Method")
030        public static ArrayX<String> m =
031                new ArrayX<String>("Circular", "Backward", "UpDown");
032    
033    //    String positioning;
034    
035        int n;
036        GraphModel g;
037    
038        public void setWorkingGraph(GraphModel g) {
039            this.g = g;
040        }
041    
042    /*    public NotifiableAttributeSet getParameters() {
043            PortableNotifiableAttributeSetImpl a=new PortableNotifiableAttributeSetImpl();
044            a.put ("Degree",3);
045            a.put ("Height",3);
046            a.put("Positioning Method",new ArrayX<String>("Circular", "Backward" , "UpDown"));
047            return a;
048        }
049    
050        public void setParameters(NotifiableAttributeSet parameters) {
051            d = Integer.parseInt(""+parameters.getAttributes().get("Degree"));
052            h = Integer.parseInt(""+parameters.getAttributes().get("Height"));
053            positioning = ((ArrayX)parameters.getAttributes().get("Positioning Method")).getValue().toString();
054            n = (int) ((Math.pow(d,h+1)-1)/(d-1));
055        }*/
056    
057        public String getName() {
058            return "Complete Tree";
059        }
060    
061        public String getDescription() {
062            return "Generates a complete tree";
063        }
064    
065        VertexModel[] v;
066    
067        public VertexModel[] getVertices() {
068            n = (int) ((Math.pow(degree, depth + 1) - 1) / (degree - 1));
069            VertexModel[] ret = new VertexModel[n];
070            for (int i = 0; i < n; i++)
071                ret[i] = new VertexModel();
072            v = ret;
073            return ret;
074        }
075    
076        public EdgeModel[] getEdges() {
077            n = (int) ((Math.pow(degree, depth + 1) - 1) / (degree - 1));
078            EdgeModel[] ret = new EdgeModel[n - 1];
079            for (int i = 0; i < n - 1; i++) {
080                ret[i] = new EdgeModel(v[i + 1], v[i / degree]);
081            }
082            return ret;
083        }
084    
085        public Point[] getVertexPositionsBackward() {
086            Point[] ret = new Point[n];
087            ret[0] = new Point(20000 / 2, 20000 / 2);
088            int last = 1;
089            int ww = 20000;
090            int hh = 20000;
091            int rad0 = Math.min(ww, hh) / 2;
092            for (int i = 0; i < n - Math.pow(degree, depth); i++) {
093                int h = (int) ((Math.log((i + 1) * (degree - 1))) / Math.log(degree));
094                int rad = (i == 0 ? rad0 : (int) (rad0 / Math.pow(2.5, h)));
095                Point _p[] = PositionGenerators.circle(rad, ret[i].x, ret[i].y, degree);
096                System.arraycopy(_p, 0, ret, last, degree);
097                last += degree;
098            }
099            return ret;
100        }
101    
102        public Point[] getVertexPositions() {
103            String positioning = m.getValue();
104            n = (int) ((Math.pow(degree, depth + 1) - 1) / (degree - 1));
105            if (positioning.equals("Backward")) {
106                return getVertexPositionsBackward();
107            } else if (positioning.equals("UpDown")) {
108                return getVertexPositionUpdown();
109            }
110            return getVertexPositionsCircular();
111        }
112    
113    
114        private Point[] getVertexPositionUpdown() {
115            System.out.println("n" + n + "deg" + degree + "hei" + depth);
116            Point[] ret = new Point[n];
117            double vwidth = 200;
118            double vheight = 200;
119            int r = 10;
120            double yratio = vheight / depth;
121            for (int i = depth; i >= 0; i--) {
122                int vertexnInRow = (int) Math.pow(degree, i);
123                double xratio = vwidth / (vertexnInRow + 1);
124                int firstInRow = 0;
125                for (int j = 0; j <= i - 1; j++) {
126                    firstInRow += Math.pow(degree, j);
127                }
128                firstInRow++;
129    
130                for (int j = 1; j <= vertexnInRow; j++) {
131                    double x = j * xratio;
132                    ret[firstInRow + j - 2] = new Point((int) x, (int) yratio * i);
133                }
134            }
135            return ret;
136        }
137    
138        public Point[] getVertexPositionsCircular() {
139            Point[] ret = new Point[n];
140            ret[0] = new Point(0, 0);
141            int last = 1;
142            for (int h = 1; h <= depth; h++) {
143                int n = (int) Math.pow(degree, h);
144                Point p[] = PositionGenerators.circle(30 * h * h, 0, 0, n);
145                System.arraycopy(p, 0, ret, last, n);
146                last += n;
147            }
148            return ret;
149        }
150    
151        public String checkParameters() {
152            return null;
153        }
154    
155        public GraphModel generateGraph() {
156            return GraphGenerator.getGraph(false, this);
157        }
158    
159        /**
160         * generates a Complete Tree with given parameters
161         */
162        public static GraphModel generateTree(int depth, int degree) {
163            TreeGenerator.depth = depth;
164            TreeGenerator.degree = degree;
165            return GraphGenerator.getGraph(false, new TreeGenerator());
166        }
167    
168    }