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 }