Free cookie consent management tool by TermsFeed Policy Generator

source: stable/HeuristicLab.ExtLibs/HeuristicLab.Igraph/0.8.0-pre/HeuristicLab.Igraph-0.8.0-pre/Wrappers/Graph.cs

Last change on this file was 17181, checked in by swagner, 5 years ago

#2875: Merged r17180 from trunk to stable

File size: 7.4 KB
Line 
1#region License Information
2/* HeuristicLab
3 * Copyright (C) Heuristic and Evolutionary Algorithms Laboratory (HEAL)
4 *
5 * This file is part of HeuristicLab.
6 *
7 * HeuristicLab is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * HeuristicLab is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with HeuristicLab. If not, see <http://www.gnu.org/licenses/>.
19 */
20#endregion
21
22using System;
23using System.Collections.Generic;
24
25namespace HeuristicLab.IGraph.Wrappers {
26  public sealed class Graph : IDisposable {
27    private igraph_t graph;
28    internal igraph_t NativeInstance { get { return graph; } }
29
30    public int Vertices { get { return graph.n; } }
31    public bool IsDirected { get { return graph.directed; } }
32
33    public Graph() : this(0) { }
34    public Graph(int vertices) : this(vertices, false) { }
35    public Graph(int vertices, bool directed) {
36      graph = new igraph_t();
37      DllImporter.igraph_empty(graph, vertices, directed);
38    }
39    public Graph(int vertices, IEnumerable<Tuple<int, int>> edges) : this(vertices, edges, false) { }
40    public Graph(int vertices, IEnumerable<Tuple<int, int>> edges, bool directed) {
41      graph = new igraph_t();
42      DllImporter.igraph_empty(graph, vertices, directed);
43      foreach (var e in edges)
44        DllImporter.igraph_add_edge(graph, e.Item1, e.Item2);
45    }
46    ~Graph() {
47      DllImporter.igraph_destroy(graph);
48    }
49
50    public void Dispose() {
51      if (graph == null) return;
52      DllImporter.igraph_destroy(graph);
53      graph = null;
54      GC.SuppressFinalize(this);
55    }
56
57    public void SetSeed(uint seed) {
58      DllImporter.igraph_rng_seed(seed);
59    }
60
61    public double Density() {
62      double density;
63      DllImporter.igraph_density(graph, out density, false);
64      return density;
65    }
66
67    public Vector PageRank(double damping = 0.85, Vector weights = null) {
68      var vec = new Vector(Vertices);
69      var all = new igraph_vs_t();
70      DllImporter.igraph_vs_all(ref all);
71      try {
72        double eigenv = 0;
73        DllImporter.igraph_pagerank(graph, igraph_pagerank_algo_t.IGRAPH_PAGERANK_ALGO_PRPACK, vec.NativeInstance, out eigenv, all, IsDirected, damping, weights != null ? weights.NativeInstance : null);
74      } finally {
75        DllImporter.igraph_vs_destroy(ref all);
76      }
77      return vec;
78    }
79
80    public Matrix LayoutWithFruchtermanReingold(Matrix initialCoords = null) {
81      return LayoutWithFruchtermanReingold(500, Math.Sqrt(Vertices), initialCoords);
82    }
83    public Matrix LayoutWithFruchtermanReingold(int niter, double startTemp, Matrix initialCoords = null) {
84      if (initialCoords != null && (initialCoords.Rows != Vertices || initialCoords.Columns != 2))
85        throw new ArgumentException("Initial coordinate matrix does not contain the required number of rows and columns.", "initialCoords");
86      var coords = initialCoords != null ? new Matrix(initialCoords) : new Matrix(Vertices, 2);
87      DllImporter.igraph_layout_fruchterman_reingold(graph, coords.NativeInstance, initialCoords != null, niter, startTemp, igraph_layout_grid_t.IGRAPH_LAYOUT_AUTOGRID, null, null, null, null, null);
88      return coords;
89    }
90
91    public Matrix LayoutWithKamadaKawai(Matrix initialCoords = null) {
92      return LayoutWithKamadaKawai(50 * Vertices, 0, Vertices, initialCoords);
93    }
94    public Matrix LayoutWithKamadaKawai(int maxiter, double epsilon, double kkconst, Matrix initialCoords = null) {
95      if (initialCoords != null && (initialCoords.Rows != Vertices || initialCoords.Columns != 2))
96        throw new ArgumentException("Initial coordinate matrix does not contain the required number of rows and columns.", "initialCoords");
97      var coords = initialCoords != null ? new Matrix(initialCoords) : new Matrix(Vertices, 2);
98      DllImporter.igraph_layout_kamada_kawai(graph, coords.NativeInstance, initialCoords != null, maxiter, epsilon, kkconst, null, null, null, null, null);
99      return coords;
100    }
101
102    public Matrix LayoutWithDavidsonHarel(Matrix initialCoords = null) {
103      var density = Density();
104      return LayoutWithDavidsonHarel(10, Math.Max(10, (int)Math.Log(Vertices, 2)), 0.75, 1.0, 0.0, density / 10.0, 1.0 - Math.Sqrt(density), 0.2 * (1 - density), initialCoords);
105    }
106    public Matrix LayoutWithDavidsonHarel(int maxiter, int fineiter, double cool_fact, double weight_node_dist, double weight_border, double weight_edge_lengths, double weight_edge_crossings, double weight_node_edge_dist, Matrix initialCoords = null) {
107      if (initialCoords != null && (initialCoords.Rows != Vertices || initialCoords.Columns != 2))
108        throw new ArgumentException("Initial coordinate matrix does not contain the required number of rows and columns.", "initialCoords");
109      var coords = initialCoords != null ? new Matrix(initialCoords) : new Matrix(Vertices, 2);
110      DllImporter.igraph_layout_davidson_harel(graph, coords.NativeInstance, initialCoords != null, maxiter, fineiter, cool_fact, weight_node_dist, weight_border, weight_edge_lengths, weight_edge_crossings, weight_node_edge_dist);
111      return coords;
112    }
113
114    /// <summary>
115    /// Use multi-dimensional scaling to layout vertices.
116    /// A distance matrix can be used to specify the distances between the vertices.
117    /// Otherwise the distances will be calculated by shortest-path-length.
118    /// </summary>
119    /// <remarks>
120    /// For disconnected graphs, dimension must be 2.
121    /// </remarks>
122    /// <param name="dist">The distance matrix to layout the vertices.</param>
123    /// <param name="dim">How many dimensions should be used.</param>
124    /// <returns>The coordinates matrix of the aligned vertices.</returns>
125    public Matrix LayoutWithMds(Matrix dist = null, int dim = 2) {
126      var coords = new Matrix(Vertices, dim);
127      DllImporter.igraph_layout_mds(graph, coords.NativeInstance, dist != null ? dist.NativeInstance : null, dim);
128      return coords;
129    }
130
131    public void BreadthFirstWalk(BreadthFirstHandler handler, int root, DirectedWalkMode mode, bool includeUnreachableFromRoot = false, object tag = null) {
132      igraph_bfshandler_t wrapper = (t, vid, pred, succ, rank, dist, extra) => handler != null && handler(this, vid, pred, succ, rank, dist, tag);
133      DllImporter.igraph_bfs(graph, root, null, (igraph_neimode_t)mode, includeUnreachableFromRoot, null, null, null, null, null, null, null, wrapper, tag);
134    }
135
136    public void DepthFirstWalk(DepthFirstHandler inHandler, DepthFirstHandler outHandler, int root, DirectedWalkMode mode, bool includeUnreachableFromRoot = false, object tag = null) {
137      igraph_dfshandler_t inWrapper = (t, vid, dist, extra) => inHandler != null && inHandler(this, vid, dist, tag);
138      igraph_dfshandler_t outWrapper = (t, vid, dist, extra) => outHandler != null && outHandler(this, vid, dist, tag);
139      DllImporter.igraph_dfs(graph, root, (igraph_neimode_t)mode, includeUnreachableFromRoot, null, null, null, null, inWrapper, outWrapper, tag);
140    }
141  }
142}
Note: See TracBrowser for help on using the repository browser.