public ComponentInfo GetComponentInfo(ConnVertex vertex) { long iteration = ++_iteration; var info = EnsureInfo(vertex); info.iteration = iteration; int size = 1; var queue = new Queue <VertexInfo>(new[] { info }); object aug = info.aug; while (queue.Count > 0) { var vert = queue.Dequeue(); foreach (var next in vert.edges) { if (next.iteration == iteration) { continue; } size++; aug = _augmentation.Combine(aug, info.aug); next.iteration = iteration; queue.Enqueue(next); } } return(new ComponentInfo(vertex, aug, size)); }
public bool IsConnected(ConnVertex vertex1, ConnVertex vertex2) { long iteration = ++_iteration; var info1 = EnsureInfo(vertex1); var info2 = EnsureInfo(vertex2); info1.iteration = iteration; info2.iteration = iteration; info1.direction = false; info2.direction = true; var queue = new Queue <VertexInfo>(new[] { info1, info2 }); while (queue.Count > 0) { var vert = queue.Dequeue(); foreach (var next in vert.edges) { if (next.iteration == iteration) { if (next.direction != vert.direction) { return(true); } continue; } next.direction = vert.direction; next.iteration = iteration; queue.Enqueue(next); } } return(false); }
public bool RemoveEdge(ConnVertex vertex1, ConnVertex vertex2) { var info1 = EnsureInfo(vertex1); var info2 = EnsureInfo(vertex2); RemoveEdge(info1, info2); return(RemoveEdge(info2, info1)); }
public bool AddEdge(ConnVertex connVertex1, ConnVertex connVertex2) { var info1 = EnsureInfo(connVertex1); var info2 = EnsureInfo(connVertex2); info1.edges.Add(info2); return(info2.edges.Add(info1)); }
public object RemoveVertexAugmentation(ConnVertex connVertex) { var info = EnsureInfo(connVertex); var old = info.aug; info.aug = null; return(old); }
public object SetVertexAugmentation(ConnVertex connVertex, object vertexAugmentation) { var info = EnsureInfo(connVertex); var old = info.aug; info.aug = vertexAugmentation; return(old); }
public ICollection <ConnVertex> AdjacentVertices(ConnVertex vertex) { if (_info.TryGetValue(vertex, out var info)) { return(info.edges.Select(x => x.vertex).ToArray()); } else { return(new ConnVertex[0]); } }
private VertexInfo EnsureInfo(ConnVertex vertex) { if (_info.TryGetValue(vertex, out var existingInfo)) { return(existingInfo); } var newInfo = new VertexInfo(vertex); _info[vertex] = newInfo; return(newInfo); }
public ComponentInfo(ConnVertex vertex, object augmentation, int size) { this.vertex = vertex; this.augmentation = augmentation; this.size = size; }
public void TestBenchmark(int nV, int nE, int nQ, int nO, int seed, int queryType = 0, bool naive = false, int type = 1) { if (seed == 0) { seed = new Random().Next(); } var swA = new PerformanceMeasurement(10); var swD = new PerformanceMeasurement(10); var swQ = new PerformanceMeasurement(1); int hash = 0; int nD = nO / 2; // number of deletions int nA = nO - nD; // number of additions int maxE = nV * (nV - 1) / 2; var rand = new Random(seed); var rand2 = new Random(seed + 31); IConnGraph graph; swA.Start(); if (naive) { graph = new NaiveConnGraph(SumAndMax.AUGMENTATION); } else { graph = new ConnGraph(SumAndMax.AUGMENTATION, (ConnGraphComponentStorageType)type); } swA.Stop(); var V = new ConnVertex[nV]; for (int i = 0; i < nV; i++) { V[i] = new ConnVertex(rand2); graph.SetVertexAugmentation(V[i], new SumAndMax(1, 1)); } var E = new HashSet <Pii>(); var EList = new List <Pii>(nE); // for (int i = 1; i < nV; i++) // { // graph.AddEdge(V[i - 1], V[i]); // } for (int i = 0; i < nE; i++) { AddRandomEdge(); } // swA.Start(); // graph.Optimize(); // swA.Stop(); _log.WriteLine($"Init time: {swA}\n"); swA.Reset(); char[] O = new char[nO + nQ]; for (int i = 0; i < nA; i++) { O[i] = 'a'; } for (int i = nA; i < nO; i++) { O[i] = 'd'; } for (int i = nO; i < nO + nQ; i++) { O[i] = 'q'; } Shuffle(O, rand); foreach (char o in O) { switch (o) { case 'a': AddRandomEdge(); break; case 'd': DeleteRandomEdge(); break; case 'q': switch (queryType) { case 0: Query0(); break; case 1: Query1(); break; case 2: Query2(); break; } break; } } _log.WriteLine($"Add time: {swA}"); _log.WriteLine($"Delete time: {swD}"); _log.WriteLine($"Query time: {swQ}"); _log.WriteLine(""); _log.WriteLine($"hash: {hash}"); void AddRandomEdge() { if (EList.Count == maxE) { return; } while (true) { int a1 = rand.Next(1, nV); int b1 = rand.Next(0, a1); var pii = new Pii(a1, b1); if (E.Add(pii)) { EList.Add(pii); swA.Start(); graph.AddEdge(V[a1], V[b1]); swA.Stop(); return; } } } void DeleteRandomEdge() { int count = EList.Count; if (count == 0) { return; } int i1 = rand.Next(0, count); var pii = EList[i1]; E.Remove(pii); EList[i1] = EList[count - 1]; EList.RemoveAt(count - 1); swD.Start(); graph.RemoveEdge(V[pii.a], V[pii.b]); swD.Stop(); } void Query0() { int a1 = rand.Next(1, nV); int b1 = rand.Next(0, a1); swQ.Start(); bool result = graph.IsConnected(V[a1], V[b1]); swQ.Stop(); hash = hash * 31 + (result ? 402653189 : 786433); } void Query1() { int a1 = rand.Next(0, nV); swQ.Start(); var info = graph.GetComponentInfo(V[a1]); swQ.Stop(); int result = ((SumAndMax)info.augmentation).sum; Assert.True(info.size == result); hash = hash * 31 + result; } void Query2() { swQ.Start(); var components = graph.GetAllComponents(); swQ.Stop(); foreach (var component in components.OrderBy(x => x.size)) { // hash += component.size; hash = hash * 31 + component.size; } } }
public VertexInfo(ConnVertex vertex) { this.vertex = vertex ?? throw new ArgumentNullException(); }
public bool ComponentHasAugmentation(ConnVertex vertex) { return(this.GetComponentAugmentation(vertex) != null); }
public bool VertexHasAugmentation(ConnVertex vertex) { var info = EnsureInfo(vertex); return(info.aug != null); }
public object GetVertexAugmentation(ConnVertex vertex) { var info = EnsureInfo(vertex); return(info.aug); }