/*******************************************************************************
* Copyright (c) 2014 EURA NOVA.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the GNU Public License v2.0
* which accompanies this distribution, and is available at
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
*
* Contributors:
* Aldemar Reynaga - initial API and implementation
* Salim Jouili - initial API and implementation
******************************************************************************/
package com.steffi.testing;
import gnu.trove.set.TLongSet;
import gnu.trove.set.hash.TLongHashSet;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import com.steffi.common.IOUtils;
/**
* @author Aldemar Reynaga
* Generates a text file representing a graph with only on path for some traversals
*/
public class SinglePathGraphGenerator {
private BufferedWriter graphFileWriter;
private int subGraphSize;
private int numberOfNodes;
private Random randomGen;
private int startNodeEdges;
private int normalNodeEdges;
private float numbOfEdgesVar;
private int maxNumberOfQueries;
private int depth;
public SinglePathGraphGenerator(int numberOfNodes, int subGraphSize,
int maxNumberOfQueries, int depth, int startNodeEdges,
int normalNodeEdges, float numbOfEdgesVar) {
this.numberOfNodes = numberOfNodes;
this.subGraphSize = subGraphSize;
this.maxNumberOfQueries = maxNumberOfQueries;
this.depth = depth;
this.startNodeEdges = startNodeEdges;
this.normalNodeEdges = normalNodeEdges;
this.randomGen = new Random();
this.numbOfEdgesVar = numbOfEdgesVar;
}
private void generateNodeEdges(long nodeId, int maxEdges, int requiredEdges) throws IOException {
TLongSet destNodeIds = new TLongHashSet();
long destNodeId=0;
for (int j=0; j<maxEdges && j<requiredEdges; j++) {
do {
destNodeId = nodeId + TestTools.nextLong(randomGen, maxEdges)+1;
} while (destNodeIds.contains(destNodeId));
destNodeIds.add(destNodeId);
graphFileWriter.newLine();
graphFileWriter.write(nodeId + "\t" + destNodeId);
}
}
private void generateSubGraph(long startNodeId) throws IOException {
int numberOfEdges;
for (int i=0; i<(startNodeId+subGraphSize-2) && i<=numberOfNodes; i++) {
if (i==0)
numberOfEdges = startNodeEdges + randomGen.nextInt((int) numbOfEdgesVar);
else
numberOfEdges = normalNodeEdges + randomGen.nextInt((int) numbOfEdgesVar);
generateNodeEdges(startNodeId+i, subGraphSize-i+1, numberOfEdges);
}
graphFileWriter.flush();
}
private void generateQueries(ArrayList<Long> startNodes, String queryFileName) throws IOException {
List<NodePair> queries = new ArrayList<NodePair>();
BufferedWriter queryFileWriter = null;
for (int i= 0; (i+depth)<startNodes.size() && queries.size() < maxNumberOfQueries; i++)
queries.add(new NodePair(startNodes.get(i), startNodes.get(i+depth)));
for (int j=0; j<(queries.size()-j) && queries.size() < maxNumberOfQueries; j++)
queries.add(new NodePair(queries.get(j).getNodeBId(), queries.get(j).getNodeAId()));
try {
queryFileWriter = new BufferedWriter(new FileWriter(new File(
queryFileName), false));
queryFileWriter.write("#START_NODE_ID\tSEARCHED_NODE_ID");
for (NodePair nodePair : queries) {
queryFileWriter.newLine();
queryFileWriter.write(nodePair.getNodeAId() + "\t" + nodePair.getNodeBId());
}
queryFileWriter.flush();
} finally {
if (queryFileWriter != null) {try {queryFileWriter.close();}catch(IOException ioe){}}
}
}
public void generate(String graphFileName, String queryFileName) throws Exception {
long prevStartNodeId=0;
long curStartNodeId=1;
ArrayList<Long> startNodes = new ArrayList<Long>();
try {
graphFileWriter = new BufferedWriter(new FileWriter(new File(
graphFileName), false));
graphFileWriter.write("#SOURCE_NODE\tDESTINATION_NODE");
do {
if (prevStartNodeId > 0) { //Generate link between subgraphs
graphFileWriter.newLine();
graphFileWriter.write(prevStartNodeId + "\t" + curStartNodeId);
}
startNodes.add(curStartNodeId);
generateSubGraph(curStartNodeId);
prevStartNodeId = curStartNodeId;
curStartNodeId = prevStartNodeId + subGraphSize;
System.out.println(curStartNodeId + " nodes written");
} while(curStartNodeId<=numberOfNodes);
graphFileWriter.flush();
generateQueries(startNodes, queryFileName);
} finally {
if (graphFileWriter!=null) {try{graphFileWriter.close();}catch(IOException ioe){}}
}
}
public static void main(String [] args) {
try {
int numberOfNodes = Integer.parseInt(IOUtils.readLine("Number of nodes: "));
int subGraphSize = Integer.parseInt(IOUtils.readLine("Sub graph size: "));
int maxQueries = Integer.parseInt(IOUtils.readLine("Max number of queries: "));
int maxDepthQuery = Integer.parseInt(IOUtils.readLine("Max depth for queries: "));
int startNodeEdges = Integer.parseInt(IOUtils.readLine("Number of edges of start node: "));
int normalNodeEdges = Integer.parseInt(IOUtils.readLine("Number of edges of normal node: "));
int nodeEdgesVar = Integer.parseInt(IOUtils.readLine("Max variation of add edges: "));
String outGraphFileName = IOUtils.readLine("Graph file name: ");
String outTestFileName = IOUtils.readLine("Test file name: ");
SinglePathGraphGenerator generator = new SinglePathGraphGenerator(numberOfNodes,
subGraphSize, maxQueries, maxDepthQuery, startNodeEdges, normalNodeEdges, nodeEdgesVar);
generator.generate(outGraphFileName, outTestFileName);
System.out.println("OK");
} catch (Exception e) {
e.printStackTrace();
}
}
}