Skip to content

Commit

Permalink
remove assumption of integer objective, fixes coin-or#23
Browse files Browse the repository at this point in the history
  • Loading branch information
rowtricker committed Nov 25, 2016
1 parent 103b7ec commit 297e7f9
Show file tree
Hide file tree
Showing 15 changed files with 56 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public abstract class AbstractBranchAndPrice<T extends ModelInterface,
protected final OptimizationSense optimizationSenseMaster;

/** Stores the objective of the best (integer) solution **/
protected int objectiveIncumbentSolution;
protected double objectiveIncumbentSolution;
/**
* List containing the columns corresponding to the best integer solution (empty list when no
* feasible solution has been found)
Expand Down Expand Up @@ -401,7 +401,7 @@ protected int getUniqueNodeID()
*
* @return the objective of the best integer solution found during the Branch-and-Price search
*/
public int getObjective()
public double getObjective()
{
return this.objectiveIncumbentSolution;
}
Expand Down Expand Up @@ -596,10 +596,17 @@ protected List<U> generateArtificialSolution()
*/
protected boolean nodeCanBePruned(BAPNode<T, U> node)
{
return (optimizationSenseMaster == OptimizationSense.MINIMIZE
&& Math.ceil(node.bound - config.PRECISION) >= upperBoundOnObjective
|| optimizationSenseMaster == OptimizationSense.MAXIMIZE
&& Math.floor(node.bound + config.PRECISION) <= lowerBoundOnObjective);
if (config.INTEGER_OBJECTIVE) {
return (optimizationSenseMaster == OptimizationSense.MINIMIZE
&& Math.ceil(node.bound - config.PRECISION) >= upperBoundOnObjective
|| optimizationSenseMaster == OptimizationSense.MAXIMIZE
&& Math.floor(node.bound + config.PRECISION) <= lowerBoundOnObjective);
} else {
return optimizationSenseMaster == OptimizationSense.MINIMIZE
&& node.bound >= upperBoundOnObjective
|| optimizationSenseMaster == OptimizationSense.MAXIMIZE
&& node.bound <= lowerBoundOnObjective;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class FinishMasterEvent
* Cutoff value: Column Generation is terminated when the bound on the Master Objective is worse
* than the cutoff value
**/
public final int cutoffValue;
public final double cutoffValue;
/** Best available bound on the master objective **/
public final double boundOnMasterObjective;

Expand All @@ -49,7 +49,7 @@ public class FinishMasterEvent
* @param boundOnMasterObjective best available bound on master problem
*/
public FinishMasterEvent(
Object source, int columnGenerationIteration, double objective, int cutoffValue,
Object source, int columnGenerationIteration, double objective, double cutoffValue,
double boundOnMasterObjective)
{
super(source);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public class FinishPricingEvent<T extends ModelInterface, U extends AbstractColu
* Cutoff value: Column Generation is terminated when the bound on the Master Objective is worse
* than the cutoff value
**/
public final int cutoffValue;
public final double cutoffValue;
/** Best available bound on the master objective **/
public final double boundOnMasterObjective;

Expand All @@ -60,7 +60,7 @@ public class FinishPricingEvent<T extends ModelInterface, U extends AbstractColu
*/
public FinishPricingEvent(
Object source, int columnGenerationIteration, List<U> columns, double objective,
int cutoffValue, double boundOnMasterObjective)
double cutoffValue, double boundOnMasterObjective)
{
super(source);
this.columnGenerationIteration = columnGenerationIteration;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class ProcessingNextNodeEvent<T extends ModelInterface, U extends Abstrac
/** Number of nodes currently waiting in the queue **/
public final int nodesInQueue;
/** Best integer solution obtained thus far **/
public final int objectiveIncumbentSolution;
public final double objectiveIncumbentSolution;

/**
* Creates a new ProcessingNextNodeEvent
Expand All @@ -47,7 +47,7 @@ public class ProcessingNextNodeEvent<T extends ModelInterface, U extends Abstrac
* @param objectiveIncumbentSolution Best integer solution found thus far
*/
public ProcessingNextNodeEvent(
Object source, BAPNode<T,U> node, int nodesInQueue, int objectiveIncumbentSolution)
Object source, BAPNode<T,U> node, int nodesInQueue, double objectiveIncumbentSolution)
{
super(source);
this.node = node;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class PruneNodeEvent<T extends ModelInterface, U extends AbstractColumn<T
/** Bound on this node **/
public final double nodeBound;
/** Best integer solution discovered so far **/
public final int bestIntegerSolution;
public final double bestIntegerSolution;

/**
* Creates a new PruneNodeEvent
Expand All @@ -46,7 +46,7 @@ public class PruneNodeEvent<T extends ModelInterface, U extends AbstractColumn<T
* @param nodeBound Bound on the node
* @param bestIntegerSolution Best integer solution discovered thus far
*/
public PruneNodeEvent(Object source, BAPNode<T, U> node, double nodeBound, int bestIntegerSolution)
public PruneNodeEvent(Object source, BAPNode<T, U> node, double nodeBound, double bestIntegerSolution)
{
super(source);
this.node = node;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class StartEvent
* Best available integer solution at the start of the Branch-and-Price or Column generation
* procedure
**/
public final int objectiveIncumbentSolution;
public final double objectiveIncumbentSolution;

/**
* Creates a new StartEvent
Expand All @@ -43,7 +43,7 @@ public class StartEvent
* @param objectiveIncumbentSolution Best available integer solution at the start of the
* Branch-and-Price or Column generation procedure
*/
public StartEvent(Object source, String instanceName, int objectiveIncumbentSolution)
public StartEvent(Object source, String instanceName, double objectiveIncumbentSolution)
{
super(source);
this.instanceName = instanceName;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ public class ColGen<T extends ModelInterface, U extends AbstractColumn<T, V>,
* is a maximization problem, the Colgen procedure is terminated if
* {@code floor(boundOnMasterObjective) <= cutoffValue}.
**/
protected int cutoffValue;
protected double cutoffValue;
/**
* Bound on the best attainable objective value from the master problem. Assuming that the
* master is a minimization problem, the Colgen procedure is terminated if
Expand Down Expand Up @@ -114,7 +114,7 @@ public class ColGen<T extends ModelInterface, U extends AbstractColumn<T, V>,
public ColGen(
T dataModel, AbstractMaster<T, U, V, ? extends MasterData<T, U, V, ?>> master, List<V> pricingProblems,
List<Class<? extends AbstractPricingProblemSolver<T, U, V>>> solvers, List<U> initSolution,
int cutoffValue, double boundOnMasterObjective)
double cutoffValue, double boundOnMasterObjective)
{
this.dataModel = dataModel;
this.master = master;
Expand Down Expand Up @@ -161,7 +161,7 @@ public ColGen(
public ColGen(
T dataModel, AbstractMaster<T, U, V, ? extends MasterData<T, U, V, ?>> master, V pricingProblem,
List<Class<? extends AbstractPricingProblemSolver<T, U, V>>> solvers, List<U> initSolution,
int cutoffValue, double boundOnMasterObjective)
double cutoffValue, double boundOnMasterObjective)
{
this(
dataModel, master, Collections.singletonList(pricingProblem), solvers, initSolution,
Expand All @@ -188,7 +188,7 @@ public ColGen(
public ColGen(
T dataModel, AbstractMaster<T, U, V, ? extends MasterData<T, U, V, ?>> master, List<V> pricingProblems,
List<Class<? extends AbstractPricingProblemSolver<T, U, V>>> solvers,
PricingProblemManager<T, U, V> pricingProblemManager, List<U> initSolution, int cutoffValue,
PricingProblemManager<T, U, V> pricingProblemManager, List<U> initSolution, double cutoffValue,
double boundOnMasterObjective)
{
this.dataModel = dataModel;
Expand Down Expand Up @@ -519,10 +519,17 @@ public List<AbstractInequality> getCuts()
*/
protected boolean boundOnMasterExceedsCutoffValue()
{
if (optimizationSenseMaster == OptimizationSense.MINIMIZE)
return Math.ceil(boundOnMasterObjective - config.PRECISION) >= cutoffValue;
else
return Math.floor(boundOnMasterObjective + config.PRECISION) <= cutoffValue;
if (config.INTEGER_OBJECTIVE) {
if (optimizationSenseMaster == OptimizationSense.MINIMIZE)
return Math.ceil(boundOnMasterObjective - config.PRECISION) >= cutoffValue;
else
return Math.floor(boundOnMasterObjective + config.PRECISION) <= cutoffValue;
} else {
if (optimizationSenseMaster == OptimizationSense.MINIMIZE)
return boundOnMasterObjective >= cutoffValue;
else
return boundOnMasterObjective <= cutoffValue;
}
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class SimpleBAPLogger<T extends ModelInterface, U extends AbstractColumn<
/** Parent node ID, -1 if root node **/
protected int parentNodeID;
/** Best integer solution **/
protected int objectiveIncumbentSolution;
protected double objectiveIncumbentSolution;
/** Bound on the BAP node **/
protected double nodeBound;
/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ public class SimpleCGLogger<T extends ModelInterface, U extends AbstractColumn<T
/** Objective of master problem at the end of iteration it **/
protected double objective;
/** Cutoff value **/
protected int cutoffValue;
protected double cutoffValue;
/** Bound on the objective at the end of iteration it **/
protected double boundOnMasterObjective;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public class SimpleDebugger<T extends ModelInterface, U extends AbstractColumn<T
/** Name of the instance being solved **/
protected String instanceName;
/** Best integer solution obtained thus far **/
protected int bestIntegerSolution;
protected double bestIntegerSolution;

/**
* Creates a debugger for Column Generation instances
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ protected Configuration()
CUTSENABLED = true;
EXPORT_MODEL = false;
EXPORT_MASTER_DIR = "./output/masterLP/";
INTEGER_OBJECTIVE = true;

// Cut handling
QUICK_RETURN_AFTER_CUTS_FOUND = true;
Expand Down Expand Up @@ -70,6 +71,8 @@ protected Configuration(Properties properties)
? Boolean.valueOf(properties.getProperty("EXPORT_MODEL")) : false);
EXPORT_MASTER_DIR = (properties.containsKey("EXPORT_MODEL_DIR")
? properties.getProperty("EXPORT_MODEL_DIR") : "./output/masterLP/");
INTEGER_OBJECTIVE = (properties.containsKey("INTEGER_OBJECTIVE")
? Boolean.valueOf(properties.getProperty("INTEGER_OBJECTIVE")): true);

// Cut handling
QUICK_RETURN_AFTER_CUTS_FOUND = (properties.containsKey("QUICK_RETURN_AFTER_CUTS_FOUND")
Expand Down Expand Up @@ -122,6 +125,8 @@ public static void readFromFile(Properties properties)
public final boolean EXPORT_MODEL;
/** Define export directory for master models. Default: ./output/masterLP/ **/
public final String EXPORT_MASTER_DIR;
/** Defines if an integer solution has an integer objective. Default = true */
public final boolean INTEGER_OBJECTIVE;

/*
* Cut handling
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,14 +92,14 @@ public void testBAPFrameworkThroughTSP()
if (inputStream == null)
Assert.fail("Cannot find problem instance!");
TSP tsp = new TSP(inputStream);
int solution = this.solveTSPInstance(tsp);
double solution = this.solveTSPInstance(tsp);
System.out.println("Solution for : " + instance + " is: " + solution);
Assert.assertEquals(solution, instances.get(instance).intValue());
Assert.assertEquals(solution, instances.get(instance).intValue(), 0.000001);
inputStream.close();
}
}

private int solveTSPInstance(TSP tsp)
private double solveTSPInstance(TSP tsp)
{
if (tsp.N % 2 == 1)
throw new RuntimeException(
Expand Down Expand Up @@ -146,7 +146,7 @@ private int solveTSPInstance(TSP tsp)
bap.runBranchAndPrice(System.currentTimeMillis() + 8000000L);

// Get the solution
int solution = -1;
double solution = -1;
if (bap.hasSolution()) {
assert (bap.isOptimal());
solution = bap.getObjective();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public final class Matching
**/
public final int[] succ;
/** Weighted cost of the matching **/
public final int cost;
public final double cost;

/**
* Creates a new column (matching)
Expand All @@ -51,7 +51,7 @@ public final class Matching
*/
public Matching(
String creator, boolean isVolatile, PricingProblemByColor associatedPricingProblem,
Set<DefaultWeightedEdge> edges, int[] succ, int cost)
Set<DefaultWeightedEdge> edges, int[] succ, double cost)
{
super(associatedPricingProblem, isVolatile, creator);
this.edges = edges;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public final class IndependentSet
/** Vertices in the independent set **/
public final Set<Integer> vertices;
/** Cost of this column in the objective of the Master Problem **/
public final int cost;
public final double cost;

/**
* Constructs a new column
Expand All @@ -43,7 +43,7 @@ public final class IndependentSet
*/
public IndependentSet(
ChromaticNumberPricingProblem associatedPricingProblem, boolean isVolatile,
String creator, Set<Integer> vertices, int cost)
String creator, Set<Integer> vertices, double cost)
{
super(associatedPricingProblem, isVolatile, creator);
this.vertices = vertices;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ public final class Matching
**/
public final int[] succ;
/** Weighted cost of the matching **/
public final int cost;
public final double cost;

/**
* Creates a new column (matching)
Expand All @@ -51,7 +51,7 @@ public final class Matching
*/
public Matching(
String creator, boolean isVolatile, PricingProblemByColor associatedPricingProblem,
Set<DefaultWeightedEdge> edges, int[] succ, int cost)
Set<DefaultWeightedEdge> edges, int[] succ, double cost)
{
super(associatedPricingProblem, isVolatile, creator);
this.edges = edges;
Expand Down

0 comments on commit 297e7f9

Please sign in to comment.