org.matsim.contrib.socnetgen.sna.graph.matrix.MatrixAPL.java Source code

Java tutorial

Introduction

Here is the source code for org.matsim.contrib.socnetgen.sna.graph.matrix.MatrixAPL.java

Source

/* *********************************************************************** *
 * project: org.matsim.*
 * MatrixAPL.java
 *                                                                         *
 * *********************************************************************** *
 *                                                                         *
 * copyright       : (C) 2011 by the members listed in the COPYING,        *
 *                   LICENSE and WARRANTY file.                            *
 * email           : info at matsim dot org                                *
 *                                                                         *
 * *********************************************************************** *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *   See also COPYING, LICENSE and WARRANTY file                           *
 *                                                                         *
 * *********************************************************************** */
package org.matsim.contrib.socnetgen.sna.graph.matrix;

import gnu.trove.list.array.TDoubleArrayList;
import gnu.trove.list.array.TIntArrayList;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.math.stat.descriptive.DescriptiveStatistics;
import org.apache.log4j.Logger;
import org.matsim.contrib.common.util.ProgressLogger;
import org.matsim.contrib.socnetgen.sna.util.MultiThreading;

/**
 * @author illenberger
 * 
 */
public class MatrixAPL {

    private static final Logger logger = Logger.getLogger(MatrixAPL.class);

    private int numThreads;

    private boolean calcDistr = true;

    public MatrixAPL() {
        this.numThreads = MultiThreading.getNumAllowedThreads();
    }

    public MatrixAPL(int numThreads) {
        this.numThreads = numThreads;
    }

    public void setCalcAPLDistribution(boolean flag) {
        this.calcDistr = flag;
    }

    public DescriptiveStatistics apl(AdjacencyMatrix<?> y) {
        List<APLThread> threads = new ArrayList<APLThread>();
        int size = (int) Math.floor(y.getVertexCount() / (double) numThreads);
        int i_start = 0;
        int i_stop = size;
        for (int i = 0; i < numThreads - 1; i++) {
            threads.add(
                    new APLThread(y, new SingelPathDijkstra(y, new CostFunction()), i_start, i_stop, calcDistr));
            i_start = i_stop;
            i_stop += size;
        }
        threads.add(new APLThread(y, new SingelPathDijkstra(y, new CostFunction()), i_start, y.getVertexCount(),
                calcDistr));
        /*
         * start threads
         */
        logger.info(String.format("Calculating average path lenth on %1$s threads.", numThreads));
        ProgressLogger.init(y.getVertexCount(), 1, 5);
        for (APLThread thread : threads) {
            thread.start();
        }
        /*
         * wait for threads
         */
        for (APLThread thread : threads) {
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        /*
         * merge results
         */
        DescriptiveStatistics stats = new DescriptiveStatistics();
        if (calcDistr) {
            for (APLThread thread : threads) {
                TDoubleArrayList vals = thread.getValues();
                for (int i = 0; i < vals.size(); i++) {
                    stats.addValue(vals.get(i));
                }
            }
        } else {
            long lengthSum = 0;
            long pathCount = 0;
            for (APLThread thread : threads) {
                lengthSum += thread.lengthSum;
                pathCount += thread.pathCount;
            }
            stats.addValue(lengthSum / (double) pathCount);
        }

        return stats;
    }

    private class APLThread extends Thread {

        private final AdjacencyMatrix<?> y;

        private final SingelPathDijkstra dijkstra;

        private final int startIdx;

        private final int endIdx;

        private final TDoubleArrayList stats;

        private final boolean calcDistr;

        private long lengthSum;

        private long pathCount;

        APLThread(AdjacencyMatrix<?> y, SingelPathDijkstra dijkstra, int startIdx, int endIdx, boolean calcDistr) {
            this.y = y;
            this.dijkstra = dijkstra;
            this.startIdx = startIdx;
            this.endIdx = endIdx;
            this.calcDistr = calcDistr;
            if (calcDistr)
                this.stats = new TDoubleArrayList((int) ((endIdx - startIdx) * y.getVertexCount() / 2.0));
            else
                this.stats = new TDoubleArrayList();
        }

        TDoubleArrayList getValues() {
            return stats;
        }

        @Override
        public void run() {
            for (int i = startIdx; i < endIdx; i++) {
                dijkstra.run(i, -1);
                for (int j = i + 1; j < y.getVertexCount(); j++) {
                    TIntArrayList path = dijkstra.getPath(i, j);
                    if (path != null) {
                        if (calcDistr)
                            stats.add(path.size());
                        else {
                            lengthSum += path.size();
                            pathCount++;
                        }
                    }
                }
                ProgressLogger.step();
            }
        }

    }

    private class CostFunction implements EdgeCostFunction {

        @Override
        public double edgeCost(int i, int j) {
            return 1;
        }

    }
}