public void CalculateShortestPaths() { var currentVisitingVertix = VerticesList[0]; while (currentVisitingVertix != null) { VisitedVertices.Add(currentVisitingVertix.Name); var adjacencyLinkedListCurrent = FindNextEdge(currentVisitingVertix.AdjacencyLinkedList.ReturnHead()); while (adjacencyLinkedListCurrent != null) { int distance; int oldDistance; ShortestPaths.TryGetValue(currentVisitingVertix.Name, out distance); ShortestPaths.TryGetValue(adjacencyLinkedListCurrent.Name, out oldDistance); var updateDistance = distance + adjacencyLinkedListCurrent.EdgeValue; if (updateDistance < oldDistance) { ShortestPaths[adjacencyLinkedListCurrent.Name] = updateDistance; } adjacencyLinkedListCurrent = FindNextEdge(adjacencyLinkedListCurrent); } currentVisitingVertix = FindMinValueInShortestPaths(); } }
/// <summary> /// This method calculate the number of bonds on the shortest path between two atoms. /// </summary> /// <param name="atom">The <see cref="IAtom"/> for which the <see cref="Result"/> is requested</param> /// <param name="focusPosition">The position of the focus atom</param> /// <returns>The number of bonds on the shortest path between two atoms</returns> public Result Calculate(IAtom atom, int focusPosition = 0) { var focus = container.Atoms[focusPosition]; // could be cached var bondsToAtom = new ShortestPaths(container, atom).GetDistanceTo(focus); return(new Result(bondsToAtom)); }
private void ComputeOptimalSwitchingCosts() { var graph = this.ConstructFullGraph(); // TODO: disable parallel computation for single-threaded programs? Parallel.ForEach( this.instance.Intervals, new ParallelOptions { MaxDegreeOfParallelism = -1 }, beginInterval => { int beginStateIdx = beginInterval.Index <= 1 ? this.instance.BaseOffStateIdx : this.instance.OnStateIdx; var shortestPaths = new ShortestPaths(graph.NodesCount); shortestPaths.SetInput( graph, false, false, graph.NodeIndex(beginInterval.Index, beginStateIdx)); if (shortestPaths.Solve(this.timer.RemainingTime).IsFeasibleSolution()) { for (int endIntervalIdx = beginInterval.Index; endIntervalIdx <= this.instance.Intervals.Length; endIntervalIdx++) { int endStateIdx = endIntervalIdx >= (this.instance.Intervals.Length - 1) ? this.instance.BaseOffStateIdx : this.instance.OnStateIdx; if (!this.FeasibilityCheck(beginInterval.Index, endIntervalIdx, beginStateIdx, endStateIdx)) { continue; } int pathWeight = int.MaxValue; if (endIntervalIdx == this.instance.Intervals.Length) { pathWeight = shortestPaths.PathWeights[graph.Sink]; } else { pathWeight = shortestPaths.PathWeights[graph.NodeIndex(endIntervalIdx, endStateIdx)]; } this.OptimalCosts[beginInterval.Index][endIntervalIdx] = pathWeight == int.MaxValue ? (int?)null : pathWeight; } } }); }
private static bool MakeDescriptorLastStage( List <double> rdfProtonCalculatedValues, IAtom atom, IAtom clonedAtom, IAtomContainer mol, IAtom neighbour0, List <int> singles, List <int> doubles, List <int> atoms, List <int> bondsInCycloex) { ///////////////////////THE SECOND CALCULATED DESCRIPTOR IS g(H)r TOPOLOGICAL WITH SUM OF BOND LENGTHS if (atoms.Any()) { const double limitInf = 1.4; const double limitSup = 4; const double smooth = -20; var startVertex = clonedAtom; var shortestPaths = new ShortestPaths(mol, startVertex); for (int c = 0; c < desc_length; c++) { var ghrt = limitInf + (limitSup - limitInf) * ((double)c / desc_length); double sum = 0; for (int at = 0; at < atoms.Count; at++) { double distance = 0; var thisAtom = atoms[at]; var position = thisAtom; var endVertex = mol.Atoms[position]; var atom2 = mol.Atoms[position]; var path = shortestPaths.GetPathTo(endVertex); for (int i = 1; i < path.Length; i++) { distance += CalculateDistanceBetweenTwoAtoms(mol.Atoms[path[i - 1]], mol.Atoms[path[i]]); } var partial = atom2.Charge.Value * Math.Exp(smooth * Math.Pow(ghrt - distance, 2)); sum += partial; } rdfProtonCalculatedValues.Add(sum); Debug.WriteLine($"RDF gr-topol distance prob.: {sum} at distance {ghrt}"); } return(true); } else { return(false); } }
// APSP layout stress public static Vector2[] Stress(Func <int[, ], Vector2[], IEnumerable <double> > Layout, SparseMatrix <bool> adjMatrix, StreamWriter file) { int n = adjMatrix.MaxIdx() + 1; Console.Error.WriteLine("vertices=" + n); Console.Error.WriteLine("edges=" + adjMatrix.Count()); var positions = new Vector2[n]; var rnd = new Random(); int[,] shortestPaths = ShortestPaths.Bacon(adjMatrix, n); var sw = new Stopwatch(); //for (int k = 0; k < 25; k++) //{ // GC.Collect(); // initialise positions positions[0] = new Vector2(0, 0); // for majorization for (int i = 1; i < n; i++) { positions[i] = new Vector2(rnd.NextDouble(), rnd.NextDouble()); } sw.Restart(); int iteration = 0; foreach (double stress in Layout(shortestPaths, positions)) { double time = sw.ElapsedMilliseconds; string info = iteration + " " + stress + " " + time; Console.Error.WriteLine(info); //Console.WriteLine(info); file.WriteLine(info); iteration += 1; } // Console.Error.WriteLine("finished run " + (k + 1) + "\n"); // Console.WriteLine(); // file.WriteLine(); //} return(positions); }
public void ComputeMinPaths(string rootNodeName) { Node startNode = Nodes[rootNodeName]; string currentNodeName; BinaryHeap <Path <string> > unusedPaths = new BinaryHeap <Path <string> >(BinaryHeapType.MIN); // create all possible paths first Dictionary <string, Path <string> > pathDict = new Dictionary <string, Path <string> >(); ShortestPaths.Add(rootNodeName, pathDict); foreach (string name in Nodes.Keys) { Path <string> path; if (name.Equals(rootNodeName)) { path = new Path <string>(new string[] { rootNodeName }); path.Distance = 0; } else { path = new Path <string>(new string[] { rootNodeName, name }); path.Distance = Int32.MaxValue; } pathDict.Add(name, path); unusedPaths.Add(path); } while (unusedPaths.Count > 0) { //get the destination node of the path with the smallest global distance currentNodeName = unusedPaths[0][unusedPaths[0].Count - 1]; Path <string> currentPath = ShortestPaths[rootNodeName][currentNodeName]; //get all neighboring nodes and calculate the distance foreach (NodeNeighbor neighbor in Nodes[currentNodeName].Neighbors) // update all distance { int neighborDistance = neighbor.Distance; Path <string> neighborPath = ShortestPaths[rootNodeName][neighbor.Id]; int oldDistance = neighborPath.Distance; int newDistance = currentPath.Distance + neighborDistance; if (newDistance < oldDistance && newDistance >= 0) { //merge the two paths neighborPath.Clear(); foreach (string name in currentPath) { neighborPath.Add(name); } neighborPath.Add(neighbor.Id); neighborPath.Distance = newDistance; } } unusedPaths.Remove(currentPath); } }
/// <summary> /// calculate the stabilization of orbitals when they contain deficiency of charge. /// </summary> /// <param name="atomContainer">the molecule to be considered</param> /// <param name="atom">IAtom for which effective atom StabilizationCharges factor should be calculated</param> /// <returns>stabilizationValue</returns> public static double CalculatePositive(IAtomContainer atomContainer, IAtom atom) { /* restrictions */ // if(atomContainer.GetConnectedSingleElectronsCount(atom) > 0 || atom.FormalCharge != 1){ if (atom.FormalCharge != 1) { return(0.0); } // only must be generated all structures which stabilize the atom in question. StructureResonanceGenerator gRI = new StructureResonanceGenerator(); var reactionList = gRI.Reactions.ToList(); reactionList.Add(new HyperconjugationReaction()); gRI.Reactions = reactionList; var resonanceS = gRI.GetStructures(atomContainer); var containerS = gRI.GetContainers(atomContainer); if (resonanceS.Count < 2) // meaning it was not find any resonance structure { return(0.0); } int positionStart = atomContainer.Atoms.IndexOf(atom); var result1 = new List <double>(); var distance1 = new List <int>(); resonanceS.RemoveAt(0);// the first is the initial structure foreach (var resonance in resonanceS) { if (resonance.Atoms.Count < 2) // resonance with only one atom donnot have resonance { continue; } ShortestPaths shortestPaths = new ShortestPaths(resonance, resonance.Atoms[positionStart]); /* search positive charge */ PiElectronegativity electronegativity = new PiElectronegativity(); foreach (var atomP in resonance.Atoms) { IAtom atomR = atomContainer.Atoms[resonance.Atoms.IndexOf(atomP)]; if (containerS[0].Contains(atomR)) { electronegativity.MaxIterations = 6; double result = electronegativity.CalculatePiElectronegativity(resonance, atomP); result1.Add(result); int dis = shortestPaths.GetDistanceTo(atomP); distance1.Add(dis); } } } /* logarithm */ double value = 0.0; double sum = 0.0; var itDist = distance1.GetEnumerator(); foreach (var ee in result1) { double suM = ee; if (suM < 0) { suM = -1 * suM; } itDist.MoveNext(); sum += suM * Math.Pow(0.67, itDist.Current); } value = sum; return(value); }
/// <summary> /// Main method: /// </summary> public static void Main() { // Create a random graph with the given edge and node count RandomGraphGenerator randomGraph = new RandomGraphGenerator(0); randomGraph.NodeCount = 30; randomGraph.EdgeCount = 60; Graph graph = randomGraph.Generate(); // Create an edgemap and assign random double weights to // the edges of the graph. IEdgeMap weightMap = graph.CreateEdgeMap(); Random random = new Random(0); for (IEdgeCursor ec = graph.GetEdgeCursor(); ec.Ok; ec.Next()) { Edge e = ec.Edge; weightMap.SetDouble(e, 100.0 * random.NextDouble()); } // Calculate the shortest path from the first to the last node // within the graph if (!graph.Empty) { Node from = graph.FirstNode; Node to = graph.LastNode; double sum = 0.0; // The undirected case first, i.e. edges of the graph and the // resulting shortest path are considered to be undirected EdgeList path = ShortestPaths.SingleSourceSingleSink(graph, from, to, false, weightMap); for (IEdgeCursor ec = path.Edges(); ec.Ok; ec.Next()) { Edge e = ec.Edge; double weight = weightMap.GetDouble(e); Console.WriteLine(e + " weight = " + weight); sum += weight; } if (sum == 0.0) { Console.WriteLine("NO UNDIRECTED PATH"); } else { Console.WriteLine("UNDIRECTED PATH LENGTH = " + sum); } // Next the directed case, i.e. edges of the graph and the // resulting shortest path are considered to be directed. // Note that this shortest path can't be shorter then the one // for the undirected case path = ShortestPaths.SingleSourceSingleSink(graph, from, to, true, weightMap); sum = 0.0; for (IEdgeCursor ec = path.Edges(); ec.Ok; ec.Next()) { Edge e = ec.Edge; double weight = weightMap.GetDouble(e); Console.WriteLine(e + " weight = " + weight); sum += weight; } if (sum == 0.0) { Console.WriteLine("NO DIRECTED PATH"); } else { Console.WriteLine("DIRECTED PATH LENGTH = " + sum); } Console.WriteLine("\nAuxiliary distance test\n"); INodeMap distanceMap = graph.CreateNodeMap(); INodeMap predMap = graph.CreateNodeMap(); ShortestPaths.SingleSource(graph, from, true, weightMap, distanceMap, predMap); if (distanceMap.GetDouble(to) == double.PositiveInfinity) { Console.WriteLine("Distance from first to last node is infinite"); } else { Console.WriteLine("Distance from first to last node is " + distanceMap.GetDouble(to)); } // Dispose distanceMap since it is not needed anymore graph.DisposeNodeMap(distanceMap); } // Dispose weightMap since it is not needed anymore graph.DisposeEdgeMap(weightMap); Console.WriteLine("\nPress key to end demo."); Console.ReadKey(); }
private void fillShortestPaths() { shortestPaths = new ShortestPaths (); List<Vector2> GSPlayerUnits = new List<Vector2>(); foreach (Unit unit in map.getUnits (Game.EntityType.GS)) { GSPlayerUnits.Add (unit.position); } foreach (Unit unit in map.getUnits (Game.EntityType.Blip)) { GSPlayerUnits.Add (unit.position); } //Add Deployment area positions for (int i = 0; i < map.otherAreas.Length; i++) { bool posExists = false; foreach (Vector2 position in GSPlayerUnits) { if (position == new Vector2(-1 - i, 0)) { posExists = true; break; } } if (!posExists) { GSPlayerUnits.Add (new Vector2(-1 - i, 0)); } } foreach (Vector2 position in GSPlayerUnits) { shortestPaths.define (position); } //For each Space Marine, find which Genestealers it is closest to foreach (Unit SM in map.getUnits(Game.EntityType.SM)) { foreach (Vector2 position in GSPlayerUnits) { Game.Facing facing = Game.Facing.North; //Test whether the unit is in a deployment area if (position.x < -0.1f) { if (map.otherAreas.Length > -1 - Mathf.RoundToInt (position.x)) { facing = map.otherAreas[-1 - Mathf.RoundToInt (position.x)].relativePosition; } } //Find the shortest path between SM and GS Path testPath = getPath (position, facing, SM.position, facing, orthoSet(), true, true, true, true); Path currentPath = shortestPaths.get (position); if (currentPath != null && testPath != null) { if (testPath.APCost < currentPath.APCost) { shortestPaths.set(position, testPath); } } else { shortestPaths.set (position, testPath); } } } }
public static Vector2[] SparseSGD(SparseMatrix <bool> adjMatrix, int numPivots, int numIter) { var sw = new Stopwatch(); sw.Start(); int n = adjMatrix.MaxIdx() + 1; Console.Error.WriteLine("vertices=" + n); // create sparse distance matrix var d = new SparseMatrix <int>(); Dictionary <int, List <int> > regions = ShortestPaths.SparseBacon(adjMatrix, d, 1, numPivots); var w = new SparseMatrix <double>(); ////////////// // 1-stress // ////////////// var constraints = new List <Tuple <int, int> >(); foreach (var ij in adjMatrix.IndexPairs) { int i = ij.Item1, j = ij.Item2; if (i > j) { constraints.Add(ij); d[i, j] = d[j, i] = 1; w[i, j] = w[j, i] = 1.0; } } Console.Error.WriteLine("edges=" + constraints.Count); /////////////////// // sparse stress // /////////////////// // for every pivot foreach (int pivot in regions.Keys) { // calculate the number of vertices in the region at each distance var regionDistances = new Dictionary <int, int>(); int maxDistance = 0; foreach (int regionMember in regions[pivot]) { if (regionMember != pivot) { int distance = d[pivot, regionMember]; maxDistance = Math.Max(distance, maxDistance); if (!regionDistances.ContainsKey(distance)) { regionDistances[distance] = 1; } else { regionDistances[distance] += 1; } } } var cumulDistances = new List <int>(); cumulDistances.Add(1); for (int i = 1; i <= maxDistance; i++) { cumulDistances.Add(cumulDistances[i - 1] + regionDistances[i]); } var terms = new List <int>(); // for every other vertex for (int thisVertex = 0; thisVertex < n; thisVertex++) { int distance = d[pivot, thisVertex]; // cut out paths to itself and its direct neighbours if (thisVertex != pivot && distance > 1) { int s = regions[pivot].Count; if (distance / 2 < cumulDistances.Count - 1) { s = cumulDistances[distance / 2]; } double weight = 1f / (distance * distance); //double w_pi = weight * numPivots / terms.Count; double w_ip = weight * s; d[pivot, thisVertex] = d[thisVertex, pivot] = distance; w[thisVertex, pivot] = w_ip; } } } foreach (var ij in d.IndexPairs) { int i = ij.Item1, j = ij.Item2; if (i < j) { constraints.Add(ij); } } Console.Error.WriteLine("constraints=" + constraints.Count); // initialise positions var positions = new Vector2[n]; var rnd = new Random(); for (int i = 0; i < n; i++) { positions[i] = new Vector2(rnd.NextDouble(), rnd.NextDouble()); } // calculate annealing double wMax = 0, wMin = double.MaxValue; foreach (var w_ij in w) { wMax = w_ij > wMax ? w_ij : wMax; wMin = w_ij < wMin ? w_ij : wMin; } double cMax = 1 / wMin; double cMin = 0.1 / wMax; double lambda = Math.Log(cMin / cMax) / (numIter - 1); Console.Error.WriteLine("cMax=" + cMax + " cMin=" + cMin + " rate=" + lambda); // SGD for (int k = 0; k < numIter + 5; k++) { FYShuffle(constraints, rnd); double c = cMax * Math.Exp(lambda * k); foreach (var ij in constraints) { int i = ij.Item1, j = ij.Item2; Vector2 pq = positions[i] - positions[j]; // mag is |p-q| double mag = pq.Magnitude(); // r is minimum distance each vertex has to move to satisfy the constraint double r = (d[i, j] - mag) / 2; // the weighting for i and j are different double wc = w[i, j] * c; wc = Math.Min(wc, 1); double r_i = wc * r; wc = w[j, i] * c; wc = Math.Min(wc, 1); double r_j = wc * r; positions[i] += pq * (r_i / mag); positions[j] -= pq * (r_j / mag); } Console.Error.Write(k); } Console.Error.WriteLine("done!"); Console.Error.WriteLine("time=" + sw.ElapsedMilliseconds + "ms"); return(positions); }
public static Vector2[] SparseMajorization(SparseMatrix <bool> adjMatrix, int numPivots, int numIter) { var sw = new Stopwatch(); sw.Start(); int n = adjMatrix.MaxIdx() + 1; Console.Error.WriteLine("vertices=" + n); // create sparse distance matrix var d = new SparseMatrix <int>(); Dictionary <int, List <int> > regions = ShortestPaths.SparseBacon(adjMatrix, d, 1, numPivots); var w = new SparseMatrix <double>(); ////////////// // 1-stress // ////////////// foreach (var ij in adjMatrix.IndexPairs) { int i = ij.Item1, j = ij.Item2; if (i > j) { d[i, j] = d[j, i] = 1; w[i, j] = w[j, i] = 1.0; } } /////////////////// // sparse stress // /////////////////// // for every pivot foreach (int pivot in regions.Keys) { // calculate the number of vertices in the region at each distance var regionDistances = new Dictionary <int, int>(); int maxDistance = 0; foreach (int regionMember in regions[pivot]) { if (regionMember != pivot) { int distance = d[pivot, regionMember]; maxDistance = Math.Max(distance, maxDistance); if (!regionDistances.ContainsKey(distance)) { regionDistances[distance] = 1; } else { regionDistances[distance] += 1; } } } var cumulDistances = new List <int>(); cumulDistances.Add(1); for (int i = 1; i <= maxDistance; i++) { cumulDistances.Add(cumulDistances[i - 1] + regionDistances[i]); } var terms = new List <int>(); // for every other vertex for (int thisVertex = 0; thisVertex < n; thisVertex++) { int distance = d[pivot, thisVertex]; // cut out paths to itself and its direct neighbours if (thisVertex != pivot && distance > 1) { int s = regions[pivot].Count; if (distance / 2 < cumulDistances.Count - 1) { s = cumulDistances[distance / 2]; } double weight = 1f / (distance * distance); //double w_pi = weight * numPivots / terms.Count; double w_ip = weight * s; d[pivot, thisVertex] = d[thisVertex, pivot] = distance; w[thisVertex, pivot] = w_ip; } } } // initialise positions var X = new Vector2[n]; var rnd = new Random(); for (int i = 0; i < n; i++) { X[i] = new Vector2(rnd.NextDouble(), rnd.NextDouble()); } var wBot = new Dictionary <int, double>(); foreach (int i in adjMatrix.GetRowIndices()) { double bot = 0; foreach (int j in adjMatrix.GetColumnIndicesInRow(i)) { if (i != j) { bot += w[i, j]; } } foreach (int p in regions.Keys) { if (p != i && adjMatrix[i, p] == false) { bot += w[i, p]; } } wBot[i] = bot; } for (int k = 0; k < numIter; k++) { foreach (int i in adjMatrix.GetRowIndices()) { double xTop = 0, yTop = 0; // do neighbours foreach (int j in adjMatrix.GetColumnIndicesInRow(i)) { if (i != j) { double dist = (X[i] - X[j]).Magnitude(); xTop += w[i, j] * (X[j].x + (d[i, j] * (X[i].x - X[j].x)) / dist); yTop += w[i, j] * (X[j].y + (d[i, j] * (X[i].y - X[j].y)) / dist); } } // do pivots foreach (int p in regions.Keys) { if (p != i && adjMatrix[i, p] == false) { double w_ip = w[i, p]; double dist = (X[i] - X[p]).Magnitude(); xTop += w[i, p] * (X[p].x + (d[i, p] * (X[i].x - X[p].x)) / dist); yTop += w[i, p] * (X[p].y + (d[i, p] * (X[i].y - X[p].y)) / dist); } } X[i] = new Vector2(xTop / wBot[i], yTop / wBot[i]); } Console.Error.Write(k); } Console.Error.WriteLine("done!"); Console.Error.WriteLine("time=" + sw.ElapsedMilliseconds + "ms"); return(X); }