diff --git a/.travis.settings.xml b/.travis.settings.xml new file mode 100644 index 00000000..fd37913e --- /dev/null +++ b/.travis.settings.xml @@ -0,0 +1,27 @@ + + + + + + packagecloud-graphhopper + ${env.PACKAGECLOUD_TOKEN} + + + diff --git a/.travis.yml b/.travis.yml index 2406cbd9..40e6f9fc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,3 +4,20 @@ jdk: - oraclejdk7 - oraclejdk8 +deploy: + provider: script + script: "cp .travis.settings.xml $HOME/.m2/settings.xml && mvn deploy" + skip_cleanup: true + on: + tags: true + +# do not install anything instead return true via unix command true +install: true +script: mvn clean test +notifications: + email: + - github@graphhopper.com + +# enable container-based stack +sudo: false + diff --git a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/util/UnassignedJobReasonTracker.java b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/util/UnassignedJobReasonTracker.java index 0a999953..03bf7d1d 100644 --- a/jsprit-core/src/main/java/com/graphhopper/jsprit/core/util/UnassignedJobReasonTracker.java +++ b/jsprit-core/src/main/java/com/graphhopper/jsprit/core/util/UnassignedJobReasonTracker.java @@ -29,121 +29,9 @@ import java.util.*; */ public class UnassignedJobReasonTracker implements JobUnassignedListener { - Map reasons = new HashMap<>(); - - Map codesToReason = new HashMap<>(); - - Map failedConstraintNamesToCode = new HashMap<>(); - - Set 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 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 getReasons() { - return Collections.unmodifiableMap(reasons); - } - - /** - * Returns an unmodifiable map of codes and reason pairs. - * - * @return - */ - public Map getCodesToReason() { - return Collections.unmodifiableMap(codesToReason); - } - - /** - * Returns an unmodifiable map of constraint names (simple name of constraint) and reason code pairs. - * - * @return - */ - public Map 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, Long>> entryIterator = reasons.entrySetIterator(); + public static String getMostLikelyFailedConstraintName(Frequency failedConstraintNamesFrequency) { + if (failedConstraintNamesFrequency == null) return "no reason found"; + Iterator, 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 failedConstraintNamesFrequencyMapping = new HashMap<>(); + + Map codesToHumanReadableReason = new HashMap<>(); + + Map failedConstraintNamesToCode = new HashMap<>(); + + Set 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 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 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 getFailedConstraintNamesFrequencyMapping() { + return Collections.unmodifiableMap(failedConstraintNamesFrequencyMapping); + } + + /** + * Returns an unmodifiable map of codes and reason pairs. + * + * @return + */ + public Map getCodesToReason() { + return Collections.unmodifiableMap(codesToHumanReadableReason); + } + + /** + * Returns an unmodifiable map of constraint names (simple name of constraint) and reason code pairs. + * + * @return + */ + public Map 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; + } + } diff --git a/pom.xml b/pom.xml index 2a1147c0..7b669fe8 100644 --- a/pom.xml +++ b/pom.xml @@ -56,6 +56,7 @@ HEAD + github https://github.com/graphhopper/jsprit/issues @@ -81,6 +82,15 @@ + + + + io.packagecloud.maven.wagon + maven-packagecloud-wagon + 0.0.4 + + + src/main/java src/test/java target @@ -180,9 +190,13 @@ + + packagecloud-graphhopper + packagecloud+https://packagecloud.io/graphhopper/jsprit + - ossrh - https://oss.sonatype.org/content/repositories/snapshots + packagecloud-graphhopper + packagecloud+https://packagecloud.io/graphhopper/jsprit