mirror of
https://github.com/graphhopper/jsprit.git
synced 2020-01-24 07:45:05 +01:00
Merge branch 'master' into prio-improvement
This commit is contained in:
commit
5fa1cea6af
4 changed files with 196 additions and 117 deletions
|
|
@ -29,121 +29,9 @@ import java.util.*;
|
|||
*/
|
||||
public class UnassignedJobReasonTracker implements JobUnassignedListener {
|
||||
|
||||
Map<String, Frequency> reasons = new HashMap<>();
|
||||
|
||||
Map<Integer, String> codesToReason = new HashMap<>();
|
||||
|
||||
Map<String, Integer> failedConstraintNamesToCode = new HashMap<>();
|
||||
|
||||
Set<String> constraintsToBeIgnored = new HashSet<>();
|
||||
|
||||
public UnassignedJobReasonTracker() {
|
||||
codesToReason.put(1, "cannot serve required skill");
|
||||
codesToReason.put(2, "cannot be visited within time window");
|
||||
codesToReason.put(3, "does not fit into any vehicle due to capacity");
|
||||
codesToReason.put(4, "cannot be assigned due to max distance constraint of vehicle");
|
||||
|
||||
failedConstraintNamesToCode.put("HardSkillConstraint", 1);
|
||||
failedConstraintNamesToCode.put("VehicleDependentTimeWindowConstraints", 2);
|
||||
failedConstraintNamesToCode.put("ServiceLoadRouteLevelConstraint", 3);
|
||||
failedConstraintNamesToCode.put("PickupAndDeliverShipmentLoadActivityLevelConstraint", 3);
|
||||
failedConstraintNamesToCode.put("ServiceLoadActivityLevelConstraint", 3);
|
||||
failedConstraintNamesToCode.put("MaxDistanceConstraint", 4);
|
||||
}
|
||||
|
||||
public void ignore(String simpleNameOfConstraint) {
|
||||
constraintsToBeIgnored.add(simpleNameOfConstraint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informJobUnassigned(Job unassigned, Collection<String> failedConstraintNames) {
|
||||
if (!this.reasons.containsKey(unassigned.getId())) {
|
||||
this.reasons.put(unassigned.getId(), new Frequency());
|
||||
}
|
||||
for (String r : failedConstraintNames) {
|
||||
if (constraintsToBeIgnored.contains(r)) continue;
|
||||
this.reasons.get(unassigned.getId()).addValue(r);
|
||||
}
|
||||
}
|
||||
|
||||
public void put(String simpleNameOfFailedConstraint, int code, String reason) {
|
||||
if (code <= 20)
|
||||
throw new IllegalArgumentException("first 20 codes are reserved internally. choose a code > 20");
|
||||
codesToReason.put(code, reason);
|
||||
if (failedConstraintNamesToCode.containsKey(simpleNameOfFailedConstraint)) {
|
||||
throw new IllegalArgumentException(simpleNameOfFailedConstraint + " already assigned to code and reason");
|
||||
} else failedConstraintNamesToCode.put(simpleNameOfFailedConstraint, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* For each job id, it returns frequency distribution of failed constraints (simple name of constraint) in an unmodifiable map.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Map<String, Frequency> getReasons() {
|
||||
return Collections.unmodifiableMap(reasons);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable map of codes and reason pairs.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Map<Integer, String> getCodesToReason() {
|
||||
return Collections.unmodifiableMap(codesToReason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable map of constraint names (simple name of constraint) and reason code pairs.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Map<String, Integer> getFailedConstraintNamesToCode() {
|
||||
return Collections.unmodifiableMap(failedConstraintNamesToCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the most likely reason code i.e. the reason (failed constraint) being observed most often.
|
||||
*
|
||||
* 1 --> "cannot serve required skill
|
||||
* 2 --> "cannot be visited within time window"
|
||||
* 3 --> "does not fit into any vehicle due to capacity"
|
||||
* 4 --> "cannot be assigned due to max distance constraint of vehicle"
|
||||
*
|
||||
* @param jobId
|
||||
* @return
|
||||
*/
|
||||
public int getMostLikelyReasonCode(String jobId) {
|
||||
if (!this.reasons.containsKey(jobId)) return -1;
|
||||
Frequency reasons = this.reasons.get(jobId);
|
||||
String mostLikelyReason = getMostLikely(reasons);
|
||||
return toCode(mostLikelyReason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the most likely reason i.e. the reason (failed constraint) being observed most often.
|
||||
*
|
||||
* @param jobId
|
||||
* @return
|
||||
*/
|
||||
public String getMostLikelyReason(String jobId) {
|
||||
if (!this.reasons.containsKey(jobId)) return "no reason found";
|
||||
Frequency reasons = this.reasons.get(jobId);
|
||||
String mostLikelyReason = getMostLikely(reasons);
|
||||
int code = toCode(mostLikelyReason);
|
||||
if (code == -1) return mostLikelyReason;
|
||||
else return codesToReason.get(code);
|
||||
}
|
||||
|
||||
private int toCode(String mostLikelyReason) {
|
||||
if (failedConstraintNamesToCode.containsKey(mostLikelyReason))
|
||||
return failedConstraintNamesToCode.get(mostLikelyReason);
|
||||
else return -1;
|
||||
}
|
||||
|
||||
private String getMostLikely(Frequency reasons) {
|
||||
if (reasons == null) return "no reason found";
|
||||
Iterator<Map.Entry<Comparable<?>, Long>> entryIterator = reasons.entrySetIterator();
|
||||
public static String getMostLikelyFailedConstraintName(Frequency failedConstraintNamesFrequency) {
|
||||
if (failedConstraintNamesFrequency == null) return "no reason found";
|
||||
Iterator<Map.Entry<Comparable<?>, Long>> entryIterator = failedConstraintNamesFrequency.entrySetIterator();
|
||||
int maxCount = 0;
|
||||
String mostLikely = null;
|
||||
while (entryIterator.hasNext()) {
|
||||
|
|
@ -156,5 +44,138 @@ public class UnassignedJobReasonTracker implements JobUnassignedListener {
|
|||
return mostLikely;
|
||||
}
|
||||
|
||||
Map<String, Frequency> failedConstraintNamesFrequencyMapping = new HashMap<>();
|
||||
|
||||
Map<Integer, String> codesToHumanReadableReason = new HashMap<>();
|
||||
|
||||
Map<String, Integer> failedConstraintNamesToCode = new HashMap<>();
|
||||
|
||||
Set<String> failedConstraintNamesToBeIgnored = new HashSet<>();
|
||||
|
||||
public UnassignedJobReasonTracker() {
|
||||
codesToHumanReadableReason.put(1, "cannot serve required skill");
|
||||
codesToHumanReadableReason.put(2, "cannot be visited within time window");
|
||||
codesToHumanReadableReason.put(3, "does not fit into any vehicle due to capacity");
|
||||
codesToHumanReadableReason.put(4, "cannot be assigned due to max distance constraint of vehicle");
|
||||
|
||||
failedConstraintNamesToCode.put("HardSkillConstraint", 1);
|
||||
failedConstraintNamesToCode.put("VehicleDependentTimeWindowConstraints", 2);
|
||||
failedConstraintNamesToCode.put("ServiceLoadRouteLevelConstraint", 3);
|
||||
failedConstraintNamesToCode.put("PickupAndDeliverShipmentLoadActivityLevelConstraint", 3);
|
||||
failedConstraintNamesToCode.put("ServiceLoadActivityLevelConstraint", 3);
|
||||
failedConstraintNamesToCode.put("MaxDistanceConstraint", 4);
|
||||
}
|
||||
|
||||
public void ignore(String simpleNameOfConstraint) {
|
||||
failedConstraintNamesToBeIgnored.add(simpleNameOfConstraint);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void informJobUnassigned(Job unassigned, Collection<String> failedConstraintNames) {
|
||||
if (!this.failedConstraintNamesFrequencyMapping.containsKey(unassigned.getId())) {
|
||||
this.failedConstraintNamesFrequencyMapping.put(unassigned.getId(), new Frequency());
|
||||
}
|
||||
for (String r : failedConstraintNames) {
|
||||
if (failedConstraintNamesToBeIgnored.contains(r)) continue;
|
||||
this.failedConstraintNamesFrequencyMapping.get(unassigned.getId()).addValue(r);
|
||||
}
|
||||
}
|
||||
|
||||
public void put(String simpleNameOfFailedConstraint, int code, String reason) {
|
||||
if (code <= 20)
|
||||
throw new IllegalArgumentException("first 20 codes are reserved internally. choose a code > 20");
|
||||
codesToHumanReadableReason.put(code, reason);
|
||||
if (failedConstraintNamesToCode.containsKey(simpleNameOfFailedConstraint)) {
|
||||
throw new IllegalArgumentException(simpleNameOfFailedConstraint + " already assigned to code and reason");
|
||||
} else failedConstraintNamesToCode.put(simpleNameOfFailedConstraint, code);
|
||||
}
|
||||
|
||||
/**
|
||||
* For each job id, it returns frequency distribution of failed constraints (simple name of constraint) in an unmodifiable map.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Deprecated
|
||||
public Map<String, Frequency> getReasons() {
|
||||
return Collections.unmodifiableMap(failedConstraintNamesFrequencyMapping);
|
||||
}
|
||||
|
||||
/**
|
||||
* For each job id, it returns frequency distribution of failed constraints (simple name of constraint) in an unmodifiable map.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Map<String, Frequency> getFailedConstraintNamesFrequencyMapping() {
|
||||
return Collections.unmodifiableMap(failedConstraintNamesFrequencyMapping);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable map of codes and reason pairs.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Map<Integer, String> getCodesToReason() {
|
||||
return Collections.unmodifiableMap(codesToHumanReadableReason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an unmodifiable map of constraint names (simple name of constraint) and reason code pairs.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public Map<String, Integer> getFailedConstraintNamesToCode() {
|
||||
return Collections.unmodifiableMap(failedConstraintNamesToCode);
|
||||
}
|
||||
|
||||
public int getCode(String failedConstraintName) {
|
||||
return toCode(failedConstraintName);
|
||||
}
|
||||
|
||||
public String getHumanReadableReason(int code) {
|
||||
return getCodesToReason().get(code);
|
||||
}
|
||||
|
||||
public String getHumanReadableReason(String failedConstraintName) {
|
||||
return getCodesToReason().get(getCode(failedConstraintName));
|
||||
}
|
||||
/**
|
||||
* Returns the most likely reason code i.e. the reason (failed constraint) being observed most often.
|
||||
*
|
||||
* 1 --> "cannot serve required skill
|
||||
* 2 --> "cannot be visited within time window"
|
||||
* 3 --> "does not fit into any vehicle due to capacity"
|
||||
* 4 --> "cannot be assigned due to max distance constraint of vehicle"
|
||||
*
|
||||
* @param jobId
|
||||
* @return
|
||||
*/
|
||||
public int getMostLikelyReasonCode(String jobId) {
|
||||
if (!this.failedConstraintNamesFrequencyMapping.containsKey(jobId)) return -1;
|
||||
Frequency reasons = this.failedConstraintNamesFrequencyMapping.get(jobId);
|
||||
String mostLikelyReason = getMostLikelyFailedConstraintName(reasons);
|
||||
return toCode(mostLikelyReason);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the most likely reason i.e. the reason (failed constraint) being observed most often.
|
||||
*
|
||||
* @param jobId
|
||||
* @return
|
||||
*/
|
||||
public String getMostLikelyReason(String jobId) {
|
||||
if (!this.failedConstraintNamesFrequencyMapping.containsKey(jobId)) return "no reason found";
|
||||
Frequency reasons = this.failedConstraintNamesFrequencyMapping.get(jobId);
|
||||
String mostLikelyReason = getMostLikelyFailedConstraintName(reasons);
|
||||
int code = toCode(mostLikelyReason);
|
||||
if (code == -1) return mostLikelyReason;
|
||||
else return codesToHumanReadableReason.get(code);
|
||||
}
|
||||
|
||||
private int toCode(String mostLikelyReason) {
|
||||
if (failedConstraintNamesToCode.containsKey(mostLikelyReason))
|
||||
return failedConstraintNamesToCode.get(mostLikelyReason);
|
||||
else return -1;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue