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

View File

@ -1,6 +1,5 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using Assets.Voronoi; using Assets.Voronoi;
using Random = System.Random; using Random = System.Random;
@ -12,7 +11,6 @@ namespace Assets.Map
private readonly Graph<Location> _locations; private readonly Graph<Location> _locations;
private readonly List<(int, Location)> _queue = new List<(int, Location)>(); 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; private readonly Random _random;
@ -20,7 +18,6 @@ namespace Assets.Map
public Graph<Location> Result => _locations; public Graph<Location> Result => _locations;
public bool Done => _queue.Count == 0; public bool Done => _queue.Count == 0;
public LocationGenerator(List<Location> locations, Graph<Site> sites, Random random = null) 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) public void SetLocation(int vertex, Location location)
{ {
_sites.Vertices[vertex].Location = location; location.AddSite(_sites.Vertices[vertex]);
location.Sites.Add(_sites.Vertices[vertex]);
FixBoundaryPoints(vertex, location);
FixBoundaryEdges(vertex, location);
foreach (var neighbour in _sites.Neighbours(vertex)) foreach (var neighbour in _sites.Neighbours(vertex))
if (_sites.Vertices[neighbour].Location == null) 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.Collections.Generic;
using System.Linq;
using Assets.Common; using Assets.Common;
using Assets.Voronoi; using Assets.Voronoi;
using UnityEngine; using UnityEngine;
@ -8,10 +10,30 @@ namespace Assets.Map
public class Location public class Location
{ {
public List<LocationSite> Sites = new List<LocationSite>(); 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 List<(int, int)> BoundaryEdges = new List<(int, int)>();
public LocationType Type; 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 public class LocationSite