Giter Site home page Giter Site logo

project-2's People

Contributors

nekozye avatar

Watchers

 avatar

project-2's Issues

Devin Romanoff - Code Review

type = (type + 1) - selector;
type = type - 1;

This seems redundant and can probably be reduced to one line.

Graph glr = createLinkedList(10000);

Having slightly more verbose/less abbreviated variable names could help with readability]

public String toString() {
return "Node{" +
"nodeVal=" + nodeVal+
'}';
}

Might be redundant because nodeVal is already a string

LinkedList<Node> nodes;

HashSet<Node> getAllNodes()
{
HashSet<Node> set = new HashSet<Node>();
set.addAll(this.nodes);
return set;
}

The LinkedList could be a redundant data structure because you can iterate through a HashSet to get all the nodes and manipulate them too

public ArrayList<Node> DFSRec(final Node start, final Node end)
{
HashSet<Node> visited = new HashSet<Node>();
LinkedList<Node> nodelist = DFSRecHelper(start,start,end,visited);
ArrayList<Node> nds = new ArrayList<Node>();
for(int i = 0; i < nodelist.size(); i++)
{
nds.add(nodelist.get(i));
}
return nds;
}
//returns null if no destination reach. returns the list including start if exists.
//makes sure the recursive happens before queueing the next log, so depth is searched first
public LinkedList<Node> DFSRecHelper(final Node start, final Node current, final Node end, HashSet<Node> visited)
{
visited.add(current);
if(current.equals(end))
{
LinkedList<Node> rtlist = new LinkedList<Node>();
rtlist.addFirst(current);
return rtlist;
}
LinkedList<Node> adjlist = graphToSearch.getAdjList(current);
boolean deadEnd = true;
for(int i = 0; i < adjlist.size(); i++)
{
if(!visited.contains(adjlist.get(i)))
{
deadEnd = false;
LinkedList<Node> rtf = DFSRecHelper(start,adjlist.get(i),end,visited);
if(rtf != null)
{
rtf.addFirst(current);
return rtf;
}
}
}
if(deadEnd)
{
return null;
}
return null;
}

The assignment states that DFSRec should recursively return an ArrayList, so while this is a recursive DFS I'm not sure it fully complies with the problem statement

switch(decider)
{
case 2:
if(nodesToAdd.isEmpty())
break;
nodeTemp = nodesToAdd.removeFirst();
graphToReturn.addDirectedEdge(nodeInQuestion,nodeTemp);
queue.addLast(nodeTemp);
case 1:
if(nodesToAdd.isEmpty())
break;
nodeTemp = nodesToAdd.removeFirst();
graphToReturn.addDirectedEdge(nodeInQuestion,nodeTemp);
queue.addLast(nodeTemp);
case 0:
break;
}

This switch is redundant because case 1 and 2 execute the same code

LinkedList<DirectCostNode> workStack = new LinkedList<DirectCostNode>();
LinkedList<DirectCostNode> resultStack = new LinkedList<DirectCostNode>();

Is there an advantage of using a LinkedList over a Stack

public void addDirectedEdge(final DirectCostNode destination, int cost)
{
this.edges.put(destination,new Integer(cost));
}

There should be a check in case an edge already exists

public void switchGraph(Graph graphToSearch)
{
this.graphToSearch = graphToSearch;
}

This operation could be performed in the constructor

if (queue.isEmpty())
{
ArrayList<Node> rtbf = new ArrayList<Node>();
rtbf.addAll(bflr);
return rtbf;
}

You might save space by making bflr an ArrayList to begin with and returning that

Andrew Peters - Code Review

public String nodeVal;
public Node(String nodeVal)
{
this.nodeVal = nodeVal;
}

giving the Node class a visited variable would make it a lot easier to keep track of which nodes you have looked at already

for(int i = 0; i < n; i++)
{
rug.addNode(String.valueOf(i+1));
}

for you random graph, you do not add n random nodes to the graph. you add specific nodes 1 through n

switch(type)
{
case 3:
select = random.nextInt(listnodes.size());
nd = nodearr[select];
rug.addUndirectedEdge(node,nd);
case 2:
select = random.nextInt(listnodes.size());
nd = nodearr[select];
rug.addUndirectedEdge(node,nd);
case 1:
select = random.nextInt(listnodes.size());
nd = nodearr[select];
rug.addUndirectedEdge(node,nd);
case 0:
select = random.nextInt(listnodes.size());
nd = nodearr[select];
rug.addUndirectedEdge(node,nd);
break;
}

since you do the same code every time with just one of them having an additional break, you don't need a switch statement. you can just use an if statement and say if type == 0, then break

Graph graphToSearch;
public GraphSearch(Graph graphToSearch)
{
switchGraph(graphToSearch);
}
public void switchGraph(Graph graphToSearch)
{
this.graphToSearch = graphToSearch;
}

isn't it kinda redundant to have the method switchGraph? in your GraphSearch constructor you can just assign graphToSearch to the parameter

LinkedList<Node> nodelist = DFSRecHelper(start,start,end,visited);
ArrayList<Node> nds = new ArrayList<Node>();
for(int i = 0; i < nodelist.size(); i++)
{
nds.add(nodelist.get(i));
}
return nds;

you can save memory space by making the helper method return an arraylist and just make nodeList an arraylist type

public ArrayList<Node> DFSRec(final Node start, final Node end)
{
HashSet<Node> visited = new HashSet<Node>();
LinkedList<Node> nodelist = DFSRecHelper(start,start,end,visited);
ArrayList<Node> nds = new ArrayList<Node>();
for(int i = 0; i < nodelist.size(); i++)
{
nds.add(nodelist.get(i));
}
return nds;
}

if you helper method ends up returning null, then the main function would return an empty list instead of null, and the question asked to return null if no path is found

public void addDirectedEdge (final DirectCostNode first, final DirectCostNode second) {
if(this.nodes.contains(first) && this.nodes.contains(second))
{
first.edges.put(second,1);
}
}

you should add some kind of check to make sure there is not already an existing edge from first to second

public static DirectedGraph createRandomDAGIter(final int n){
DirectedGraph graphToReturn = new DirectedGraph();
LinkedList<DirectCostNode> nodesToAdd = new LinkedList<DirectCostNode>();
for(int i = 0; i < n; i++)
{
DirectCostNode nd = new DirectCostNode(String.valueOf(i));
nodesToAdd.addLast(nd);
graphToReturn.addNode(nd);
}
Random rand = new Random();
LinkedList<DirectCostNode> queue = new LinkedList<DirectCostNode>();
queue.addLast(nodesToAdd.removeFirst());
while(!queue.isEmpty())
{
int decider = rand.nextInt(3);
DirectCostNode nodeInQuestion = queue.removeFirst();
DirectCostNode nodeTemp = null;
switch(decider)
{
case 2:
if(nodesToAdd.isEmpty())
break;
nodeTemp = nodesToAdd.removeFirst();
graphToReturn.addDirectedEdge(nodeInQuestion,nodeTemp);
queue.addLast(nodeTemp);
case 1:
if(nodesToAdd.isEmpty())
break;
nodeTemp = nodesToAdd.removeFirst();
graphToReturn.addDirectedEdge(nodeInQuestion,nodeTemp);
queue.addLast(nodeTemp);
case 0:
break;
}
if(queue.isEmpty() && !nodesToAdd.isEmpty())
{
queue.addLast(nodesToAdd.removeFirst());
}
}
return graphToReturn;
}

your random DAG code does not check to make sure it is not adding an edge backwards, so this could create a cycle in the graph, and a DAG is acyclic

LinkedList<DirectCostNode> visited = new LinkedList<DirectCostNode>();
LinkedList<DirectCostNode> workStack = new LinkedList<DirectCostNode>();
LinkedList<DirectCostNode> resultStack = new LinkedList<DirectCostNode>();

you could save memory space by having a visited variable in the node class and just using a stack to track what you have processed

public void addUndirectedEdge(final GridNode first, final GridNode second)
{
boolean nextTo = isNextTo(first,second);
if(nextTo)
{
GridNode.GridDirection gd = getSide(first,second);
if(gd != GridNode.GridDirection.ERR)
{
first.setSide(gd,second);
second.setSide(GridNode.GridDirection.flip(gd),first);
}
}
}

you first check if node second is next to node first, and then you check which side the node second is on and then add as long as that side isn't an error. you probably don't need to have 2 separate checks to add the node. you can just have one check to determine what side node second is on, and if returns an error then you know that second is not a neighbor

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.