Change graph edges structure to adjacency

This commit is contained in:
Kacper Donat 2019-08-18 21:29:35 +02:00
parent e7888956a8
commit b9f8695996
3 changed files with 52 additions and 37 deletions

View File

@ -7,16 +7,34 @@ namespace Assets.Map
public class Graph<T>
{
public List<T> Vertices { get; internal set; } = new List<T>();
public ISet<(int, int)> Edges { get; internal set; } = new HashSet<(int, int)>();
public Dictionary<int, List<int>> _edges = new Dictionary<int, List<int>>();
public IEnumerable<(int, int)> Edges
{
get
{
return _edges.SelectMany(pair => pair.Value.Where(value => value > pair.Key).Select(value => (pair.Key, value)));
}
set
{
_edges = new Dictionary<int, List<int>>();
foreach (var (a, b) in value)
AddEdge(a, b);
}
}
public void AddEdge(int a, int b)
{
Edges.Add(a < b ? (a, b) : (b, a));
}
public IEnumerable<(int, int)> EdgesOf(int a)
{
return Edges.Where(x => x.Item1 == a || x.Item2 == a);
if (!_edges.ContainsKey(a))
_edges[a] = new List<int>();
if (!_edges.ContainsKey(b))
_edges[b] = new List<int>();
_edges[a].Add(b);
_edges[b].Add(a);
}
public Graph<U> Morph<U>(Func<T, U> morph)
@ -30,8 +48,9 @@ namespace Assets.Map
public IEnumerable<int> Neighbours(int vertex)
{
foreach (var (a, b) in this.EdgesOf(vertex))
yield return a == vertex ? b : a;
if (!_edges.ContainsKey(vertex)) return Enumerable.Empty<int>();
return _edges[vertex];
}
}
}

View File

@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Assets.Voronoi;
using Random = System.Random;
@ -12,7 +11,6 @@ namespace Assets.Map
private readonly Graph<Location> _locations;
private readonly List<(int, Location)> _queue = new List<(int, Location)>();
private readonly Dictionary<Location, List<int>> _blacklist = new Dictionary<Location, List<int>>();
private readonly Random _random;
@ -20,7 +18,6 @@ namespace Assets.Map
public Graph<Location> Result => _locations;
public bool Done => _queue.Count == 0;
public LocationGenerator(List<Location> locations, Graph<Site> sites, Random random = null)
{
@ -32,11 +29,7 @@ namespace Assets.Map
public void SetLocation(int vertex, Location location)
{
_sites.Vertices[vertex].Location = location;
location.Sites.Add(_sites.Vertices[vertex]);
FixBoundaryPoints(vertex, location);
FixBoundaryEdges(vertex, location);
location.AddSite(_sites.Vertices[vertex]);
foreach (var neighbour in _sites.Neighbours(vertex))
if (_sites.Vertices[neighbour].Location == null)
@ -75,24 +68,5 @@ namespace Assets.Map
{
}
}
private void FixBoundaryPoints(int vertex, Location location)
{
var a = location.BoundaryPoints;
var b = _sites.Vertices[vertex].Site.Vertices;
if (!_blacklist.ContainsKey(location)) _blacklist[location] = new List<int>();
_blacklist[location].AddRange(a.Intersect(b));
location.BoundaryPoints = a.Union(b).Except(_blacklist[location]).ToList();
}
private void FixBoundaryEdges(int vertex, Location location)
{
var a = location.BoundaryEdges;
var b = _sites.Vertices[vertex].Site.Edges;
location.BoundaryEdges = a.Union(b).Except(a.Intersect(b)).ToList();
}
}
}

View File

@ -1,4 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Assets.Common;
using Assets.Voronoi;
using UnityEngine;
@ -8,10 +10,30 @@ namespace Assets.Map
public class Location
{
public List<LocationSite> Sites = new List<LocationSite>();
public List<int> BoundaryPoints = new List<int>();
public IEnumerable<int> Points => Sites.SelectMany(site => site.Site.Vertices);
public IEnumerable<int> BoundaryPoints => BoundaryEdges.SelectMany(edge => new [] { edge.Item1, edge.Item2 }).Distinct();
public IEnumerable<int> InsidePoints => Points.Except(BoundaryPoints);
public List<(int, int)> BoundaryEdges = new List<(int, int)>();
public LocationType Type;
public void AddSite(LocationSite site)
{
site.Location = this;
Sites.Add(site);
FixBoundaryEdges(site);
}
private void FixBoundaryEdges(LocationSite site)
{
var a = BoundaryEdges;
var b = site.Site.Edges;
BoundaryEdges = a.Union(b).Except(a.Intersect(b)).ToList();
}
}
public class LocationSite