diff --git a/src/grafos/DirectedSocialNetwork.java b/src/grafos/DirectedSocialNetwork.java index fb8691370f4a4f648183f515134366257cf08d90..166a1a12dccc65ae339701de5d1b8af802b6cf59 100644 --- a/src/grafos/DirectedSocialNetwork.java +++ b/src/grafos/DirectedSocialNetwork.java @@ -186,7 +186,7 @@ public class DirectedSocialNetwork extends public double espectedSpread(HashSet<Actor> seed, boolean ic) { double media = 0; int soma = 0; - int repeticoes = 5000; + int repeticoes =100; if (!ic) { HashSet<Actor> ativados = linearThresholdDiffusion(seed); diff --git a/src/plot/JGnuplot.java b/src/plot/JGnuplot.java new file mode 100644 index 0000000000000000000000000000000000000000..597f6ca2f409175d000cee255f5d4e1bee62fe18 --- /dev/null +++ b/src/plot/JGnuplot.java @@ -0,0 +1,551 @@ +package plot; +import java.io.FileWriter; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.Date; +import java.util.List; +import java.util.Scanner; + +import org.leores.ecpt.TRuntimeException; +import org.leores.util.Logger; +import org.leores.util.SysUtil; +import org.leores.util.SysUtil.Command; +import org.leores.util.U; +import org.leores.util.able.Processable2; +import org.leores.util.data.DataTable; +import org.leores.util.data.DataTableSet; + +/** + * We do not check the null of parameters intentionally to make the program stop + * as soon as error occurs. + * + * @author leoking + * + */ +public class JGnuplot extends Logger { + public Integer id; + public String style, style2d, style3d, header; + public String plot2d, plot2dBar, plot3d, plotDensity, plotImage, multiplot, plotx; + public String beforeStyle, beforeStyleVar, afterStyleVar, afterStyle, beforeHeader, extra, afterHeader, bp; + public String terminal, output; + public String sPatNumOut; + protected String sFTemp; + public String sFLoad; + protected static JGnuplot tJGnuplot; + protected static Integer maxId = 0; + + public static final int JG_InNewThread = 0x00000001; + public static final int JG_DeleteTempFile = 0x00000002; + public static final int JG_Pause = 0x00000004; + public static final int JG_Log = 0x00000008; + public static final int JG_Default = JG_DeleteTempFile | JG_Pause | JG_Log; + public static final int JG_All = ~0x00000000; + + public JGnuplot(boolean bCopyLoadFromFile) { + initialize(bCopyLoadFromFile); + } + + public JGnuplot() { + initialize(false); + } + + public static synchronized JGnuplot tJGnuplot() { + if (tJGnuplot == null) { + tJGnuplot = new JGnuplot(true); + } + return tJGnuplot; + } + + public static int delAllTempFiles() { + return U.deleleFiles("JGnuplotTemp.*plt"); + } + + public synchronized static int nextId() { + maxId++; + return maxId; + } + + public boolean initialize(boolean bCopyLoadFromFile) { + boolean rtn = false; + id = nextId(); + bp = ""; + sFLoad = "jgnuplot.xml"; + String sFTempEnd = "_" + id; + sFTemp = "JGnuplotTemp" + sFTempEnd + ".plt"; + if (bCopyLoadFromFile) { + rtn = copyLoadFromFile(); + } else { + JGnuplot jg = tJGnuplot(); + style = jg.style; + style2d = jg.style2d; + style3d = jg.style3d; + header = jg.header; + extra = jg.extra; + plot2d = jg.plot2d; + plot2dBar = jg.plot2dBar; + plot3d = jg.plot3d; + plotDensity = jg.plotDensity; + plotImage = jg.plotImage; + multiplot = jg.multiplot; + plotx = jg.plotx; + sPatNumOut = jg.sPatNumOut; + rtn = true; + } + initialize(); + return rtn; + } + + public void initialize() { + } + + public boolean load(String str) { + return U.loadFromString(this, str); + } + + public boolean copyLoadFromFile() { + U.copyFileFromClassPath(JGnuplot.class, sFLoad, sFLoad, false);//this also works in a jar file + return U.loadFromXML(this, sFLoad, false); + } + + public void afterLoadObj(String sLoadMethod) { + U.processFields(this, U.modAll, new Processable2.TrimStringField()); + } + + protected boolean prep() { + return true; + } + +// public boolean compile(Plot plot, String code, String sFile) { +// boolean rtn = false; +// +// if (plot != null && sFile != null && prep()) { +// String sFileTU = U.toValidFileName(sFile); +// String codeEvaled = code; +// if (codeEvaled == null) { +// codeEvaled = plot2d; +// int nColumn = plot.nColumn(0, 0); +// if (nColumn == 3) { +// codeEvaled = plot3d; +// } +// } +// for (int i = 0; i < 5; i++) { +// codeEvaled = U.eval(codeEvaled, this, U.EVAL_InvalidIgnore | U.EVAL_NullIgnore); +// } +// rtn = plot.compile(codeEvaled, sFileTU, sPatNumOut); +// } +// +// return rtn; +// } + /** + * Modified by Renato Melo, to preserve the "/" symbol + * @param plot + * @param code + * @param sFile + * @return + */ + public boolean compile(Plot plot, String code, String sFile) { + boolean rtn = false; + + if (plot != null && sFile != null && prep()) { +// String sFileTU = U.toValidFileName(sFile); + String codeEvaled = code; + if (codeEvaled == null) { + codeEvaled = plot2d; + int nColumn = plot.nColumn(0, 0); + if (nColumn == 3) { + codeEvaled = plot3d; + } + } + for (int i = 0; i < 5; i++) { + codeEvaled = U.eval(codeEvaled, this, U.EVAL_InvalidIgnore | U.EVAL_NullIgnore); + } + rtn = plot.compile(codeEvaled, sFile, sPatNumOut); + } + + return rtn; + } + + public boolean compile(Plot plot, String code) { + return compile(plot, code, plot.info + ".plt"); + } + + public boolean compile(Plot plot) { + return compile(plot, null, plot.info + ".plt"); + } + + protected String sCommand(String sFile, boolean bPause) { + String rtn = "gnuplot " + sFile; + if (bPause) { + rtn += " -e \"pause mouse key\""; + } + return rtn; + } + + /** + * flags:<br> + * <b>JG_InNewThread</b> <br> + * <b>JG_DeleteTempFile:</b> use ~JG_DeleteTempFile flag to keep the temp + * file. This is useful when doing multi-thread plotting. The temp files + * shold be deleted at the end all together (delAllTempFiles()) to guarantee + * all figures can be plotted before temp files are deleted.<br> + * <b>JG_Pause</b><br> + * <b>JG_Log</b><br> + * <b>JG_Default</b> = JG_DeleteTempFile | JG_Pause | JG_Log<br> + * <b>JG_All</b> + * + * @param plot + * @param code + * @param flags + * @return + */ + public Command execute(Plot plot, String code, int flags) { + Command rtn = null; + U.deleteFile(sFTemp); + if (compile(plot, code, sFTemp)) { + String sCmd = sCommand(sFTemp, (flags & JG_Pause) > 0); + rtn = SysUtil.execCmd(sCmd, (flags & JG_Log) > 0, (flags & JG_InNewThread) > 0); + if ((flags & JG_DeleteTempFile) > 0) { + U.deleleFiles("^" + sFTemp + ".*"); + } + } + return rtn; + } + + public Command execute(Plot plot, String code) { + return execute(plot, code, JG_Default); + } + + public Command execute(Plot plot) { + return execute(plot, null, JG_Default); + } + + /** + * Execute the plot in a new thread so that the current thread can go on + * without waiting. The execution results can be obtained through calling + * waitForRtn() of the return Command obj (this will cause the current + * thread to wait). + * + * @param plot + * @param code + * @return + */ + public Command executeA(Plot plot, String code) { + return execute(plot, code, JG_All); + } + + public Command executeA(Plot plot) { + return execute(plot, null, JG_All); + } + + public static class Plot extends Logger { + public String info; + public String beforeStyle2, beforeStyleVar2, afterStyleVar2, afterStyle2, beforeHeader2, extra2, extra3, afterHeader2, bp2; + public String xlabel, ylabel, zlabel, xrange, yrange, zrange; + protected List<DataTableSet> lDataTableSet; + protected String sPatNumOut; + protected String sFile; + protected Integer fid; + + protected Integer nextFid() { + fid++; + return fid; + } + + public Plot(String info) { + this.info = info; + lDataTableSet = new ArrayList<DataTableSet>(); + initialize(); + } + + public void initialize() { + fid = 0; + bp2 = ""; + } + + public boolean autoSetLabels() { + boolean rtn = false; + DataTableSet dts = getDataTableSet(0); + if (dts != null) { + int ndt = dts.size(); + if (ndt > 0) { + DataTable dt = dts.get(0); + String[] cns = dt.getColNames(); + if (cns != null) { + rtn = true; + if (ndt == 1) { + if (cns.length > 0) {//1 or more + xlabel = cns[0]; + } + if (cns.length > 1) {//2 or more + ylabel = cns[1]; + } + if (cns.length > 2) {//3 or more + zlabel = cns[2]; + } + } else {//ndt>1 + if (cns.length > 1) {//2 or more + xlabel = cns[0]; + } + if (cns.length > 2) {//3 or more + ylabel = cns[1]; + } + } + + } + } + } + return rtn; + } + + public boolean load(String str) { + return U.loadFromString(this, str); + } + + public DataTableSet addNewDataTableSet(String info) { + DataTableSet dataTableSet = new DataTableSet(info); + add(dataTableSet); + return dataTableSet; + } + + public int add(DataTableSet... dataTableSets) { + int rtn = 0; + for (int i = 0; i < dataTableSets.length; i++) { + if (dataTableSets[i] != null) { + if (lDataTableSet.add(dataTableSets[i])) { + rtn++; + } + } + } + return rtn; + } + + public boolean addAll(Collection<? extends DataTableSet> dataTableSets) { + boolean rtn = false; + if (dataTableSets != null) { + rtn = lDataTableSet.addAll(dataTableSets); + } + return rtn; + } + + public DataTableSet getDataTableSet(int i) { + DataTableSet rtn = null; + if (i >= 0 && i < lDataTableSet.size()) { + return lDataTableSet.get(i); + } + return rtn; + } + + public DataTable getDataTable(int iDataTableSet, int iDataTable) { + DataTable rtn = null; + DataTableSet dts = getDataTableSet(iDataTableSet); + if (dts != null) { + rtn = dts.get(iDataTable); + } + return rtn; + } + + public List<DataTableSet> getDataTableSets() { + return lDataTableSet; + } + + protected boolean prep() { + return true; + } + + public boolean compile(String code, String sFile, String sPatNumOut) { + boolean rtn = false; + if (code != null && prep()) { + this.sFile = sFile; + this.sPatNumOut = sPatNumOut; + //U.deleteFile(sFile); + Scanner scanner = new Scanner(code); + while (scanner.hasNextLine()) { + String line = scanner.nextLine(); + try { + //Those lines with invalid/null fields/methods/expressions will be cause a runtime exception here. + String lineEvaled = line; + for (int i = 0; i < 5 && (!U.bNoEval(lineEvaled)); i++) { + lineEvaled = U.eval(lineEvaled, this, U.EVAL_InvalidException | U.EVAL_NullException); + } + if (U.bNoEval(lineEvaled)) { + lineEvaled = lineEvaled.substring(U.sNoEval.length()); + } + if (lineEvaled.length() > 0) { + U.appendFile(sFile, lineEvaled + "\n"); + } + rtn = true; + } catch (TRuntimeException exception) { + //log(exception); + } + } + scanner.close(); + } + return rtn; + } + + public int size() { + return lDataTableSet.size(); + } + + public int nColumn(int iDataTableSet, int iDataTable) { + int rtn = -1; + if (iDataTableSet >= 0 && iDataTableSet < lDataTableSet.size()) { + DataTableSet dts = lDataTableSet.get(iDataTableSet); + if (iDataTable >= 0 && iDataTable < dts.size()) { + rtn = dts.get(iDataTable).nColumns(); + } + } + return rtn; + } + + public Integer size(String dataTableSetNum) { + Integer rtn = null; + int iDataTableSet = Integer.parseInt(dataTableSetNum) - 1; + if (iDataTableSet >= 0 && iDataTableSet < lDataTableSet.size()) { + rtn = lDataTableSet.get(iDataTableSet).size(); + } + return rtn; + } + + public Integer nColumn(String dataTableSetNum, String dataTableNum) { + int iDataTableSet = Integer.parseInt(dataTableSetNum) - 1; + int iDataTable = Integer.parseInt(dataTableNum) - 1; + Integer rtn = nColumn(iDataTableSet, iDataTable); + if (rtn < 0) { + rtn = null; + } + return rtn; + } + + public String info(String dataTableSetNum) { + String rtn = null; + int iDataTableSet = Integer.parseInt(dataTableSetNum) - 1; + if (iDataTableSet >= 0 && iDataTableSet < lDataTableSet.size()) { + DataTableSet dts = lDataTableSet.get(iDataTableSet); + rtn = dts.info; + } + return rtn; + } + + public String info(String dataTableSetNum, String dataTableNum) { + String rtn = null; + int iDataTableSet = Integer.parseInt(dataTableSetNum) - 1; + if (iDataTableSet >= 0 && iDataTableSet < lDataTableSet.size()) { + DataTableSet dts = lDataTableSet.get(iDataTableSet); + int iDataTable = Integer.parseInt(dataTableNum) - 1; + if (iDataTable >= 0 && iDataTable < dts.size()) { + rtn = dts.get(iDataTable).info; + } + } + return rtn; + } + + public String infos() { + StringBuffer sBuffer = new StringBuffer(); + for (int i = 0, mi = lDataTableSet.size(); i < mi; i++) { + DataTableSet dts = lDataTableSet.get(i); + sBuffer.append("info" + (i + 1) + "=\"" + dts.info + "\";\n"); + for (int j = 0, mj = dts.size(); j < mj; j++) { + DataTable dt = dts.get(j); + sBuffer.append("info" + (i + 1) + "_" + (j + 1) + "=\"" + dt.info + "\";\n"); + } + } + String sInfos = sBuffer.toString(); + sInfos = U.sNoEval + sInfos.substring(0, sInfos.length() - 1);//remove the last line break; + return sInfos; + } + + protected void saveToFile(String sFile, DataTable dt, String type) { + String sLastColumn1 = null; + String[] colNames = dt.getColNames(); + try { + FileWriter fw = new FileWriter(U.createIfNotExist(sFile), true); + if (colNames != null) { + String line = "#" + U.wrap(colNames, "", "", " "); + fw.append(line + "\n"); + } + for (int i = 0, mj = dt.nRows(); i < mj; i++) { + Object[] row = dt.getRow(i); + String[] sRow = U.toStrArray(Arrays.asList(row), sPatNumOut); + if ("3d".equals(type)) { + if (sLastColumn1 == null) { + sLastColumn1 = sRow[0]; + } + if (!sLastColumn1.equals(sRow[0])) { + fw.append("\n"); + sLastColumn1 = sRow[0]; + } + } + String line = U.wrap(sRow, "", "", " "); + fw.append(line + "\n"); + } + fw.append("e\n"); + fw.flush(); + fw.close(); + } catch (IOException e) { + log(e); + } + } + + public String data(String dataTableSetNum, String dataTableNum, String type) { + String rtn = null; + if (data2f(sFile, dataTableSetNum, dataTableNum, type) != null) { + rtn = ""; + } + return rtn; + } + + public String data2f(String fn, String dataTableSetNum, String dataTableNum, String type) { + String rtn = null; + int iDataTableSet = Integer.parseInt(dataTableSetNum) - 1; + if (fn != null && iDataTableSet >= 0 && iDataTableSet < lDataTableSet.size() && type != null) { + DataTableSet dts = lDataTableSet.get(iDataTableSet); + if (dataTableNum == null) { + for (int i = 0, mi = dts.size(); i < mi; i++) { + DataTable dt = dts.get(i); + saveToFile(fn, dt, type); + } + rtn = fn; + } else { + int iDataTable = Integer.parseInt(dataTableNum) - 1; + if (iDataTable >= 0 && iDataTable < dts.size()) { + DataTable dt = dts.get(iDataTable); + saveToFile(fn, dt, type); + rtn = fn; + } + } + } + return rtn; + } + + public String data2f(String dataTableSetNum, String dataTableNum, String type) { + String rtn = data2f(sFile + "-D" + nextFid(), dataTableSetNum, dataTableNum, type); + return rtn; + } + + public String data2f(String dataTableSetNum, String type) { + String rtn = data2f(dataTableSetNum, null, type); + return rtn; + } + + public String data(String dataTableSetNum, String type) { + return data(dataTableSetNum, null, type); + } + + public String data(String dataTableSetNum) { + return data(dataTableSetNum, null, "2d"); + } + + public String setInfo(String dataTableSetNum, String info) { + int iDataTableSet = Integer.parseInt(dataTableSetNum) - 1; + if (iDataTableSet >= 0 && iDataTableSet < lDataTableSet.size()) { + DataTableSet dts = lDataTableSet.get(iDataTableSet); + dts.info = info; + } + return ""; + } + } + +} diff --git a/src/plot/MeuPlot.java b/src/plot/MeuPlot.java index 83e2bd358f0772dcbee5bb37a1fe07e070246b53..15eb0b02b7d4c58519036c295a0bde0a6d5182c1 100644 --- a/src/plot/MeuPlot.java +++ b/src/plot/MeuPlot.java @@ -65,10 +65,10 @@ public class MeuPlot extends JGnuplot { String saida = outDir+"propagacao_esperada.plt"; plot.compile(plotPropagacao, plot.plot2d, saida); -// this.terminal = "epslatex color colortext dashed"; -// this.output = outDir+"propagacao.tex'"; - this.terminal = "eps color dashed"; - this.output = outDir+"propagacao.eps"; + this.terminal = "epslatex color colortext dashed"; + this.output = outDir+"propagacao.tex"; +// this.terminal = "eps color dashed"; +// this.output = outDir+"propagacao.eps"; this.execute(plotPropagacao, this.plot2d); } @@ -85,7 +85,23 @@ public class MeuPlot extends JGnuplot { return x2; } - public void plotChamadas(double[] y1, double[] y2, String outDir){ + public void plotTime(double timePS, double timeCelf, double timeHD, double timeRS, String outDir){ + JGnuplot jg = new JGnuplot(); + Plot plot = new Plot("") { + { + xlabel = "x"; + ylabel = "y"; + extra2 = "set key top left"; + } + }; + double[] x = { 1, 2, 3, 4, 5 }, y1 = {}, y2 = {}; + DataTableSet dts = plot.addNewDataTableSet("2D Bar"); + DataTable dt = dts.addNewDataTable("", x, y1, y2); + dt.insert(0, new String[] { "", "y1=2x", "y2=3x" }); + jg.execute(plot, jg.plot2dBar); + } + + public void plotChamadas( String outDir){ JGnuplot jg = new JGnuplot(); Plot plot = new Plot("") { { @@ -95,7 +111,7 @@ public class MeuPlot extends JGnuplot { extra2 = "set key top left"; } }; - double[] x = { 1, 2, 3, 4, 5 }; + double[] x = { 1, 2, 3, 4, 5 }, y1 = {}, y2 = {}; DataTableSet dts = plot.addNewDataTableSet("2D Bar"); DataTable dt = dts.addNewDataTable("", x, y1, y2); dt.insert(0, new String[] { "", "y1=2x", "y2=3x" }); diff --git a/src/readgraph/GraphReader.java b/src/readgraph/GraphReader.java index 5aa0f6642dd84512bfc5f7e876922ca75e02dd69..d853657a429e59281d5de68aeb56bc2f013c186d 100644 --- a/src/readgraph/GraphReader.java +++ b/src/readgraph/GraphReader.java @@ -47,7 +47,7 @@ public class GraphReader { for (int i = 0; i < values[0]; i++) { Actor v = new Actor(i); // - v.setThreshold(Math.random()); +// v.setThreshold(Math.random()); g.addVertex(v); vertices[i] = v; } @@ -81,16 +81,15 @@ public class GraphReader { * Sorteia um valor aleatório */ public double peso() { - // int p = (int) (Math.random() * 3); // double[] choice = { 0.2, 0.04, 0.008 }; // return choice[p]; // uniform IC model -// return (double)10/100; -// return 0.025; - return Math.random()/4; -// return 0.0025; +// return (double)10/100; +// return 0.001; +// return Math.random()/4; + return 0.0025; } public DirectedSocialNetwork readEpinions() { @@ -121,6 +120,20 @@ public class GraphReader { return run(n, m, arquivo); } + public DirectedSocialNetwork amazon() { + int n = 262111; + int m = 1234877; + String arquivo = "data/Amazon0302.txt"; + return run(n, m, arquivo); + } + + public DirectedSocialNetwork enron() { + int n = 36692; + int m = 367662; + String arquivo = "data/enron.txt"; + return run(n, m, arquivo); + } + public DirectedSocialNetwork readDblp() { int n = 654628; int m = 1990259; @@ -131,8 +144,11 @@ public class GraphReader { public static void main(String args[]) { GraphReader reader = new GraphReader(); DirectedSocialNetwork g; - g = reader.readEpinions(); - // g = reader.readHep(); +// g = reader.readDblp(); +// g = reader.readEpinions(); +// g = reader.readHep(); + g = reader.enron(); +// g = reader.amazon(); // NÃO tem curva power law Histograma histograma = new Histograma(); diff --git a/src/simulacao/Experimentacao.java b/src/simulacao/Experimentacao.java index 6e8b280de6b96b5f396b926c11cebb5d1457b520..8d3e0a32cb0f87f010ec1d3361fbd08f5d26fddf 100644 --- a/src/simulacao/Experimentacao.java +++ b/src/simulacao/Experimentacao.java @@ -18,18 +18,19 @@ import readgraph.GraphReader; public class Experimentacao { public static void main(String[] args) { - int k = 30; + int k = 50; // sinteticGraphSimulate(k); //Simulações a serem feita com probabilidade 0.01 - simularHep(k); - simularPhy(k); - simularAmazon(k); - simularDblp(k); - // Simulações a serem feita com probabilidade 0.0025 +// System.out.println("Simulaçoes realizadas para p = 0.025"); +// System.out.println("Grafos: HEP, PHY e DBLP"); +// simularHep(k); +// simularPhy(k); +// simularDblp(k); +// Simulações a serem feita com probabilidade 0.0025 + System.out.println("Simulaçoes realizadas para p = 0.0025"); + System.out.println("Grafos: ENRON e EPINIONS"); simularEnron(k); simularEpinions(k); - - } private static void simularHep(int k) { @@ -108,16 +109,33 @@ public class Experimentacao { private static void monteCarloSimulation(DirectedSocialNetwork g, String out, int k) { double[] spreadPS,spreadCelf, spreadHD, spreadRS; + double timePS, timeCelf, timeHD, timeRS; double[] x; + long time = 0; +// Testa o celf LazyGreedy celf = new LazyGreedy(g); System.out.println("#Celf"); + + time = System.currentTimeMillis() * -1; celf.escolher(k); + time += System.currentTimeMillis(); + + timeCelf = (time / 1000.0f); + System.out.println("Tempo: "+timeCelf); spreadCelf = celf.getSpreadData(); + +// Testa o PrevalentSeed PrevalentSeed ps = new PrevalentSeed(g); System.out.println("#PrevalentSeed"); + + time = System.currentTimeMillis() * -1; ps.escolher(k); + time += System.currentTimeMillis(); + + timePS = (time / 1000.0f); + System.out.println("Tempo: "+timePS); spreadPS = ps.getSpreadData(); // // Testa a heuristica de grau diff --git a/src/simulacao/Simulacao.java b/src/simulacao/Simulacao.java index 06acdc21bb53c0981b69dfa7fac1dd1e59136303..8767ab0e9363fffd98070eedf4023485702a1dd8 100644 --- a/src/simulacao/Simulacao.java +++ b/src/simulacao/Simulacao.java @@ -72,8 +72,7 @@ public class Simulacao { } MeuPlot meuplot = new MeuPlot(); - meuplot.plotPropagacao(tamSemente, sigma1, sigma2, sigma3, sigma4, - outDir); +// meuplot.plotPropagacao(tamSemente, sigma1, sigma2, sigma3, sigma4,outDir); meuplot.plotTempoExecucao(tamSemente, tempo1, tempo2, tempo3, tempo4, outDir); } @@ -170,8 +169,7 @@ public class Simulacao { } MeuPlot meuplot = new MeuPlot(); - meuplot.plotPropagacao(tamSemente, sigma1, sigma2, sigma3, sigma4, - outDir); +// meuplot.plotPropagacao(tamSemente, sigma1, sigma2, sigma3, sigma4,outDir); meuplot.plotTempoExecucao(tamSemente, tempo1, tempo2, tempo3, tempo4, outDir); }