Originally posted by: JorisK
Dear,
Thank you for your reply! I have implemented my model into cp optimizer (v12.5.1) via the java interface. Unfortunately, the results are poor (only very small instances can be solved), basically due to weak domain propagation.
Here I'll post some of the propagation issues I encounter using a highly simplified version of my model (java implementation attached). Hopefully you can tell me what I'm doing wrong.
Note: in my experiments, I have set: cp.setParameter(IloCP.IntParam.DefaultInferenceLevel, IloCP.ParameterValues.Extended);
First, a simplified version of my model:
================================
tuple Customer{
key int id; //unique identifier 1..n
int demand; //demand of customer
int release; //Time window during which customer can be serviced
int deadline;
int max_deliveries;
}
tuple Delivery{
Customer customer;
int id;
int duration; //Time required to perform delivery
int capacity; //Amount delivered
}
//Not all customers can be served, hence optional
dvar interval customers[c in Customers] in c.release ... c.deadline optional
forall(d in Deliveries)
dvar interval deliveries[d] in d.customer.release ... d.customer.deadline size d.duration optional
//The deliveries must be made in order, i.e first delivery 1, then delivery 2 etc:
//CONSTRAINTS 1a,b:
forall(d1,d2 in Deliveries: d1.id+1==d2.id){
endBeforeStart(delivery[d1],delivery[d2]);
presenceOf(delivery[d2])=>presenceOf(delivery[d1]);
}
//The customer is 'satisfied' iff sufficient deliveries are made such that its demand is fulfilled:
//Constraints 2:
forall(c in Customers){
precenceOf(customer[c]) ==
(sum(d in Deliveries: d.customer==c) (precenceOf(delivery[d])*d.capacity) >= c.demand);
}
//The objective simply maximizes the number of satisfied customers:
maximize sum(c in Customers)precenceOf(c)
================================
1. Instance 1
One customer with demand 10, time window [100,200]
Two deliveries with capacity 5, duration 10
Expected propagation:
a. Propagation on time windows of deliveries due to constraints 1a,b. Delivery d1 must start within the interval [100,180]. Delivery d2 must start within [110,190]
Result after invoking cp.propagate():
c1[0..1: 100..200 -- (0..100)0..100 --> 100..200]
d1[0..1: 100..190 -- (10)10 --> 110..200]
d2[0..1: 110..190 -- (10)10 --> 120..200]
Conclusion:
The starts of the intervals d1 and d2 have not been propagated well. To have a non-zero objective, interval c1 must be present. To have c1 present, both d1 and d2 must be present (constraint 2). Having d1 and d2 present implies (constraints 1a,1b):
d1[0..1: 100..180 -- (10)10 --> 110..190]
d2[0..1: 110..190 -- (10)10 --> 120..200]
Any suggestions how to tighten the propagation in this instance?
In my real problem, I have a heterogeneous fleet; hence the number of deliveries required to satisfy a customer is unknown and depend on the vehicles that perform the deliveries. However a simple lower bound is: Demand of customer divided by the largest vehicle, rounded up.
2. Instance 2
One customer with demand 10, time window [100,200]
Two deliveries with capacity 5, duration 60
Expected propagation:
a. To satisfy the customer, 2 deliveries must be made. However, since each delivery takes 60 time units, it is impossible to perform 2 deliveries within the time window of the customer. Hence, this customer cannot be satisfied.
Result after invoking cp.propagate():
c1[0]0 -- (0)0 --> 0]
d1[0..1: 100..140 -- (60)60 --> 160..200]
d2[0]0 -- (0)0 --> 0]
Conclusion:
Excellent propagation. CP correctly identified that customer c1 cannot be satisfied.
Question: so in this case, CP is capable of identifying the fact that customer c1 could not be scheduled. Imagine that I have 2 customers which can be scheduled individually, but not together (due to resource restrictions). These 'sets' of infeasible customers are highly valuable to me as I can use these sets to generate cuts in my Integer Programming model. Is there a smart way to produce these sets using CP? One approach would be to do the following:
for every combination of customers C:
forall(c in C)
c.setPresent()
forall(c not in C)
c.setOptional();
Next you can propagate the model again and see whether the result is infeasible. This approach seems however rather expensive, especially since you would have to run this approach for every combination of customers? Is there a smarter approach?
br,
Joris
#ConstraintProgramming-General#DecisionOptimization