lab6
This commit is contained in:
1 parent
1b564e47e9
commit
7f65ead644
44 files changed
+4582
-2
No files matched your search
@@ -0,0 +1,244 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Code.Lab6
|
||||
{
|
||||
public abstract class Graph : MonoBehaviour
|
||||
{
|
||||
public GameObject vertexPrefab;
|
||||
protected List<Vertex> Vertices;
|
||||
protected List<List<Vertex>> Neighbours;
|
||||
protected List<List<float>> Costs;
|
||||
|
||||
public virtual void Start()
|
||||
{
|
||||
if (Application.isPlaying)
|
||||
{
|
||||
Load();
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Load() { }
|
||||
|
||||
public virtual int GetSize()
|
||||
{
|
||||
if (ReferenceEquals(Vertices, null)) return 0;
|
||||
return Vertices.Count;
|
||||
}
|
||||
|
||||
public virtual Vertex GetNearestVertex(Vector3 position)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
public virtual Vertex GetVertexObj(int id)
|
||||
{
|
||||
if (ReferenceEquals(Vertices, null) || Vertices.Count == 0)
|
||||
return null;
|
||||
if (id < 0 || id >= Vertices.Count)
|
||||
return null;
|
||||
return Vertices[id];
|
||||
}
|
||||
|
||||
public virtual Vertex[] GetNeighbours(Vertex v)
|
||||
{
|
||||
if (ReferenceEquals(Neighbours, null) || Neighbours.Count == 0 || v.id < 0 || v.id >= Neighbours.Count)
|
||||
return Array.Empty<Vertex>();
|
||||
return Neighbours[v.id].ToArray();
|
||||
}
|
||||
|
||||
public virtual Edge[] GetEdges(Vertex v)
|
||||
{
|
||||
return v.neighbours == null ? Array.Empty<Edge>() : v.neighbours.ToArray();
|
||||
}
|
||||
|
||||
public List<Vertex> GetPathBfs(GameObject srcObj, GameObject dstObj)
|
||||
{
|
||||
if (!srcObj || !dstObj)
|
||||
return new List<Vertex>();
|
||||
|
||||
var src = GetNearestVertex(srcObj.transform.position);
|
||||
var dst = GetNearestVertex(dstObj.transform.position);
|
||||
|
||||
if (!src || !dst)
|
||||
{
|
||||
Debug.LogWarning("Source or destination vertex is null");
|
||||
return new List<Vertex>();
|
||||
}
|
||||
|
||||
Debug.Log($"BFS from {src.id} to {dst.id}");
|
||||
|
||||
var previous = new Dictionary<int, int>();
|
||||
var visited = new HashSet<int>();
|
||||
var queue = new Queue<Vertex>();
|
||||
|
||||
visited.Add(src.id);
|
||||
previous[src.id] = src.id;
|
||||
queue.Enqueue(src);
|
||||
|
||||
while (queue.Count > 0)
|
||||
{
|
||||
var current = queue.Dequeue();
|
||||
|
||||
if (current.id == dst.id)
|
||||
{
|
||||
Debug.Log("BFS: Path found!");
|
||||
return BuildPath(src.id, dst.id, previous);
|
||||
}
|
||||
|
||||
var neighbours = GetNeighbours(current);
|
||||
|
||||
foreach (var neighbour in neighbours)
|
||||
{
|
||||
if (!neighbour) continue;
|
||||
|
||||
if (!visited.Add(neighbour.id)) continue;
|
||||
|
||||
previous[neighbour.id] = current.id;
|
||||
queue.Enqueue(neighbour);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.LogWarning("BFS: No path found");
|
||||
return new List<Vertex>();
|
||||
}
|
||||
|
||||
public List<Vertex> GetPathDfs(GameObject srcObj, GameObject dstObj)
|
||||
{
|
||||
if (!srcObj || !dstObj)
|
||||
return new List<Vertex>();
|
||||
|
||||
var src = GetNearestVertex(srcObj.transform.position);
|
||||
var dst = GetNearestVertex(dstObj.transform.position);
|
||||
|
||||
if (!src || !dst)
|
||||
{
|
||||
Debug.LogWarning("Source or destination vertex is null");
|
||||
return new List<Vertex>();
|
||||
}
|
||||
|
||||
Debug.Log($"DFS from {src.id} to {dst.id}");
|
||||
|
||||
var previous = new Dictionary<int, int>();
|
||||
var visited = new HashSet<int>();
|
||||
var stack = new Stack<Vertex>();
|
||||
|
||||
visited.Add(src.id);
|
||||
previous[src.id] = src.id;
|
||||
stack.Push(src);
|
||||
|
||||
while (stack.Count > 0)
|
||||
{
|
||||
var current = stack.Pop();
|
||||
|
||||
if (current.id == dst.id)
|
||||
{
|
||||
Debug.Log("DFS: Path found!");
|
||||
return BuildPath(src.id, dst.id, previous);
|
||||
}
|
||||
|
||||
var neighbours = GetNeighbours(current);
|
||||
|
||||
foreach (var neighbour in neighbours)
|
||||
{
|
||||
if (!neighbour) continue;
|
||||
|
||||
if (!visited.Add(neighbour.id)) continue;
|
||||
|
||||
previous[neighbour.id] = current.id;
|
||||
stack.Push(neighbour);
|
||||
}
|
||||
}
|
||||
|
||||
Debug.LogWarning("DFS: No path found");
|
||||
return new List<Vertex>();
|
||||
}
|
||||
|
||||
private List<Vertex> BuildPath(int srcId, int dstId, Dictionary<int, int> previous)
|
||||
{
|
||||
var path = new List<Vertex>();
|
||||
|
||||
if (!previous.ContainsKey(dstId))
|
||||
{
|
||||
Debug.LogError("Destination not in previous dictionary");
|
||||
return path;
|
||||
}
|
||||
|
||||
var currentId = dstId;
|
||||
|
||||
while (currentId != srcId)
|
||||
{
|
||||
var currentVertex = GetVertexById(currentId);
|
||||
if (!currentVertex)
|
||||
{
|
||||
Debug.LogError($"Vertex with id {currentId} not found");
|
||||
break;
|
||||
}
|
||||
|
||||
path.Add(currentVertex);
|
||||
|
||||
if (!previous.TryGetValue(currentId, out var previou))
|
||||
{
|
||||
Debug.LogError($"Previous not found for id {currentId}");
|
||||
break;
|
||||
}
|
||||
|
||||
currentId = previou;
|
||||
}
|
||||
|
||||
var srcVertex = GetVertexById(srcId);
|
||||
if (srcVertex is not null)
|
||||
{
|
||||
path.Add(srcVertex);
|
||||
}
|
||||
|
||||
path.Reverse();
|
||||
|
||||
Debug.Log($"Path built with {path.Count} vertices");
|
||||
return path;
|
||||
}
|
||||
|
||||
private Vertex GetVertexById(int id)
|
||||
{
|
||||
return Vertices?.FirstOrDefault(v => v && v.id == id);
|
||||
}
|
||||
|
||||
private List<Vertex> BuildPath(int srcId, int dstId, ref int[] prevList)
|
||||
{
|
||||
var path = new List<Vertex>();
|
||||
var prev = dstId;
|
||||
|
||||
do
|
||||
{
|
||||
var v = GetVertexById(prev);
|
||||
if (v == null)
|
||||
{
|
||||
Debug.LogError($"Vertex with id {prev} not found");
|
||||
break;
|
||||
}
|
||||
|
||||
path.Add(v);
|
||||
|
||||
if (prev < 0 || prev >= prevList.Length)
|
||||
{
|
||||
Debug.LogError($"Index {prev} out of range for prevList (size {prevList.Length})");
|
||||
break;
|
||||
}
|
||||
|
||||
prev = prevList[prev];
|
||||
} while (prev != srcId && prev != -1);
|
||||
|
||||
if (prev != -1)
|
||||
{
|
||||
var srcV = GetVertexById(srcId);
|
||||
if (srcV != null)
|
||||
path.Add(srcV);
|
||||
}
|
||||
|
||||
path.Reverse();
|
||||
return path;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user