{"id":28532545,"url":"https://github.com/dyekuu/graph-drawing-contest-2020","last_synced_at":"2025-06-29T08:37:51.659Z","repository":{"id":100483792,"uuid":"250806159","full_name":"DyeKuu/Graph-Drawing-Contest-2020","owner":"DyeKuu","description":"Java project dedicated to Graph Drawing Contest 2019-2020, ranking 5th","archived":false,"fork":false,"pushed_at":"2020-10-24T22:06:12.000Z","size":8872,"stargazers_count":0,"open_issues_count":0,"forks_count":1,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-09T15:53:13.062Z","etag":null,"topics":["algorithms","directedgraph","force-directed","graph-drawing","heuristic-search","java","localsearch","upward-drawing"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"lgpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/DyeKuu.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2020-03-28T13:47:43.000Z","updated_at":"2021-09-12T10:16:23.000Z","dependencies_parsed_at":"2023-05-15T04:45:11.621Z","dependency_job_id":null,"html_url":"https://github.com/DyeKuu/Graph-Drawing-Contest-2020","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/DyeKuu/Graph-Drawing-Contest-2020","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DyeKuu%2FGraph-Drawing-Contest-2020","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DyeKuu%2FGraph-Drawing-Contest-2020/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DyeKuu%2FGraph-Drawing-Contest-2020/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DyeKuu%2FGraph-Drawing-Contest-2020/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/DyeKuu","download_url":"https://codeload.github.com/DyeKuu/Graph-Drawing-Contest-2020/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/DyeKuu%2FGraph-Drawing-Contest-2020/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261069464,"owners_count":23105202,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["algorithms","directedgraph","force-directed","graph-drawing","heuristic-search","java","localsearch","upward-drawing"],"created_at":"2025-06-09T15:38:31.386Z","updated_at":"2025-06-29T08:37:51.649Z","avatar_url":"https://github.com/DyeKuu.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\r\n![](https://raw.github.com/DyeKuu/Graph-Drawing-Contest-2019-2020/master/report/icon.jpg)\r\n# Java project for Graph Drawing Contest 2020\r\n[![standard-readme compliant](https://img.shields.io/badge/readme%20style-standard-brightgreen.svg?style=flat-square)](https://github.com/RichardLitt/standard-readme)\r\n### Author: Yuyang ZHAO, Kunhao ZHENG, Luca Castelli Aleardi\r\n### This project has ranked 5th place in the Graph Drawing Contest 2020 during the 28th International Symposium on Graph Drawing and Network Visualization\r\n\r\n\r\n## Table of Contents\r\n- [How to run](#how-to-run)\r\n- [Hierarchical organization](#hierarchical-organization)\r\n- [UpwardDrawing presentation](#upwarddrawing-presentation)\r\n- [Node and NodeSegment presentation](#node-and-nodesegment-presentation)\r\n- [DirectedGraph presentation](#directedgraph-presentation)\r\n- [License](#license)\r\n\r\n\r\n# How to run\r\n\r\nThe folder contains \r\n- README.md \r\n- folder result (where the result are stored)\r\n- folder report (where the latex files and figures are stored)\r\n- folder Project (where the eclipse project are stored)\r\n\r\n\r\n\r\n# Hierarchical organization\r\n\r\n## Defaut Class\r\n- ComputeUpwardGridDrawing\r\n    - Test (We add) \r\n    - UpwardDrawing\r\n    - GraphRenderer\r\n\r\n## Package jdg-graph\r\n- DirectedGraph\r\n    - NodeSegment (We add)\r\n    - Node \r\n        - GridSegment_2\r\n        - GridVector_2\r\n            - GridPoint_2\r\n\r\n## Package jdg-io\r\n- GraphLoader\r\n    - GraphWriter_Json\r\n- GraphReader\r\n    - GraphReader_Json\r\n\r\n## Package jdg-utils\r\n- Print\r\n\r\n# UpwardDrawing presentation\r\n\r\nThis is our main class where we develop different algorithms and methods.\r\n\r\n- isValid()\r\n    - checkCondition1()\r\n    - checkHasOn()\r\n    - checkCondition3()\r\n\r\n- computValidInitialLayout()\r\n    - topoSortDeepFirstSearch()\r\n        - topoSortDeepFirstSearch(Node u, List topoList)\r\n    - moveOnePlace(Node node)\r\n    - checkAdd(DirectedGraph graph, Node node, List listOfPredecessors)\r\n\r\n- forceDirectedHeuristic() \r\n    - forceDirectedHeuristic(double tol, double c, double k)\r\n        - calculateForce(Node node, double k, double c)\r\n        - update_steplength(int step, double energy, double energy0)\r\n        - distanceOfPositionList(GridPoint_2[] x,GridPoint_2[] y)\r\n\r\n- localSearchHeuristic()\r\n    - localSearch(NodeSegment seg, int Xrange , int Yrange, int Xstep, int Ystep) \r\n\r\nOther pre-processing methods of the graph.\r\n- affineTransform()\r\n- centralize()\r\n- preAffineTransform()\r\n\r\n# Node and NodeSegment presentation\r\n\r\nNode\r\n----\r\nWe have added several instances in this class namely these.\r\n```\r\npublic int d; //time when the Node turns grey in DFS\r\npublic int f; //time when the Node turns black in DFS\r\npublic Node pi; //predecessor in the DFS tree\r\npublic Vector\u003cDouble\u003e force;\r\n```\r\n\r\nThe instance force is to storage the force it receives when in force-directed heuristic algorithm.\r\n\r\nThe d, f, pi are for noting the status during the DFS of the graph. The color can be either white, grey or black during the graph. More information can be found in our report.\r\n\r\nWe have added two methods here.\r\n\r\n- getUpperBoundValidY\r\n\r\nThis method calculate the upper bound it can move to while it maintains the upward property.\r\n```\r\npublic int getUpperBoundValidY() {\r\n\t    \tif (this.successors.isEmpty()) return Integer.MAX_VALUE;\r\n\t    \tint Ymax = this.successors.get(0).getPoint().getY();\r\n\t    \tfor (Node nextNode : this.successors) {\r\n\t    \t\tif (nextNode.getPoint().getY()\u003cYmax)\r\n\t    \t\t\tYmax = nextNode.getPoint().getY();\r\n\t    \t}\r\n\t    \treturn Ymax-1;\r\n\t    }\r\n``` \r\n\r\n- getLowerBoundValidY\r\n\r\nThis method is largely the same as this one above.\r\n\r\nNodeSegment\r\n-----\r\nWe have created this class mainly to maintain the same property of GridSegment_2. Meanwhile this class has two ends of type Node but not GridPoint_2.\r\n\r\nWe have also created the instances for the sake of local search heuristic.\r\n```\r\npublic Node p,q;\r\npublic ArrayList\u003cNodeSegment\u003e crossing;\r\npublic ArrayList\u003cNodeSegment\u003e nextLinkedEdge;\r\npublic ArrayList\u003cNodeSegment\u003e preLinkedEdge;\r\npublic ArrayList\u003cNodeSegment\u003e sorceNeighbors;\r\npublic ArrayList\u003cNodeSegment\u003e targetNeighbors;\r\n```\r\n\r\n- ArrayList crossing\r\n    \r\n    this is to store the other edges which cross with this edge.\r\n\r\n- ArrayList nextLinkedEdge\r\n\r\n    this is to store the edges whose source is the same as this edge's target.\r\n\r\n- ArrayList preLinkedEdge\r\n\r\n    this is to store the edges whose target is the same as this edge's source.\r\n\r\n- ArrayList sorceNeighbors\r\n\r\n    this is to store the edges whose target or source is the same as this edge's source.\r\n\r\n- ArrayList targetNeighbors\r\n\r\n    this is to store the edges whose target or source is the same as this edge's target.\r\n\r\nGridVector_2\r\n----\r\n\r\n- crossProduct\r\n\r\nThe static method crossProduct() return a long int (this can prevent error for large input) of the cross product of two instances of GridVector_2. \r\n```\r\npublic static long crossProduct(GridVector_2 vec1,GridVector_2 vec2) {\r\n\t  return (long)vec1.getX()*(long)vec2.getY()-(long)vec1.getY()*(long)vec2.getX();\r\n  }\r\n```\r\n\r\nGridSegment_2\r\n----\r\n\r\n- hasOn\r\n\r\nThe method hasOn() is to use judge whether a point (GridPoint_2) is lying on a segment including the source and the target.\r\n\r\nFirstly we judge whether the point lies in the rectangle whose diagonal is this segment, only the sign of the equation counts to avoid out of range of int.\r\n\r\nSecondly we judge whether the slopes are equal, in other words whether they are parallel.\r\n\r\n```\r\n    public boolean hasOn(GridPoint_2 p) {\r\n\t  if (p.equals(this.p)||p.equals(this.q))\r\n\t\t  return true;\r\n\t  \r\n\t  if( Math.signum((p.getX()-this.p.getX()))*Math.signum((p.getX()-this.q.getX()))\u003c=0 \u0026\u0026 \r\n\t\t\t  Math.signum((p.getY()-this.p.getY()))* Math.signum((p.getY()-this.q.getY()))\u003c=0) {\r\n\t\t  if( (long)(this.q.getX()-this.p.getX())*(long)(p.getY()-this.q.getY())==(long)(this.q.getY()-this.p.getY())*(long)(p.getX()-this.q.getX()) )\r\n\t\t\t  return true;\r\n\t  }\r\n\t  return false;\r\n  }\r\n```\r\n\r\n- isCrossing\r\n\r\nThis method mainly use 4 cross product to judge whether two ends of one segment lie on the same side of the other segment. Only the sign of the result counts here.\r\n\r\n```\r\n    public static boolean isCrossing(GridSegment_2 seg1, GridSegment_2 seg2) {\r\n  \tGridVector_2 P1P2 = new GridVector_2(seg1.source(),seg1.target());\r\n  \tGridVector_2 P1Q1 = new GridVector_2(seg1.source(),seg2.source());\r\n  \tGridVector_2 P1Q2 = new GridVector_2(seg1.source(),seg2.target());\r\n  \tGridVector_2 Q1Q2 = new GridVector_2(seg2.source(),seg2.target());\r\n  \tGridVector_2 Q1P1 = P1Q1.opposite();\r\n  \tGridVector_2 Q1P2 = new GridVector_2(seg2.source(),seg1.target());\r\n  \tlong d1 = GridVector_2.crossProduct(P1P2, P1Q1);\r\n  \tlong d2 = GridVector_2.crossProduct(P1P2, P1Q2);\r\n  \tlong d3 = GridVector_2.crossProduct(Q1Q2, Q1P1);\r\n  \tlong d4 = GridVector_2.crossProduct(Q1Q2, Q1P2);\r\n  \tif (Math.signum(d1) * Math.signum(d2)  \u003c 0 \u0026\u0026 Math.signum(d3) * Math.signum(d4) \u003c 0) \r\n  \t\treturn true;\r\n  \treturn false;  \t\r\n  }\r\n}\r\n```\r\n\r\n# DirectedGraph presentation\r\nWe have added the instance to store directly the edges of the graph.\r\n\r\n```\r\npublic ArrayList\u003cNode\u003e vertices; // list of vertices\r\npublic HashMap\u003cString,Node\u003e labelMap; // map between vertices and their labels\r\npublic ArrayList\u003cNodeSegment\u003e edges; //list of edges\r\npublic Queue\u003cNodeSegment\u003e edgeQueue;\r\n```\r\n\r\nThe labelMap is a hash map between vertex and label.\r\nHere the edgeQueue is a priority queue comparing the crossing number of each edge.\r\n\r\n```\r\nedgeQueue = new PriorityQueue\u003cNodeSegment\u003e(edges.size(),\r\n                new Comparator\u003cNodeSegment\u003e() {\r\n                    public int compare(NodeSegment s1, NodeSegment s2) {\r\n                        return s2.crossingNumber() - s1.crossingNumber();\r\n                    }\r\n                });\r\n```\r\n\r\nWe have added several methods as below.\r\n\r\n- resetPosition(GridPoint_2[] newPosition)\r\n\r\n    This method is to reset positions of vertex to a set of new positions.\r\n\r\n\r\n- barycenter()\r\n\r\n    This method is to calculate the barycenter of all the vertex.\r\n\r\n- initializeEdges()\r\n\r\n    Initially the graph only have the information of all the vertex and their successors / predecessors. This method is to initialize the instance Edges.\r\n\r\n- calculateCrossingEdge()\r\n\r\n    This method is to calculate the edges crossing with each other, storing the information in their instance.\r\n\r\n- initializeLinkedRelation()\r\n\r\n    This method is to calculate and initialize the instance sorceNeighbors and targetNeighbors.\r\n\r\n- getCrossings(NodeSegment seg)\r\n\r\n    This method returns the crossing number of NodeSegment seg.\r\n\r\n- get AroundCrossings(NodeSegment seg)\r\n\r\n    This method returns the crossing number of this seg plusing the number of its source segments and target segments.\r\n\r\n# License\r\n\r\n[GNU Lesser General Public License v3.0](https://raw.githubusercontent.com/DyeKuu/Graph-Drawing-Contest-2019-2020/master/LICENSE)\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdyekuu%2Fgraph-drawing-contest-2020","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdyekuu%2Fgraph-drawing-contest-2020","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdyekuu%2Fgraph-drawing-contest-2020/lists"}