Archived
0

implement scorer

This commit is contained in:
iMoHax
2015-04-15 20:56:19 +03:00
parent ad760938a7
commit bef5cc2f99
8 changed files with 185 additions and 26 deletions

View File

@@ -0,0 +1,45 @@
package ru.trader.analysis;
import ru.trader.core.*;
import java.util.Collection;
import java.util.stream.Stream;
public class FilteredMarket {
private final Market market;
private final MarketFilter filter;
public FilteredMarket(Market market, MarketFilter filter) {
this.market = market;
this.filter = filter;
}
public Stream<Place> get(){
return market.get().stream()
.filter(p -> !filter.isFiltered(p));
}
public Stream<Vendor> getVendors(){
return get().flatMap(p -> p.get().stream())
.filter(v -> !filter.isFiltered(v));
}
public Collection<Item> getItems(){
return market.getItems();
}
public Stream<Offer> getSell(Item item){
return getOffers(OFFER_TYPE.SELL, item);
}
public Stream<Offer> getBuy(Item item){
return getOffers(OFFER_TYPE.BUY, item);
}
public Stream<Offer> getOffers(OFFER_TYPE offerType, Item item){
return market.getStat(offerType, item).getOffers().stream()
.filter(o -> !filter.isFiltered(o.getVendor(), true));
}
}

View File

@@ -0,0 +1,102 @@
package ru.trader.analysis;
import ru.trader.core.*;
import java.util.*;
import java.util.stream.Stream;
public class Scorer {
private final Map<Item, Offer> sellOffers;
private final Map<Item, Offer> buyOffers;
private final FilteredMarket market;
private final Profile profile;
private int ordersCount = 5;
private double avgProfit;
public Scorer(FilteredMarket market, Profile profile) {
this.market = market;
this.profile = profile;
sellOffers = new HashMap<>(100, 0.9f);
buyOffers = new HashMap<>(100, 0.9f);
market.getItems().parallelStream().forEach(this::fillOffers);
avgProfit = computeAvgProfit();
}
private void fillOffers(Item item){
Optional<Offer> offer = market.getSell(item).findFirst();
if (offer.isPresent()){
sellOffers.put(item, offer.get());
}
offer = market.getBuy(item).findFirst();
if (offer.isPresent()){
buyOffers.put(item, offer.get());
}
}
public void setOrdersCount(int ordersCount) {
this.ordersCount = ordersCount;
}
private double computeAvgProfit(){
OptionalDouble avg = sellOffers.values().stream()
.flatMap(this::mapToOrder)
.mapToDouble(Order::getProfit)
.average();
return avg.orElse(0);
}
public Score getScore(Vendor vendor){
Stream<Order> sellOrders = vendor.getAllSellOffers().stream().flatMap(this::mapToOrder);
Stream<Order> buyOrders = vendor.getAllBuyOffers().stream().flatMap(this::mapToOrder);
return new Score(sellOrders, buyOrders);
}
private Stream<Order> mapToOrder(Offer offer) {
Offer sell;
Offer buy;
if (offer.getType() == OFFER_TYPE.SELL){
sell = offer;
buy = buyOffers.get(offer.getItem());
} else {
sell = sellOffers.get(offer.getItem());
buy = offer;
}
if (sell == null || buy == null) return Stream.empty();
Order order = new Order(sell, buy, profile.getBalance(), profile.getShip().getCargo());
if (order.getProfit() <= 0) return Stream.empty();
return Stream.of(order);
}
public class Score {
private double sellProfit;
private double buyProfit;
private double score;
public Score(Stream<Order> sell, Stream<Order> buy) {
sellProfit = computeProfits(sell);
buyProfit = computeProfits(buy);
long count = sell.limit(ordersCount).count();
computeScore(count);
}
private double computeProfits(Stream<Order> orders) {
OptionalDouble profit = orders.sorted(Comparator.<Order>reverseOrder())
.limit(ordersCount)
.mapToDouble(Order::getProfit)
.average();
return profit.orElse(0);
}
private void computeScore(long sellOrdersCount){
score = (sellProfit + buyProfit)/2;
if (sellOrdersCount < ordersCount){
score =- Math.abs(avgProfit-sellProfit) * (ordersCount - sellOrdersCount) / score;
}
}
}
}

View File

@@ -84,6 +84,11 @@ public class MarketFilter {
} }
public boolean isFiltered(Vendor vendor){ public boolean isFiltered(Vendor vendor){
return isFiltered(vendor, false);
}
public boolean isFiltered(Vendor vendor, boolean checkPlace){
if (checkPlace && isFiltered(vendor.getPlace())) return true;
if (distance > 0 && vendor.getDistance() > distance) return true; if (distance > 0 && vendor.getDistance() > distance) return true;
if (excludes.contains(vendor)) return true; if (excludes.contains(vendor)) return true;
for (SERVICE_TYPE service : services) { for (SERVICE_TYPE service : services) {

View File

@@ -16,9 +16,13 @@ public class Order implements Comparable<Order> {
this.profit = Double.NaN; this.profit = Double.NaN;
} }
public Order(Offer sell, Offer buy, double balance, long limit) {
this(sell, buy);
setMax(balance, limit);
}
public Order(Offer sell, Offer buy, long count) { public Order(Offer sell, Offer buy, long count) {
this.sell = sell; this(sell, buy);
this.buy = buy;
this.count = getMaxCount(sell, buy, count); this.count = getMaxCount(sell, buy, count);
this.profit = (buy.getPrice() - sell.getPrice()) * count; this.profit = (buy.getPrice() - sell.getPrice()) * count;
} }

View File

@@ -0,0 +1,15 @@
package ru.trader.core;
public class Profile {
private double balance;
private Ship ship;
public double getBalance() {
return balance;
}
public Ship getShip() {
return ship;
}
}

View File

@@ -2,35 +2,23 @@ package ru.trader.core;
public class Ship { public class Ship {
private double balance; private int cargo;
private long cargo;
private double engine; private double engine;
private int jumps;
public Ship(double balance, long cargo, double engine, int jumps) { public Ship(int cargo, double engine) {
this.balance = balance;
this.cargo = cargo; this.cargo = cargo;
this.engine = engine; this.engine = engine;
this.jumps = jumps;
} }
public static Ship copyOf(Ship other){ public static Ship copyOf(Ship other){
return new Ship(other.balance, other.cargo, other.engine, other.jumps); return new Ship(other.cargo, other.engine);
} }
public double getBalance() { public int getCargo() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public long getCargo() {
return cargo; return cargo;
} }
public void setCargo(long cargo) { public void setCargo(int cargo) {
this.cargo = cargo; this.cargo = cargo;
} }
@@ -42,11 +30,4 @@ public class Ship {
this.engine = engine; this.engine = engine;
} }
public int getJumps() {
return jumps;
}
public void setJumps(int jumps) {
this.jumps = jumps;
}
} }

View File

@@ -13,6 +13,12 @@ public class VendorsIterator implements Iterator<Vendor> {
private Iterator<Vendor> vendors; private Iterator<Vendor> vendors;
private Vendor next; private Vendor next;
public VendorsIterator(Iterator<Place> places, boolean includeTransit) {
this.places = places;
this.includeTransit = includeTransit;
nextPlace();
}
public VendorsIterator(Collection<Place> places, boolean includeTransit) { public VendorsIterator(Collection<Place> places, boolean includeTransit) {
this.places = places.iterator(); this.places = places.iterator();
this.includeTransit = includeTransit; this.includeTransit = includeTransit;

File diff suppressed because one or more lines are too long