How can I override the default objective function?

1,235 views
Skip to first unread message

Stefan Schröder

unread,
Sep 26, 2014, 2:38:57 AM9/26/14
to jsprit-ma...@googlegroups.com
For various reasons one requires to specify a custom objective function. How can I override the default one?

Stefan Schröder

unread,
Sep 26, 2014, 3:02:40 AM9/26/14
to jsprit-ma...@googlegroups.com
First, all objective functions are implementations of jsprit.core.problem.solution.SolutionCostCalculator. Since it is a cost function, it is always minimized. If one wants to maximize profits, this function can be easily inverted, i.e. negative costs are actually profits.

Second, the default objective function looks like the following:

1 new SolutionCostCalculator() {
2
3            @Override
4            public double getCosts(VehicleRoutingProblemSolution solution) {
5                double c = 0.0;
6                for(VehicleRoute r : solution.getRoutes()){
7                    c += stateManager.getRouteState(r, InternalStates.COSTS, Double.class);
8                    c += r.getVehicle().getType().getVehicleCostParams().fix;
9                }
10                c += solution.getUnassignedJobs().size() * c * .1;
11                return c;
12            }
13
14 });

It loops through all routes in the solution (line 6-9) and sums up variable transport costs (line 7) and fixed costs (line 8). Variable transport costs are retrieved from an internal state calculated in the course of inserting customers. Since the solution is evaluated just after the whole insertion process of an iteration ends, the internal costs state is related to the solution to be evaluated. Note that if you want to sum up costs long after the algorithm terminates (as a post process), you need to replace line 7 by your own variable transport cost calulator (just loop through all activities and sum up the costs you get by your VehicleRoutingTransportCosts) since states do not live anymore.
Line 10 penalyzes unassigned jobs (which is new since v1.4). I chose to penalyze each unassigned job with 10 percent of the total transport costs (which might not be the right choice for your case, but which I found reasonable for all the tests I did).

Third, you activate your own function much like it illustrated here:

VehicleRoutingAlgorithmBuilder vraBuilder = new VehicleRoutingAlgorithmBuilder(vrp,"input/algorithm.xml");
vraBuilder
.addDefaultCostCalculators();
vraBuilder
.addCoreConstraints();
final StateManager stateManager = new StateManager(vrp);
ConstraintManager constraintManager = new ConstraintManager(vrp,stateManager);
vraBuilder
.setStateAndConstraintManager(stateManager,constraintManager);
vraBuilder
.setObjectiveFunction(new SolutionCostCalculator() {

       
@Override
       
public double getCosts(VehicleRoutingProblemSolution solution) {
           
double c = 0.0;
           
for(VehicleRoute r : solution.getRoutes()){
                c
+= stateManager.getRouteState(r, InternalStates.COSTS, Double.class);
                c
+= r.getVehicle().getType().getVehicleCostParams().fix;
           
}
            c
+= solution.getUnassignedJobs().size() * c * .2;
           
return c;
       
}

});
VehicleRoutingAlgorithm vra = vraBuilder.build();

And of course, you can always use and set a new class (instead of the inner one) that implements jsprit.core.problem.solution.SolutionCostCalculator.

Yang Yang

unread,
Nov 19, 2014, 5:03:33 PM11/19/14
to jsprit-ma...@googlegroups.com
the sample code here uses 

VRABuilder.setObjectiveFunction()

but this is still not there.  I took a lazy quick and dirty approach and added the ObjectiveFunction customization feature in :



but still , if we want to give different "gains" to each customer/node, we need to modify the Service class

Stefan Schröder

unread,
Nov 19, 2014, 5:35:08 PM11/19/14
to jsprit-ma...@googlegroups.com
Look at this to set your own objFunction:
https://github.com/jsprit/playground/blob/master/src/stackoverflow/Stackoverflow_RelatedJobs_13_and_21_inSameRoute.java

@service class: Each service has a unique id which you can use to add an arbitrary number of additional information. You can just define a profit map for your services and retrieve the profits from it if you need it. You do not even need the id, you can just put the service into your map like this: Map<Service,Double> profitMap ...

Yang Yang

unread,
Nov 19, 2014, 5:38:07 PM11/19/14
to jsprit-ma...@googlegroups.com
I modified the CostMatrix example. originally it has starting node 0, and 3 other services to visit: 1 2 3.

I made all access distance and time to 3 to be prohibitively large https://github.com/yangyangyyy/jsprit/commit/5f8f35b5ec5b2f77d0f40b632ca3ffcc7bdb46ff

but the resulting algorithm still fails to remove 3 from the routing solution: it includes 3 and gives a solution with cost of 1.xE6
while if u ignore 3, the cost is only 102.x

Yang Yang

unread,
Nov 19, 2014, 5:39:32 PM11/19/14
to jsprit-ma...@googlegroups.com
thanks Stefan !  could u please address my next question too? (regarding the CostMatrix example)

Heerad Farkhoor

unread,
Nov 19, 2014, 6:02:49 PM11/19/14
to jsprit-ma...@googlegroups.com
I think Yang's issue might have a similar underlying cause to the one I described here where I attempt to implement soft time windows:

https://groups.google.com/forum/#!topic/jsprit-mailing-list/osxd6LM8KPU
--
You received this message because you are subscribed to the Google Groups "jsprit-mailing-list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jsprit-mailing-...@googlegroups.com.
To post to this group, send email to jsprit-ma...@googlegroups.com.
Visit this group at http://groups.google.com/group/jsprit-mailing-list.
For more options, visit https://groups.google.com/d/optout.

Yang Yang

unread,
Nov 25, 2014, 7:35:00 PM11/25/14
to jsprit-ma...@googlegroups.com
OK..... I finally figured out . thanks to Stefan for your responses on this board !.


I slightly modified the "AdditionalCostMatrixExample"

now it ignores node3.


I'll write a write-up (maybe in addition to https://github.com/jsprit/jsprit/wiki/Walkthrough---Constraints   to describe the code structure of jsprit, from the fresh perspective of
a new developer, hopefully that will be helpful to other people too.

Yang


On Wednesday, November 19, 2014 3:02:49 PM UTC-8, hfarkhoor24 wrote:
I think Yang's issue might have a similar underlying cause to the one I described here where I attempt to implement soft time windows:

https://groups.google.com/forum/#!topic/jsprit-mailing-list/osxd6LM8KPU
On Wed Nov 19 2014 at 2:39:33 PM Yang Yang <teddy...@gmail.com> wrote:
thanks Stefan !  could u please address my next question too? (regarding the CostMatrix example)


On Wednesday, November 19, 2014 2:35:08 PM UTC-8, Stefan Schröder wrote:
Look at this to set your own objFunction:
https://github.com/jsprit/playground/blob/master/src/stackoverflow/Stackoverflow_RelatedJobs_13_and_21_inSameRoute.java

@service class: Each service has a unique id which you can use to add an arbitrary number of additional information. You can just define a profit map for your services and retrieve the profits from it if you need it. You do not even need the id, you can just put the service into your map like this: Map<Service,Double> profitMap ...

--
You received this message because you are subscribed to the Google Groups "jsprit-mailing-list" group.
To unsubscribe from this group and stop receiving emails from it, send an email to jsprit-mailing-list+unsub...@googlegroups.com.
Reply all
Reply to author
Forward
0 new messages