Archived
0

add time and profit to route entry

This commit is contained in:
iMoHax
2015-08-10 16:18:45 +03:00
parent 096af8d868
commit f04c050843
9 changed files with 135 additions and 50 deletions

View File

@@ -13,8 +13,8 @@ public class Route implements Comparable<Route> {
private double profit = 0;
private double balance = 0;
private double distance = 0;
private double score = 0;
private double fuel = 0;
private double time = 0;
private int lands = 0;
private int refills = 0;
@@ -64,6 +64,18 @@ public class Route implements Comparable<Route> {
return refills;
}
public double getTime() {
return time;
}
public double getFuel() {
return fuel;
}
public double getScore() {
return profit / time;
}
public void add(RouteEntry entry){
LOG.trace("Add entry {} to route {}", entry, this);
entries.add(entry);
@@ -120,7 +132,7 @@ public class Route implements Comparable<Route> {
}
void updateStats(){
LOG.trace("Update stats, old: profit={}, distance={}, lands={}, fuel={}, refills={}, score={}", profit, distance, lands, fuel, refills, score);
LOG.trace("Update stats, old: profit={}, distance={}, lands={}, fuel={}, refills={}, time={}", profit, distance, lands, fuel, refills, time);
profit = 0; distance = 0; lands = 0; fuel = 0; refills = 0;
if (entries.isEmpty()) return;
RouteEntry entry = entries.get(0);
@@ -128,7 +140,7 @@ public class Route implements Comparable<Route> {
RouteEntry next = entries.get(i);
distance += entry.getVendor().getDistance(next.getVendor());
profit += entry.getProfit();
score += entry.getScore();
time += entry.getFullTime();
fuel += entry.getFuel();
if (entry.isLand()){
lands++;
@@ -138,12 +150,12 @@ public class Route implements Comparable<Route> {
}
entry = next;
}
LOG.trace("new stats profit={}, distance={}, lands={}, fuel={}, score={}", profit, distance, lands, fuel, score);
LOG.trace("new stats profit={}, distance={}, lands={}, fuel={}, time={}", profit, distance, lands, fuel, time);
}
@Override
public int compareTo(Route o) {
return Double.compare(score, o.score);
return Double.compare(getScore(), o.getScore());
}
@Override
@@ -151,7 +163,7 @@ public class Route implements Comparable<Route> {
if (this == o) return true;
if (!(o instanceof Route)) return false;
Route route = (Route) o;
return Double.compare(route.profit, profit) == 0 && entries.equals(route.entries);
return (Double.compare(route.profit, profit) == 0 || Math.abs(profit - route.profit) < 0.1)&& entries.equals(route.entries);
}
@Override
@@ -166,7 +178,8 @@ public class Route implements Comparable<Route> {
", profit=" + profit +
", balance=" + balance +
", distance=" + distance +
", score=" + score +
", time=" + time +
", score=" + getScore() +
", fuel=" + fuel +
", lands=" + lands +
'}';

View File

@@ -13,14 +13,16 @@ public class RouteEntry {
private final List<Order> orders;
private boolean land;
private double refill;
private double score;
private double profit;
private double time;
private double fulltime;
public RouteEntry(Vendor vendor, double refill, double fuel, double score) {
public RouteEntry(Vendor vendor, double refill, double fuel, double profit) {
orders = new ArrayList<>();
this.vendor = vendor;
this.refill = refill;
this.fuel = fuel;
this.score = score;
this.profit = profit;
}
public Vendor getVendor() {
@@ -47,12 +49,28 @@ public class RouteEntry {
return fuel;
}
public double getScore() {
return score;
public double getProfit() {
return profit;
}
void setScore(double score) {
this.score = score;
void setProfit(double profit) {
this.profit = profit;
}
public double getTime() {
return time;
}
void setTime(double time) {
this.time = time;
}
public double getFullTime() {
return fulltime;
}
void setFullTime(double fullTime) {
this.fulltime = fullTime;
}
void add(Order order){
@@ -71,7 +89,7 @@ public class RouteEntry {
orders.clear();
}
public double getProfit(){
public double getProfitByOrders(){
return orders.stream().mapToDouble(Order::getProfit).sum();
}
@@ -97,6 +115,7 @@ public class RouteEntry {
if (refill != that.refill) return false;
if (Double.compare(that.fuel, fuel) != 0) return false;
if (orders.size() != that.orders.size()) return false;
if (time != that.time) return false;
return vendor.equals(that.vendor);
}
@@ -109,7 +128,7 @@ public class RouteEntry {
result = 31 * result + (int) (temp ^ (temp >>> 32));
result = 31 * result + (land ? 1 : 0);
result = 31 * result + (isRefill() ? 1 : 0);
temp = Double.doubleToLongBits(score);
temp = Double.doubleToLongBits(profit);
result = 31 * result + (int) (temp ^ (temp >>> 32));
return result;
}

View File

@@ -176,8 +176,15 @@ public class RouteFiller {
if (best != TRANSIT)
entry.addAll(best.bestOrders);
}
int jumps = i==0 || entries.get(i-1).getVendor().getPlace().equals(entry.getVendor().getPlace())? 0 : 1;
entry.setScore(i==0 ? 0 : scorer.getScore(entry, jumps));
RouteEntry prev = i != 0 ? entries.get(i-1) : null;
if (prev != null){
prev.setProfit(scorer.getProfit(prev.getProfitByOrders(), prev.getFuel()));
prev.setTime(scorer.getTime(entry, prev));
prev.setFullTime(prev.getTime());
} else {
entry.setProfit(0);
entry.setTime(0);
}
}
}

View File

@@ -24,6 +24,10 @@ public class RouteSearcher {
this.callback = callback;
}
public Scorer getScorer() {
return scorer;
}
public List<Edge<Place>> getPath(Place from, Place to, Collection<Place> places){
List<List<Edge<Place>>> res = search(from, to, places, 1, null);
return res.isEmpty() ? null : res.get(0);
@@ -103,8 +107,7 @@ public class RouteSearcher {
private List<Route> routes = new ArrayList<>();
public void add(List<Edge<Vendor>> edges){
Route route = toRoute(edges);
route.setBalance(scorer.getProfile().getBalance());
Route route = toRoute(edges, scorer);
routes.add(route);
}
@@ -113,10 +116,11 @@ public class RouteSearcher {
}
}
public static Route toRoute(List<Edge<Vendor>> edges){
public static Route toRoute(List<Edge<Vendor>> edges, final Scorer scorer){
List<RouteEntry> entries = new ArrayList<>(edges.size()+1);
Vendor buyer = null;
VendorsGraph.VendorsEdge vEdge = null;
RouteEntry prev = null;
for (Edge<Vendor> e : edges) {
vEdge = (VendorsGraph.VendorsEdge) e;
List<ConnectibleEdge<Vendor>> transitEdges = vEdge.getPath().getEntries();
@@ -129,45 +133,67 @@ public class RouteSearcher {
buyer = null;
}
if (k == 0) {
entry.setScore(vEdge.getWeight());
entry.setProfit(scorer.getProfit(vEdge.getProfit(), vEdge.getFuelCost()));
entry.setFullTime(vEdge.getTime());
List<Order> orders = vEdge.getOrders();
if (!orders.isEmpty()) {
buyer = orders.get(0).getBuyer();
entry.addAll(orders);
}
}
if (prev != null){
prev.setTime(scorer.getTime(entry, prev));
}
entries.add(entry);
prev = entry;
}
}
if (vEdge != null) {
RouteEntry entry = new RouteEntry(vEdge.getTarget().getEntry(), 0, 0, 0);
if (buyer != null) entry.setLand(true);
if (prev != null){
prev.setTime(scorer.getTime(entry, prev));
}
entries.add(entry);
}
return new Route(entries);
Route route = new Route(entries);
route.setBalance(scorer.getProfile().getBalance());
return route;
}
public static Route toRoute(Order order, List<Edge<Place>> edges){
Route route = toRoute(order.getSeller(), order.getBuyer(), edges);
public static Route toRoute(Order order, List<Edge<Place>> edges, final Scorer scorer){
Route route = toRoute(order.getSeller(), order.getBuyer(), edges, scorer);
if (route.isEmpty()) return route;
route.get(0).add(order);
route.updateStats();
return route;
}
public static Route toRoute(Vendor from, Vendor to, List<Edge<Place>> edges){
public static Route toRoute(Vendor from, Vendor to, List<Edge<Place>> edges, final Scorer scorer){
List<RouteEntry> entries = new ArrayList<>(edges.size()+1);
RouteEntry prev = null;
for (int i = 0; i < edges.size(); i++) {
ConnectibleEdge<Place> edge = (ConnectibleEdge<Place>) edges.get(i);
Vendor vendor = i == 0 ? from : edge.getSource().getEntry().asTransit();
RouteEntry entry = new RouteEntry(vendor, edge.getRefill(), edge.getFuelCost(), 0);
if (prev != null){
prev.setTime(scorer.getTime(entry, prev));
prev.setFullTime(prev.getTime());
}
entries.add(entry);
if (i == edges.size()-1){
entry = new RouteEntry(to, 0, 0, 0);
entry.setLand(true);
if (prev != null){
prev.setTime(scorer.getTime(entry, prev));
prev.setFullTime(prev.getTime());
}
entries.add(entry);
}
prev = entry;
}
return new Route(entries);
Route route = new Route(entries);
route.setBalance(scorer.getProfile().getBalance());
return route;
}
}

View File

@@ -95,15 +95,6 @@ public class Scorer {
return avgDistance;
}
public double getScore(RouteEntry entry, int jumps) {
int lands = entry.isLand() ? 1 : 0;
return getScore(entry.getVendor(), entry.getProfit(), jumps, lands, entry.getFuel());
}
public double getScore(Vendor vendor, double profit, int jumps, int lands, double fuel) {
return getScore(vendor.getDistance(), profit, jumps, lands, fuel);
}
private double getTime(double distance){
double a = 6000;
double b = 673;
@@ -111,26 +102,50 @@ public class Scorer {
return Math.log(distance + a)*b*profile.getDistanceTime() - c;
}
public double getProfitByTonne(double profit, double fuel){
return getProfit(profit, fuel) / profile.getShip().getCargo();
}
public double getProfit(double profit, double fuel){
profit -= profile.getFuelPrice() * fuel;
profit = profit / profile.getShip().getCargo();
return profit;
}
public double getTime(RouteEntry entry, RouteEntry prev) {
if (prev == null) return 0;
int lands = entry.isLand() ? 1 : 0;
int jumps = prev.getVendor().getPlace().equals(entry.getVendor().getPlace()) ? 0 : 1;
double time = getTime(entry.getVendor().getDistance(), jumps, lands);
if (!prev.isLand()){
time = time - profile.getTakeoffTime() + profile.getRechargeTime();
}
return time;
}
public double getTime(double distance, int jumps, int lands){
double time = profile.getTakeoffTime();
if (jumps > 0){
time += profile.getJumpTime() + (jumps-1) * (profile.getRechargeTime() + profile.getJumpTime());
}
if (profile.getLandingTime() > 0){
if (profile.getLandingTime() > 0 & lands > 0){
time += (lands-1)*(getTime(avgDistance) + profile.getLandingTime() + profile.getTakeoffTime()) + getTime(distance) + profile.getLandingTime();
}
return time;
}
public double getScore(RouteEntry entry, RouteEntry prev) {
int lands = prev.isLand() ? 1 : 0;
int jumps = prev.getVendor().getPlace().equals(entry.getVendor().getPlace())? 0 : 1;
return getScore(prev.getVendor(), prev.getProfit(), jumps, lands, prev.getFuel());
}
public double getScore(Vendor vendor, double profit, int jumps, int lands, double fuel) {
return getScore(vendor.getDistance(), profit, jumps, lands, fuel);
}
public double getScore(double distance, double profit, int jumps, int lands, double fuel){
LOG.trace("Compute score distance={}, profit={}, jumps={}, lands={}, fuel={}", distance, profit, jumps, lands, fuel);
double score = getProfit(profit, fuel)/getTime(distance, jumps, lands);
double score = getProfitByTonne(profit, fuel)/getTime(distance, jumps, lands);
LOG.trace("score={}", score);
return score;
}

View File

@@ -383,10 +383,19 @@ public class VendorsGraph extends ConnectibleGraph<Vendor> {
return path.getRemain();
}
@Override
public boolean isRefill() {
return path.isRefill();
}
@Override
public double getFuelCost() {
if (path != null){
return path.getFuelCost();
}
return super.getFuelCost();
}
public TransitPath getPath() {
return path;
}
@@ -415,11 +424,7 @@ public class VendorsGraph extends ConnectibleGraph<Vendor> {
}
protected double computeProfit(){
double fuel = fuelCost;
if (path != null){
fuel = path.getFuelCost();
}
return scorer.getProfit(getProfit(), fuel);
return scorer.getProfitByTonne(getProfit(), getFuelCost());
}
protected double computeTime(){

View File

@@ -176,11 +176,11 @@ public class MarketAnalyzer {
}
public Route getPath(Vendor from, Vendor to){
return RouteSearcher.toRoute(from, to, searcher.getPath(from.getPlace(), to.getPlace(), getPlaces()));
return RouteSearcher.toRoute(from, to, searcher.getPath(from.getPlace(), to.getPlace(), getPlaces()), searcher.getScorer());
}
public Route getPath(Order order){
return RouteSearcher.toRoute(order, searcher.getPath(order.getSeller().getPlace(), order.getBuyer().getPlace(), getPlaces()));
return RouteSearcher.toRoute(order, searcher.getPath(order.getSeller().getPlace(), order.getBuyer().getPlace(), getPlaces()), searcher.getScorer());
}
public Collection<Route> getTopRoutes(int limit){

View File

@@ -74,7 +74,7 @@ public class RouteSearcherTest extends Assert{
RouteFiller filler = new RouteFiller(scorer);
filler.fill(route);
assertEquals(981200, route.getProfit(), 0);
assertEquals(978883.1, route.getProfit(), 0.1);
assertEquals(2, route.getLands());
assertEquals(72.42, route.getDistance(), 0.01);
@@ -102,7 +102,7 @@ public class RouteSearcherTest extends Assert{
filler = new RouteFiller(scorer);
filler.fill(route);
assertEquals(1971200, route.getProfit(), 0);
assertEquals(1967873.6, route.getProfit(), 0.1);
assertEquals(4, route.getLands());
assertEquals(109.51, route.getDistance(), 0.01);

View File

@@ -45,7 +45,7 @@ public class MarketAnalyzerTest2 extends Assert {
assertTrue(path.isPresent());
Route actual = path.get();
assertEquals(expect, actual);
assertEquals(981200, actual.getProfit(), 0.00001);
assertEquals(978883.1, actual.getProfit(), 0.1);
assertEquals(72.42, actual.getDistance(), 0.01);
assertEquals(2, actual.getLands());
}
@@ -78,7 +78,7 @@ public class MarketAnalyzerTest2 extends Assert {
assertTrue(path.isPresent());
Route actual = path.get();
assertEquals(199056, actual.getProfit(), 0.00001);
assertEquals(198127.6, actual.getProfit(), 0.1);
assertEquals(28.72, actual.getDistance(), 0.01);
assertEquals(2, actual.getLands());