Changeset - f8cbbd135cc1
[Not reviewed]
0 4 0
Tom Bannink - 9 years ago 2017-02-02 18:30:09
tombannink@gmail.com
Add triangle counting
4 files changed with 30 insertions and 5 deletions:
0 comments (0 inline, 0 general)
cpp/exports.hpp
Show inline comments
 
#pragma once
 
#include <iostream>
 
#include "graph.hpp"
 

	
 
std::ostream &operator<<(std::ostream &s, const Edge &e) {
 
    s << '{' << e.u << ',' << e.v << '}';
 
    return s;
 
}
cpp/graph.hpp
Show inline comments
 
#pragma once
 
#include <cassert>
 
#include <numeric>
 
#include <vector>
 

	
 
class Edge {
 
  public:
 
    unsigned int u, v;
 
@@ -32,13 +33,12 @@ class Graph {
 
        }
 
        adj.resize(n);
 
    }
 

	
 
    unsigned int edgeCount() const { return edges.size(); }
 

	
 
    Edge &getEdge(unsigned int i) { return edges[i]; }
 
    const Edge &getEdge(unsigned int i) const { return edges[i]; }
 

	
 
    bool createFromDegreeSequence(const DegreeSequence &d) {
 
        // Havel-Hakimi algorithm
 

	
 
        unsigned int n = d.size();
 
@@ -175,12 +175,27 @@ class Graph {
 
            edges.push_back({e1.u, e2.v});
 
            edges.push_back({e1.v, e2.u});
 
        }
 
        return true;
 
    }
 

	
 
    int countTriangles() const {
 
        int triangles = 0;
 
        for (auto& v : adj) {
 
            for (unsigned int i = 0; i < v.size(); ++i) {
 
                for (unsigned int j = i + 1; j < v.size(); ++j) {
 
                    if (hasEdge({v[i], v[j]})) {
 
                        ++triangles;
 
                    }
 
                }
 
            }
 
        }
 
        assert(triangles % 3 == 0);
 
        return triangles / 3;
 
    }
 

	
 
  private:
 
    // Graph is saved in two formats for speed
 
    // The two should be kept consistent at all times
 
    std::vector<std::vector<unsigned int>> adj;
 
    std::vector<Edge> edges;
 
};
cpp/showgraphs.m
Show inline comments
 
(* ::Package:: *)
 

	
 
gsraw=Import[NotebookDirectory[]<>"graphdata.m"];
 

	
 

	
 
gs=Map[Graph[#,GraphLayout->"CircularEmbedding"]&,gsraw];
 
gs2=Map[Graph[#,GraphLayout->Automatic]&,gsraw];
 
ListPlot[gsraw[[2]],Joined->True,PlotRange->All,AxesLabel->{"Step","Triangles"}]
 

	
 

	
 
gs=Map[Graph[#,GraphLayout->"CircularEmbedding"]&,gsraw[[1]]];
 
gs2=Map[Graph[#,GraphLayout->Automatic]&,gsraw[[1]]];
 

	
 

	
 
Grid[Partition[gs,10],Frame->All]
cpp/switchchain.cpp
Show inline comments
 
@@ -101,24 +101,30 @@ int main() {
 
    if (!chain.initialize(g)) {
 
        std::cerr << "Could not initialize Markov chain.\n";
 
        return 1;
 
    }
 

	
 
    std::ofstream outfile("graphdata.m");
 
    outfile << '{';
 
    outfile << '{' << g;
 

	
 
    std::cout << "Starting switch Markov chain" << std::endl;
 
    int movesDone = 0;
 
    int movesTotal = 100000;
 
    constexpr int movesTotal = 10000;
 
    int triangles[movesTotal];
 
    for (int i = 0; i < movesTotal; ++i) {
 
        if (chain.doMove())
 
            ++movesDone;
 
        triangles[i] = chain.g.countTriangles();
 
        if (i % (movesTotal / 50) == (movesTotal / 50 - 1))
 
            outfile << ',' << chain.g;
 
    }
 
    outfile << '}';
 
    outfile << '}' << ',' << '{' << triangles[0];
 
    for (int i = 1; i < movesTotal; ++i)
 
        outfile << ',' << triangles[i];
 
    outfile << '}' << '}';
 

	
 
    std::cout << movesDone << '/' << movesTotal << " moves succeeded."
 
              << std::endl;
 

	
 
    return 0;
 
}
0 comments (0 inline, 0 general)