Package samples.pert

Source Code of samples.pert.GraphGenerator

/**
*  Copyright (c) 1999-2014, Ecole des Mines de Nantes
*  All rights reserved.
*  Redistribution and use in source and binary forms, with or without
*  modification, are permitted provided that the following conditions are met:
*
*      * Redistributions of source code must retain the above copyright
*        notice, this list of conditions and the following disclaimer.
*      * Redistributions in binary form must reproduce the above copyright
*        notice, this list of conditions and the following disclaimer in the
*        documentation and/or other materials provided with the distribution.
*      * Neither the name of the Ecole des Mines de Nantes nor the
*        names of its contributors may be used to endorse or promote products
*        derived from this software without specific prior written permission.
*
*  THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
*  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
*  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
*  DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
*  DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
*  (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
*  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
*  ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
*  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

package samples.pert;

import java.util.BitSet;
import java.util.Random;

/**
* <br/>
*
* @author Xavier Lorca
* @since 31/03/11
*/
public class GraphGenerator {

    int n;
    int nbPrec;
    int nbNeq;
    Random rand;
    int idx;
    int[] dfsTree;

    //static Pair pair = new Pair(0, 0);

    // nbPrec < (n^2-n)/2
    public GraphGenerator(int n, int nbPrec, int nbNeq, Random rand) {
        this.n = n;
        this.nbPrec = nbPrec;
        if (nbPrec > ((n * n) - n) / 2) {
            throw new UnsupportedOperationException();
        }
        this.nbNeq = nbNeq;
        this.rand = rand;
    }

    // graph restreint aux contraintes de type 1 est acyclique
    // si graph[i][j] = 1 alors var(i) < var(j)
    // si graph[i][j] = 2 alors var(i) =/= var(j)
    public int[][] generate() {
        int[][] graph = new int[n][n];

        BitSet precs = new BitSet();
        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {
                int ij = i * n + j;
                precs.set(ij, true);

            }
        }


        // on bouche jusqu'a la limite pour creer les contraintes 1
        while (nbPrec > 0) {
            //Pair p = precs.get(rand.nextInt(precs.size()));
            int ij = precs.nextSetBit(0);
            int index = rand.nextInt(precs.cardinality());
            while (index > 0) {
                ij = precs.nextSetBit(ij + 1);
                index--;
            }
            assert (ij > -1);
            graph[ij / n][ij % n] = 1;
            precs.set(ij, false);
            nbPrec--;
        }

        // on assure que chaque sommet i > 0 a un pred
        for (int i = 1; i < n; i++) {
            int k = 0;
            while (k < n && graph[k][i] != 1) {
                k++;
            }
            if (k == n) {
                graph[0][i] = 1;
                precs.set(i, false);
            }
        }

        // on assure que chaque sommet i < n-1 a un succ
        for (int i = 0; i < n - 1; i++) {
            int k = i + 1;
            while (k < n && graph[i][k] != 1) {
                k++;
            }
            if (k == n) {
                graph[i][n - 1] = 1;
                precs.set((i * n) + n - 1, false);
            }
        }

        // on bouche jusqu'a la limite pour creer les contraintes 2
        BitSet neqs = new BitSet();
        neqs.or(precs);
        while (nbNeq > 0 && neqs.cardinality() > 0) {
            int ij = neqs.nextSetBit(0);
            int index = rand.nextInt(neqs.cardinality());
            while (index > 0) {
                ij = neqs.nextSetBit(ij + 1);
                index--;
            }
            assert (ij > -1);
            graph[ij / n][ij % n] = 2;
            neqs.set(ij, false);
            nbNeq--;
        }
        computeTRfromScratch(graph);
        return graph;
    }

    private void computeTRfromScratch(int[][] graph) {
        dfsTree = new int[n];
        for (int i = 0; i < n; i++) {
            int[][] num = new int[n][2];
            for (int j = 0; j < n; j++) {
                num[j][0] = -1;
                num[j][1] = -1;
            }
            idx = 0;
            for (int k = 0; k < n; k++) {
                dfsTree[k] = -1;
            }
            dfs(i, i, num, graph);
        }
    }

    private int[][] dfs(int root, int u, int[][] num, int[][] trgraph) {
        num[u][0] = idx++;
        for (int v = 0; v < n; v++) {
            if (trgraph[u][v] == 1) {
                if (num[v][0] == -1) {
                    dfsTree[v] = u;
                    num = dfs(root, v, num, trgraph);
                } else {
                    if (num[u][1] == -1 && num[u][0] > num[v][0]) {
                        int w = dfsTree[v];
                        if (w == root) { // (w,v) is a transitive arc in the dfs tree
                            trgraph[w][v] = 0;
                        }
                    }
                    // (u,v) is a transitive arc in a specific branch of the dfs tree
                    if (num[v][1] != -1 && num[u][0] < num[v][0]) {
                        trgraph[u][v] = 0;
                    }
                }
            }
        }
        num[u][1] = idx++;
        return num;
    }

    public static void main(String[] args) {
        int n = 5;
        int nbPrecs = 10;
        int nbNeqs = 0;
        System.out.println("******* " + nbPrecs + " ********");
        Random rand = new Random(0);
        long t = System.currentTimeMillis();
        GraphGenerator gen = new GraphGenerator(n, nbPrecs, nbNeqs, rand);
        int[][] graph = gen.generate();
        t = System.currentTimeMillis() - t;
        System.out.println("time : " + t);
        for (int i = 0; i < n; i++) {
            System.out.print(i + ": ");
            for (int j = 0; j < n; j++) {
                if (graph[i][j] == 1) {
                    System.out.print(j + " ");
                }
                if (graph[i][j] == 2) {
                    System.out.print("(" + j + ")" + " ");
                }
            }
            System.out.println();
        }//*/
    }

}
TOP

Related Classes of samples.pert.GraphGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.