
org.cpsolver.ifs.util.ToolBox Maven / Gradle / Ivy
package org.cpsolver.ifs.util;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Random;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeSet;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.core.config.Configurator;
import org.apache.logging.log4j.core.config.builder.api.AppenderComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.ComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilder;
import org.apache.logging.log4j.core.config.builder.api.ConfigurationBuilderFactory;
import org.apache.logging.log4j.core.config.builder.api.LayoutComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.LoggerComponentBuilder;
import org.apache.logging.log4j.core.config.builder.api.RootLoggerComponentBuilder;
import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration;
/**
* Several auxiliary static methods.
*
* @author Tomas Muller
* @version IFS 1.3 (Iterative Forward Search)
* Copyright (C) 2006 - 2014 Tomas Muller
* [email protected]
* http://muller.unitime.org
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 3 of the
* License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not see
* http://www.gnu.org/licenses/.
*/
public class ToolBox {
private static long sSeed = System.currentTimeMillis();
private static Random sRandom = new Random(sSeed);
/** Returns random number (int) from the set 0 .. limit - 1
* @param limit a limit
* @return a random number between 0 and limit - 1
**/
public static int random(int limit) {
return (int) (random() * limit);
}
/** Returns random element from the given set of elements
* @param set collection of objects
* @param some type
* @return randomly selected object
**/
public static E random(Collection set) {
switch (set == null ? 0 : set.size()) {
case 0:
return null;
case 1:
return set.iterator().next();
case 2:
Iterator i = set.iterator();
if (sRandom.nextBoolean()) i.next();
return i.next();
default:
int index = random(set.size());
if (set instanceof List>) return ((List)set).get(index);
Iterator it = set.iterator();
for (int j = 0; j < index; j++) it.next();
return it.next();
}
}
/**
* Returns a randomly generated subset of the given set
*
* @param set
* set
* @param part
* probability of selection of an element into the resultant
* subset
* @param some type
* @return randomly selected subset
*/
public static Collection subSet(Collection set, double part) {
return subSet(set, part, 1);
}
/** Swaps two elements in the list*/
private static void swap(List list, int first, int second) {
E o = list.get(first);
list.set(first, list.get(second));
list.set(second, o);
}
/**
* Returns a randomly generated subset of the given set
*
* @param set
* set
* @param part
* probability of selection of an element into the resultant
* subset
* @param minSize
* minimal size of the returned subset
* @param some type
* @return randomly selected subset
*/
public static Collection subSet(Collection set, double part, int minSize) {
if (set.size() <= minSize || part >= 1.0)
return set;
ArrayList subSet = new ArrayList(set);
int size = set.size();
int numberToSelect = Math.max(minSize, (int) (part * set.size()));
for (int idx = 0; idx < numberToSelect; idx++) {
swap(subSet, idx, idx + (int) (random() * (size - idx)));
}
return subSet.subList(0, numberToSelect);
}
/** Trim a string to have given length
* @param s a string to trim
* @param length a length to trim to
* @return trimmed and padded string of the given length
**/
public static String trim(String s, int length) {
if (s.length() > length)
return s.substring(0, length);
StringBuffer sb = new StringBuffer(s);
while (sb.length() < length)
sb.append(" ");
return sb.toString();
}
/** Multiline representation of a collection
* @param col a collection
* @param tab tab size
* @return string representation
**/
public static String col2string(Collection> col, int tab) {
StringBuffer tabsb = new StringBuffer();
while (tabsb.length() < 2 * tab)
tabsb.append(" ");
StringBuffer sb = new StringBuffer("[\n");
for (Iterator> i = col.iterator(); i.hasNext();) {
sb.append(tabsb + " " + i.next() + (i.hasNext() ? "," : "") + "\n");
}
sb.append(tabsb + "]");
return sb.toString();
}
/** Multiline representation of a dictionary
* @param dict a map
* @param tab tab size
* @param a key class
* @param a value class
* @return string representation
*/
public static String dict2string(Map dict, int tab) {
StringBuffer tabsb = new StringBuffer();
while (tabsb.length() < 2 * tab)
tabsb.append(" ");
StringBuffer sb = new StringBuffer("[\n");
TreeSet keys = new TreeSet(dict.keySet());
for (K key : keys) {
V value = dict.get(key);
sb.append(tabsb + " " + key + ": " + value + "\n");
}
sb.append(tabsb + "]");
return sb.toString();
}
/**
* Root mean square
*
* @param n
* number of tests
* @param x
* total value of all tests
* @param x2
* total value^2 of all tests
* @return root mean square
*/
public static double rms(int n, double x, double x2) {
double var = x2 / n;
double mean = x / n;
return Math.sqrt(Math.abs(var - mean * mean));
}
/** Merge source with target
* @param target target list
* @param source source list
* @param some object
**/
public static void merge(List target, Collection source) {
for (E o : source) {
if (!target.contains(o))
target.add(o);
}
}
/** Returns intersection of two collections
* @param source1 first collection
* @param source2 second collection
* @param some object
* @return intersection
*/
public static List intersect(Collection source1, Collection source2) {
List target = new ArrayList();
for (E o : source1) {
if (!source2.contains(o))
target.add(o);
}
return target;
}
/**
* Sets seeds for {@link ToolBox#getRandom()} and {@link ToolBox#random()}
* methods.
* @param seed random seed
*/
public static void setSeed(long seed) {
sSeed = seed;
sRandom = new Random(sSeed);
}
/** Gets current seed
* @return random seed
**/
public static long getSeed() {
return sSeed;
}
/** Gets random number generator
* @return random number generator
**/
public static Random getRandom() {
return sRandom;
}
/** Generates random double number
* @return random number
**/
public static double random() {
return sRandom.nextDouble();
}
/** Configurates log4j loging */
public static void configureLogging() {
if ("true".equalsIgnoreCase(System.getProperty("org.cpsolver.debug", "false"))) {
Configurator.setLevel("org.cpsolver", Level.DEBUG);
}
}
/**
* Setup log4j logging
*
* @param logFile log file
* @param debug true if debug messages should be logged (use -Ddebug=true to enable debug message)
*/
public static void setupLogging(File logFile, boolean debug) {
ConfigurationBuilder builder = ConfigurationBuilderFactory.newConfigurationBuilder();
AppenderComponentBuilder console = builder.newAppender("stdout", "Console");
console.addAttribute("target", "SYSTEM_OUT");
LayoutComponentBuilder consoleLayout = builder.newLayout("PatternLayout");
consoleLayout.addAttribute("pattern", "%-5p %c{2}: %m%n");
console.add(consoleLayout);
builder.add(console);
RootLoggerComponentBuilder root = builder.newRootLogger(Level.INFO);
root.add(builder.newAppenderRef("stdout"));
builder.add(root);
if (logFile != null) {
AppenderComponentBuilder file = builder.newAppender("log", "File");
file.addAttribute("fileName", logFile.getPath());
LayoutComponentBuilder filePattern = builder.newLayout("PatternLayout");
filePattern.addAttribute("pattern", "%d{dd-MMM-yy HH:mm:ss.SSS} [%t] %-5p %c{2}> %m%n");
file.add(filePattern);
builder.add(file);
LoggerComponentBuilder logger = builder.newLogger("org.cpsolver", debug ? Level.DEBUG : Level.INFO);
logger.add(builder.newAppenderRef("log"));
logger.addAttribute("additivity", true);
builder.add(logger);
}
Configurator.reconfigure(builder.build());
}
/**
* Configure log4j logging
*
* @param logDir
* output folder
* @param properties
* some other log4j properties
* @return name of the log file
*/
public static String configureLogging(String logDir, Properties properties) {
return configureLogging(logDir, properties, false);
}
/**
* Configure log4j logging
*
* @param logDir
* output folder
* @param properties
* some other log4j properties
* @param timeInFileName
* if true log file is named debug_yyyy-MM-dd_(HH.mm.ss).log, it
* is named debug.log otherwise
* @return name of the log file
*/
public static String configureLogging(String logDir, Properties properties, boolean timeInFileName) {
return configureLogging(logDir, properties, timeInFileName, true);
}
/**
* Configure log4j logging
*
* @param logDir
* output folder
* @param properties
* some other log4j properties
* @param timeInFileName
* if true log file is named debug_yyyy-MM-dd_(HH.mm.ss).log, it
* is named debug.log otherwise
* @param includeSystemOuts include system out and error in the log
* @return name of the log file
*/
public static String configureLogging(String logDir, Properties properties, boolean timeInFileName, boolean includeSystemOuts) {
(new File(logDir)).mkdirs();
ConfigurationBuilder builder = ConfigurationBuilderFactory.newConfigurationBuilder();
AppenderComponentBuilder console = builder.newAppender("stdout", "Console");
LayoutComponentBuilder consoleLayout = builder.newLayout("PatternLayout");
consoleLayout.addAttribute("pattern", "[%t] %m%n");
console.add(consoleLayout);
builder.add(console);
AppenderComponentBuilder file = null;
String fileName = null;
if (timeInFileName) {
file = builder.newAppender("log", "File");
String time = new java.text.SimpleDateFormat("yyyy-MM-dd_(HH.mm.ss)", java.util.Locale.US).format(new Date());
fileName = logDir + File.separator + "debug_" + time + ".log";
file.addAttribute("fileName", fileName);
} else {
file = builder.newAppender("log", "RollingFile");
fileName = logDir + File.separator + "debug.log";
file.addAttribute("fileName", fileName);
file.addAttribute("filePattern", logDir + File.separator + "debug-%d{MM-dd-yy}-%i.log.gz");
ComponentBuilder> triggeringPolicies = builder.newComponent("Policies")
.addComponent(builder.newComponent("CronTriggeringPolicy").addAttribute("schedule", "0 0 0 * * ?"))
.addComponent(builder.newComponent("SizeBasedTriggeringPolicy").addAttribute("size", "100M"));
file.addComponent(triggeringPolicies);
}
LayoutComponentBuilder filePattern = builder.newLayout("PatternLayout");
filePattern.addAttribute("pattern", "%d{dd-MMM-yy HH:mm:ss.SSS} [%t] %-5p %c{2}> %m%n");
file.add(filePattern);
builder.add(file);
RootLoggerComponentBuilder root = builder.newRootLogger("true".equals(System.getProperty("org.cpsolver.debug", "false")) ? Level.DEBUG : Level.INFO);
root.add(builder.newAppenderRef("log"));
builder.add(root);
LoggerComponentBuilder info = builder.newLogger("org.cpsolver", Level.INFO);
info.add(builder.newAppenderRef("stdout"));
info.addAttribute("additivity", true);
builder.add(info);
if (properties != null) {
for (Map.Entry
© 2015 - 2025 Weber Informatics LLC | Privacy Policy