Commit 4f460dbb authored by Tanmim Hanifa's avatar Tanmim Hanifa
Browse files

added files

parent 43fd38f1
using System;
using System.Collections.Generic;
/*
* An A* Pathfinder
*/
public class AStar : Pathfinder {
private Graph graph;
private PriorityQueue frontier;
private Dictionary<Node, Node> previous;
private Dictionary<Node, int> cost;
public void SetGraph(Graph g) {
graph = g;
}
public List<Node> FindPath(Node start, Node goal) {
Console.WriteLine("\nLooking for path from " + start + " to " + goal);
// Set up data structures
Initialise(start);
// Search graph for goal
if (Search(goal)) {
return Path(start, goal); // If found, return path
} else {
return null; // Otherwise return nothing
}
}
// Setup data structures
private void Initialise(Node start) {
// The frontier
frontier = new PriorityQueue();
frontier.Enqueue(start, 0);
// Record of how we got to each node
previous = new Dictionary<Node, Node>();
previous[start] = null; // start has no previous node (we started there!)
// Record of least known cost from start->node
cost = new Dictionary<Node, int>();
cost[start] = 0; // start->start costs nothing
}
// A* search: returns true if path found
private bool Search(Node goal) {
bool found = false; // Did we find the goal yet?
while (frontier.Count != 0) {
// Select a current node from frontier
Node current = (Node) frontier.Dequeue();
Console.WriteLine("Current node: " + current);
// Is this the goal?
if (current.Equals(goal)) {
found = true;
break; // Stop at goal
}
// Expand current node
List<Node> neighbours = graph.Neighbours(current);
foreach (Node next in neighbours) {
// Find cost to next node
int nextCost = cost[current] + graph.Cost(current, next);
// Have we been here before?
bool visitedBefore = cost.ContainsKey(next);
// New node OR cheaper path to known node
if (!visitedBefore || nextCost < cost[next]) {
// Add it to the frontier
frontier.Enqueue(next, nextCost + Distance(next, goal));
// Record how we got to next and it's cost
previous[next] = current;
cost[next] = nextCost;
}
}
}
return found;
}
// Straight line distance between nodes
public static int Distance(Node a, Node b) {
double x2 = Math.Pow(a.X - b.X, 2);
double y2 = Math.Pow(a.Y - b.Y, 2);
return (int) Math.Ceiling(Math.Sqrt(x2 + y2));
}
// Reconstruct the path start->goal from previous data structure
private List<Node> Path(Node start, Node goal) {
List<Node> path = new List<Node>();
Node current = goal;
while (current != start) {
path.Add(current);
current = previous[current];
if (path.Contains(current)) {
Console.WriteLine("Error: path contains a loop");
return null;
}
}
path.Add(start);
path.Reverse();
return path;
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
class BrokenGraph : Graph {
public BrokenGraph() {}
public void AddNode(Node a) {}
public void AddEdge(Node a, Node b, int c) {}
public List<Node> Nodes() {
return new List<Node>();
}
public List<Node> Neighbours(Node a) {
return new List<Node>();
}
public int Cost(Node a, Node b) {
return 1;
}
public void Write() {
Console.WriteLine("You need to write a graph data structure.");
}
}
\ No newline at end of file
class Examples {
public static void Build(Graph graph, int g) {
switch (g) {
case 1:
Example1(graph);
break;
case 2:
Example2(graph);
break;
case 3:
Example3(graph);
break;
default:
Example0(graph);
break;
}
}
private static void AddEdge(Graph g, Node a, Node b, int cost) {
g.AddEdge(a, b, cost);
g.AddEdge(b, a, cost);
}
private static void AddEdge(Graph g, Node a, Node b) {
AddEdge(g, a, b, AStar.Distance(a, b));
}
private static void Example0(Graph graph) {
Node n0 = new Node(0, 0, 0);
Node n1 = new Node(1, 1, 0);
Node n2 = new Node(2, 2, 0);
graph.AddNode(n0);
graph.AddNode(n1);
graph.AddNode(n2);
graph.AddEdge(n0, n1, 1);
graph.AddEdge(n1, n0, 2);
}
private static void Example1(Graph graph) {
Node n0 = new Node(0, -1, 0);
Node n1 = new Node(1, 0, -1);
Node n2 = new Node(2, 0, 0);
Node n3 = new Node(3, 1, 0);
Node n4 = new Node(4, 0, 1);
graph.AddNode(n0);
graph.AddNode(n1);
graph.AddNode(n2);
graph.AddNode(n3);
graph.AddNode(n4);
AddEdge(graph, n0, n2, 5);
AddEdge(graph, n1, n2, 3);
AddEdge(graph, n2, n3, 2);
AddEdge(graph, n2, n4, 7);
}
private static void Example2(Graph graph) {
Node n0 = new Node(0, 0, 0);
Node n1 = new Node(1, 2, 0);
Node n2 = new Node(2, 3, 1);
Node n3 = new Node(3, 1, 4);
Node n4 = new Node(4, 4, 5);
Node n5 = new Node(5, 5, 3);
Node n6 = new Node(6, 1, 2);
Node n7 = new Node(7, 0, 4);
Node n8 = new Node(8, 2, 5);
Node n9 = new Node(9, 2, 3);
graph.AddNode(n0);
graph.AddNode(n1);
graph.AddNode(n2);
graph.AddNode(n3);
graph.AddNode(n4);
graph.AddNode(n5);
graph.AddNode(n6);
graph.AddNode(n7);
graph.AddNode(n8);
graph.AddNode(n9);
AddEdge(graph, n0, n1);
AddEdge(graph, n0, n6);
AddEdge(graph, n0, n7);
AddEdge(graph, n1, n2);
AddEdge(graph, n1, n6);
AddEdge(graph, n3, n7);
AddEdge(graph, n3, n8);
AddEdge(graph, n3, n9);
AddEdge(graph, n4, n5);
AddEdge(graph, n4, n8);
AddEdge(graph, n4, n9);
AddEdge(graph, n5, n9);
AddEdge(graph, n6, n7);
AddEdge(graph, n6, n9, 8); // High cost edge
}
private static void Example3(Graph graph) {
Node a = new Node(0, 0, 2);
Node b = new Node(1, 2, 2);
Node c = new Node(2, 2, 0);
Node d = new Node(3, 4, 1);
Node e = new Node(4, 2, 5);
Node f = new Node(5, 4, 2);
Node g = new Node(6, 6, 0);
Node h = new Node(7, 5, 5);
Node z = new Node(8, 7, 4);
graph.AddNode(a);
graph.AddNode(b);
graph.AddNode(c);
graph.AddNode(d);
graph.AddNode(e);
graph.AddNode(f);
graph.AddNode(g);
graph.AddNode(h);
graph.AddNode(z);
AddEdge(graph, a, b);
AddEdge(graph, a, c);
AddEdge(graph, a, e);
AddEdge(graph, b, f);
AddEdge(graph, c, d);
AddEdge(graph, c, g);
AddEdge(graph, d, f);
AddEdge(graph, d, g);
AddEdge(graph, e, f);
AddEdge(graph, e, h);
AddEdge(graph, f, z);
AddEdge(graph, g, z);
AddEdge(graph, h, z);
}
}
\ No newline at end of file
using System.Collections.Generic;
public interface Graph {
// Try to add the node a.
void AddNode(Node a);
// Try to add the edge a-b with cost c.
// If it already exists, update the cost.
// Do nothing if cost is non-positive.
void AddEdge(Node a, Node b, int c);
// Return all the nodes in this graph.
List<Node> Nodes();
// Return all the neighbours on node a.
// i.e. nodes connected to a by an edge.
List<Node> Neighbours(Node a);
// Return cost of edge a-b (-1 if no such edge)
int Cost(Node a, Node b);
// Write a description of the graph to System.Console
void Write();
}
\ No newline at end of file
using System;
public class Node {
public int Id;
public double X;
public double Y;
public Node(int i) {
Id = i;
}
public Node(int i, double x, double y) {
Id = i;
X = x;
Y = y;
}
public override bool Equals(Object obj) {
Node node = obj as Node;
return (node != null) && (Id == node.Id);
}
public override int GetHashCode() {
return Id;
}
public override string ToString() {
return Id.ToString();
}
public void SetPosition(double x, double y) {
this.X = x;
this.Y = y;
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
/*
* Builds graphs and finds paths via Main method:
* - 1st argument selects the graph to create.
* - Optionally, tries to find path from 2nd to 3rd argument.
*
* For example...
*
* mono Pathfind.exe 2
* (Creates graph #2)
*
* mono Pathfind.exe 2 8 3
* (Creates graph #2 and requests a path from node 8 to node 3)
*/
class Pathfind {
// Main method
public static void Main(string[] args) {
int g, a, b;
if (args.Length < 1) {
// ERROR: not enough arguments
Console.WriteLine("Error: no arguments provided");
} else {
// Parse first argument
if (!int.TryParse(args[0], out g)) {
Console.WriteLine(args[0] + " is not an integer");
} else {
// First argument selects the graph
Graph graph = new BrokenGraph(); // ***** CHANGE TO YOUR GRAPH CLASS *****
Examples.Build(graph, g);
graph.Write();
// If more arguments, then pathfind
if (args.Length > 2) {
// Parse second argument
if (!int.TryParse(args[1], out a)) {
Console.WriteLine(args[1] + " is not an integer");
// Parse third argument
} else if (!int.TryParse(args[2], out b)) {
Console.WriteLine(args[2] + " is not an integer");
} else {
FindPath(graph, a, b);
}
}
}
}
}
// Find path a->b on graph g
private static void FindPath(Graph g, int a, int b) {
Node start = new Node(a);
Node goal = new Node(b);
Pathfinder finder = new AStar(); // ***** CHANGE TO YOUR SEARCH CLASS *****
finder.SetGraph(g);
List<Node> path = finder.FindPath(start, goal);
if (path != null) {
WritePath(path);
} else {
Console.WriteLine("No path found.");
}
}
// Write path nodes to console
private static void WritePath(List<Node> path) {
Console.Write("Path: ");
bool first = true;
foreach (Node node in path) {
if (!first) Console.Write(", ");
Console.Write(node.ToString());
first = false;
}
Console.Write("\n");
}
}
using System.Collections.Generic;
interface Pathfinder {
void SetGraph(Graph g);
List<Node> FindPath (Node a, Node b);
}
\ No newline at end of file
using System.Collections.Generic;
// A simple priority queue
public class CostedNode {
public Node node;
public int cost;
public CostedNode(Node node, int cost) {
this.node = node;
this.cost = cost;
}
}
public class PriorityQueue {
private List<CostedNode> items = new List<CostedNode>();
public void Enqueue(Node node, int cost) {
items.Add(new CostedNode(node, cost));
}
public int Count {
get {
return items.Count;
}
}
public Node Dequeue() {
int minIdx = findMinIndex();
if (minIdx < 0) {
return null;
}
CostedNode item = items[minIdx];
items.RemoveAt(minIdx);
return item.node;
}
private int findMinIndex() {
CostedNode min = null;
int idx = -1;
for (int i = 0; i < items.Count; i++) {
if (min == null) {
idx = i;
min = items [i];
} else if (items[i].cost <= min.cost) {
idx = i;
min = items [i];
}
}
return idx;
}
}
......@@ -5,6 +5,7 @@ class YellowGraph : Graph {
// List of nodes in this graph
private List<Node> nodes;
// An adjacency matrix, recording edges between nodes
// Edge FROM node i to node j is recorded in adjMatrix[i,j]
......@@ -13,16 +14,39 @@ class YellowGraph : Graph {
private int[,] adjMatrix;
public YellowGraph() {
nodes = new List<Node>();
nodes = new List<Node>();
adjMatrix = new int[0,0];
}
// ADD MISSING METHODS HERE
public void AddNode (Node a)
{
}
public void AddEdge(Node a, Node b, int c)
{
graph.addEdge("a", "b");
}
public List<Node> Nodes() {
return new List<Node>();
}
public List<Node> Neighbours(Node a) {
return new List<Node>();
}
public int Cost(Node a, Node b)
{
return -1;
}
public void Write() {
Console.WriteLine("YellowGraph");
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment