/*
 * Sparsifiers.h
 *
 *  Created on: 23.07.2014
 *      Author: Gerd Lindner
 */

#ifndef NETWORKIT_SPARSIFICATION_SPARSIFIERS_HPP_
#define NETWORKIT_SPARSIFICATION_SPARSIFIERS_HPP_

#include <networkit/graph/Graph.hpp>

namespace NetworKit {

/**
 * In this file, edge score calculators and edge score filters are combined
 * into different sparsification algorithms.
 */

/**
 * Abstract base class for Sparsifiers.
 */
class Sparsifier {

public:

    Sparsifier(const Graph& inputGraph);

    virtual ~Sparsifier() = default;

    /**
     * REQ: Needs to fill outputGraph and set hasOutput to true.
     */
    virtual void run() = 0;

    Graph getGraph();

protected:
    const Graph& inputGraph;
    Graph outputGraph;
    bool hasOutput;

};


/**
 * Imlementation of the non-parametric variant of Simmelian Backbones,
 * as introduced by Nick et al.
 */
class SimmelianSparsifierNonParametric : public Sparsifier {

public:
    /**
     * Creates a new instance of the non-parametric (jaccard) variant of the Simmelian Backbone calculator.
     * @param graph			the input graph
     * @param threshold		the jaccard index threshold.
     */
    SimmelianSparsifierNonParametric(const Graph& graph, double threshold);

    virtual void run() override;

private:
    double threshold;

};

 /**
  * Imlementation of the parametric variant (Top-k neighborhood overlap)
  * of Simmelian Backbones, as introduced by Nick et al.
  */
class SimmelianSparsifierParametric : public Sparsifier {

public:
    /**
     * Creates a new instance of the parametric variant of the Simmelian Backbone calculator.
     * @param graph			the input graph
     * @param maxRank 		the maximum rank that is considered for overlap calculation
     * @param minOverlap	the minimum overlap of the top-k neighbors for an edge to be
                                contained in the sparsified graph.
     */
    SimmelianSparsifierParametric(const Graph& graph, int maxRank, int minOverlap);

    virtual void run() override;

private:
    int maxRank;
    int minOverlap;

};

/**
 * Implementation of the Multiscale Backbone, as introduced by Serrano et al.
 */
class MultiscaleSparsifier : public Sparsifier {

public:
    /**
     * Creates a new instance of the Multiscale Backbone calculator.
     * @param graph			the input graph
     * @param alpha 		the probability threshold
     */
    MultiscaleSparsifier(const Graph& graph, double alpha);

    virtual void run() override;

private:
    double alpha;

};

/**
 * Local Similarity Sparsification as introduced by Satuluri et al.
 */
class LocalSimilaritySparsifier : public Sparsifier {

public:
    /**
     * Creates a new instance of the Local Similarity sparsifier.
     * @param graph			the input graph
     * @param e				the threshold value
     */
    LocalSimilaritySparsifier(const Graph& graph, double e);

    virtual void run() override;

private:
    double e;

};

/**
 * Multiscale backbone using simmelianness as input weight.
 */
class SimmelianMultiscaleSparsifier : public Sparsifier {

public:
    /**
     * Creates a new instance of the Simmelian Multiscale Backbone calculator
     * @param graph			the input graph
     * @param alpha			the threshold value for multiscale filtering
     */
    SimmelianMultiscaleSparsifier(const Graph& graph, double alpha);

    virtual void run() override;

private:
    double alpha;

};

/**
* Produces sparsified graphs that contain approximately a given percentage
* of edges of the original graph. The edges are selected unformly at random.
*/
class RandomSparsifier : public Sparsifier {

public:
    /**
    * Creates a new instance of the Random Sparsifier.
    * @param graph			the input graph
    * @param ratio			edge ratio in [0,1] to be kept in the sparse graph.
    */
    RandomSparsifier(const Graph& graph, double ratio);

    virtual void run() override;

private:
    double ratio;

};

} /* namespace NetworKit */
#endif // NETWORKIT_SPARSIFICATION_SPARSIFIERS_HPP_
