Increase search speed, add minimum vendor rating parameter for skip low profitable vendors
This commit is contained in:
@@ -36,6 +36,8 @@ public class SettingsController {
|
||||
@FXML
|
||||
private NumberField routesCount;
|
||||
@FXML
|
||||
private NumberField minVendorRating;
|
||||
@FXML
|
||||
private NumberField fuelPrice;
|
||||
@FXML
|
||||
private ComboBox<Profile.PATH_PRIORITY> pathPriority;
|
||||
@@ -93,6 +95,7 @@ public class SettingsController {
|
||||
jumps.setValue(profile.getJumps());
|
||||
lands.setValue(profile.getLands());
|
||||
routesCount.setValue(profile.getRoutesCount());
|
||||
minVendorRating.setValue(profile.getMinVendorRating());
|
||||
fuelPrice.setValue(profile.getFuelPrice());
|
||||
pathPriority.setValue(profile.getPathPriority());
|
||||
jumpTime.setValue(profile.getJumpTime());
|
||||
@@ -134,6 +137,7 @@ public class SettingsController {
|
||||
profile.setJumps(jumps.getValue().intValue());
|
||||
profile.setLands(lands.getValue().intValue());
|
||||
profile.setRoutesCount(routesCount.getValue().intValue());
|
||||
profile.setMinVendorRating(minVendorRating.getValue().doubleValue());
|
||||
profile.setFuelPrice(fuelPrice.getValue().intValue());
|
||||
profile.setPathPriority(pathPriority.getValue());
|
||||
profile.setJumpTime(jumpTime.getValue().intValue());
|
||||
|
||||
@@ -184,13 +184,14 @@ settings.emdn.on=Active
|
||||
settings.emdn.sub=Server SUB:
|
||||
settings.emdn.updateOnly=Update price only:
|
||||
settings.emdn.auto=Auto update (sec.):
|
||||
settings.edce.on=Active
|
||||
settings.edce.interval=Update interval, sec.
|
||||
settings.performance=Performance
|
||||
settings.performance.segmentSize=Segment size (0 - auto):
|
||||
settings.performance.limit=Routes count:
|
||||
settings.edce.on=Active
|
||||
settings.edce.interval=Update interval, sec.
|
||||
settings.performance.jumps=Jumps:
|
||||
settings.performance.landings=Landings:
|
||||
settings.performance.minVendorRating=Minimal station rating (0-10):
|
||||
settings.search=Search options
|
||||
settings.search.fuelPrice=1t fuel price:
|
||||
settings.search.pathType=Path priority:
|
||||
|
||||
@@ -183,13 +183,14 @@ settings.emdn.on=\u0412\u043A\u043B\u044E\u0447\u0438\u0442\u044C
|
||||
settings.emdn.sub=\u0421\u0435\u0440\u0432\u0435\u0440 SUB:
|
||||
settings.emdn.updateOnly=\u0422\u043E\u043B\u044C\u043A\u043E \u043E\u0431\u043D\u043E\u0432\u043B\u044F\u0442\u044C \u0446\u0435\u043D\u044B:
|
||||
settings.emdn.auto=\u041E\u0431\u043D\u043E\u0432\u043B\u044F\u0442\u044C \u0430\u0442\u043E\u043C\u0430\u0442\u0438\u0447\u0435\u0441\u043A\u0438 \u0447\u0435\u0440\u0435\u0437 (\u0441\u0435\u043A.):
|
||||
settings.edce.on=\u0412\u043A\u043B\u044E\u0447\u0438\u0442\u044C
|
||||
settings.edce.interval=\u0418\u043D\u0442\u0435\u0440\u0432\u0430\u043B, \u0441\u0435\u043A.
|
||||
settings.performance=\u041F\u0440\u043E\u0438\u0437\u0432\u043E\u0434\u0438\u0442\u0435\u043B\u044C\u043D\u043E\u0441\u0442\u044C
|
||||
settings.performance.segmentSize=\u041C\u0430\u0440\u0448\u0440\u0443\u0442\u043E\u0432 \u0432 \u0441\u0435\u0433\u043C\u0435\u043D\u0442\u0435 (0 - \u0430\u0432\u0442\u043E):
|
||||
settings.performance.limit=\u041A\u043E\u043B-\u0432\u043E \u043C\u0430\u0440\u0448\u0440\u0443\u0442\u043E\u0432 \u043D\u0430 \u0432\u044B\u0432\u043E\u0434:
|
||||
settings.edce.on=\u0412\u043A\u043B\u044E\u0447\u0438\u0442\u044C
|
||||
settings.edce.interval=\u0418\u043D\u0442\u0435\u0440\u0432\u0430\u043B, \u0441\u0435\u043A.
|
||||
settings.performance.jumps=\u041F\u0440\u044B\u0436\u043A\u043E\u0432:
|
||||
settings.performance.landings=\u041F\u043E\u0441\u0430\u0434\u043E\u043A:
|
||||
settings.performance.minVendorRating=\u041C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u044B\u0439 \u0440\u0435\u0439\u0442\u0438\u043D\u0433 \u0441\u0442\u0430\u043D\u0446\u0438\u0438 (0-10):
|
||||
settings.search=\u041F\u0430\u0440\u0430\u043C\u0435\u0442\u0440\u044B \u043F\u043E\u0438\u0441\u043A\u0430
|
||||
settings.search.fuelPrice=\u0421\u0442\u043E\u0438\u043C\u043E\u0441\u0442\u044C 1\u0442 \u0442\u043E\u043F\u043B\u0438\u0432\u0430:
|
||||
settings.search.pathType=\u0422\u0438\u043F \u043C\u0430\u0440\u0448\u0440\u0443\u0442\u043E\u0432:
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
<?import javafx.scene.layout.*?>
|
||||
<?import ru.trader.view.support.*?>
|
||||
<?import org.controlsfx.glyphfont.Glyph?>
|
||||
<GridPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ru.trader.controllers.SettingsController"
|
||||
styleClass="dialog" vgap="4" hgap="8">
|
||||
<ScrollPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="ru.trader.controllers.SettingsController"
|
||||
styleClass="dialog">
|
||||
<GridPane vgap="4" hgap="8">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints />
|
||||
<ColumnConstraints minWidth="260" maxWidth="260"/>
|
||||
@@ -26,38 +27,40 @@
|
||||
<NumberField fx:id="lands" maxWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="5" />
|
||||
<Label text="%settings.performance.limit" GridPane.rowIndex="6" />
|
||||
<NumberField fx:id="routesCount" maxWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="6" />
|
||||
<Label text="%settings.search" styleClass="settings-group" GridPane.halignment="CENTER" GridPane.columnSpan="2" GridPane.rowIndex="7"/>
|
||||
<Label text="%settings.search.fuelPrice" GridPane.rowIndex="8" />
|
||||
<NumberField fx:id="fuelPrice" maxWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="8" />
|
||||
<Label text="%settings.search.pathType" GridPane.rowIndex="9" />
|
||||
<ComboBox fx:id="pathPriority" maxWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="9" />
|
||||
<Label text="%settings.search.times.jump" GridPane.rowIndex="10" />
|
||||
<NumberField fx:id="jumpTime" maxWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="10" />
|
||||
<Label text="%settings.search.times.landing" GridPane.rowIndex="11" />
|
||||
<NumberField fx:id="landingTime" maxWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="11" />
|
||||
<Label text="%settings.search.times.orbital" GridPane.rowIndex="12" />
|
||||
<NumberField fx:id="orbitalTime" maxWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="12" />
|
||||
<Label text="%settings.search.times.takeoff" GridPane.rowIndex="13" />
|
||||
<NumberField fx:id="takeoffTime" maxWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="13" />
|
||||
<Label text="%settings.search.times.recharge" GridPane.rowIndex="14" />
|
||||
<NumberField fx:id="rechargeTime" maxWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="14" />
|
||||
<Label text="%settings.hotkeys" styleClass="settings-group" GridPane.halignment="CENTER" GridPane.columnSpan="2" GridPane.rowIndex="15"/>
|
||||
<Label text="%settings.hotkeys.complete" GridPane.rowIndex="16" />
|
||||
<TextField fx:id="completeKeyText" maxWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="16" />
|
||||
<Label text="ED Log Watcher" styleClass="settings-group" GridPane.halignment="CENTER" GridPane.columnSpan="2" GridPane.rowIndex="17"/>
|
||||
<Label text="%settings.edlog.on" GridPane.rowIndex="18"/>
|
||||
<CheckBox fx:id="edLogActive" GridPane.columnIndex="1" GridPane.rowIndex="18"/>
|
||||
<Label text="%settings.edlog.dir" GridPane.rowIndex="19" />
|
||||
<HBox maxWidth="260" GridPane.columnIndex="1" GridPane.rowIndex="19">
|
||||
<Label text="%settings.performance.minVendorRating" GridPane.rowIndex="7" />
|
||||
<NumberField fx:id="minVendorRating" maxWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="7" />
|
||||
<Label text="%settings.search" styleClass="settings-group" GridPane.halignment="CENTER" GridPane.columnSpan="2" GridPane.rowIndex="8"/>
|
||||
<Label text="%settings.search.fuelPrice" GridPane.rowIndex="9" />
|
||||
<NumberField fx:id="fuelPrice" maxWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="9" />
|
||||
<Label text="%settings.search.pathType" GridPane.rowIndex="10" />
|
||||
<ComboBox fx:id="pathPriority" maxWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="10" />
|
||||
<Label text="%settings.search.times.jump" GridPane.rowIndex="11" />
|
||||
<NumberField fx:id="jumpTime" maxWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="11" />
|
||||
<Label text="%settings.search.times.landing" GridPane.rowIndex="12" />
|
||||
<NumberField fx:id="landingTime" maxWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="12" />
|
||||
<Label text="%settings.search.times.orbital" GridPane.rowIndex="13" />
|
||||
<NumberField fx:id="orbitalTime" maxWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="13" />
|
||||
<Label text="%settings.search.times.takeoff" GridPane.rowIndex="14" />
|
||||
<NumberField fx:id="takeoffTime" maxWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="14" />
|
||||
<Label text="%settings.search.times.recharge" GridPane.rowIndex="15" />
|
||||
<NumberField fx:id="rechargeTime" maxWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="15" />
|
||||
<Label text="%settings.hotkeys" styleClass="settings-group" GridPane.halignment="CENTER" GridPane.columnSpan="2" GridPane.rowIndex="16"/>
|
||||
<Label text="%settings.hotkeys.complete" GridPane.rowIndex="17" />
|
||||
<TextField fx:id="completeKeyText" maxWidth="100" GridPane.columnIndex="1" GridPane.rowIndex="17" />
|
||||
<Label text="ED Log Watcher" styleClass="settings-group" GridPane.halignment="CENTER" GridPane.columnSpan="2" GridPane.rowIndex="18"/>
|
||||
<Label text="%settings.edlog.on" GridPane.rowIndex="19"/>
|
||||
<CheckBox fx:id="edLogActive" GridPane.columnIndex="1" GridPane.rowIndex="19"/>
|
||||
<Label text="%settings.edlog.dir" GridPane.rowIndex="20" />
|
||||
<HBox maxWidth="260" GridPane.columnIndex="1" GridPane.rowIndex="20">
|
||||
<TextField fx:id="edLogDir" />
|
||||
<Button minWidth="30" minHeight="25" onAction="#selectLogDir"><graphic><Glyph text="FontAwesome|FOLDER_OPEN"/></graphic></Button>
|
||||
|
||||
</HBox>
|
||||
<Label text="%settings.emdn" styleClass="settings-group" GridPane.halignment="CENTER" GridPane.columnSpan="2" GridPane.rowIndex="20"/>
|
||||
<Label text="%settings.emdn.on" GridPane.rowIndex="21"/>
|
||||
<CheckBox fx:id="emdnOn" GridPane.columnIndex="1" GridPane.rowIndex="21"/>
|
||||
<Label text="%settings.emdn.sub" GridPane.rowIndex="22" />
|
||||
<TextField fx:id="emdnSubServ" GridPane.columnIndex="1" GridPane.rowIndex="22" />
|
||||
<Label text="%settings.emdn" styleClass="settings-group" GridPane.halignment="CENTER" GridPane.columnSpan="2" GridPane.rowIndex="21"/>
|
||||
<Label text="%settings.emdn.on" GridPane.rowIndex="22"/>
|
||||
<CheckBox fx:id="emdnOn" GridPane.columnIndex="1" GridPane.rowIndex="22"/>
|
||||
<Label text="%settings.emdn.sub" GridPane.rowIndex="23" />
|
||||
<TextField fx:id="emdnSubServ" GridPane.columnIndex="1" GridPane.rowIndex="23" />
|
||||
|
||||
</GridPane>
|
||||
|
||||
</ScrollPane>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package ru.trader.analysis;
|
||||
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import ru.trader.analysis.graph.Edge;
|
||||
import ru.trader.core.Offer;
|
||||
import ru.trader.core.Vendor;
|
||||
@@ -165,6 +166,7 @@ public class CrawlerSpecificator {
|
||||
if (res) return true;
|
||||
for (TimeEntry<Offer> entry : offers){
|
||||
Offer offer = entry.obj;
|
||||
if (offer.getVendor().equals(vendor)) return true;
|
||||
Offer sell = vendor.getSell(offer.getItem());
|
||||
res = sell != null && sell.getCount() >= offer.getCount();
|
||||
if (res) return true;
|
||||
@@ -172,12 +174,23 @@ public class CrawlerSpecificator {
|
||||
return false;
|
||||
}
|
||||
|
||||
public Collection<Vendor> getVendors(Collection<Vendor> vendors){
|
||||
Set<Vendor> v = containsAny.stream().map(e -> e.obj).collect(Collectors.toSet());
|
||||
any.stream().map(e -> e.obj).forEach(v::add);
|
||||
all.stream().map(e -> e.obj).forEach(v::add);
|
||||
offers.stream().map(e -> e.obj.getVendor()).forEach(v::add);
|
||||
v.addAll(vendors);
|
||||
public Set<Vendor> getVendors(Collection<Scorer.Rating> vendors){
|
||||
Set<Vendor> v = all.stream().map(e -> e.obj).collect(Collectors.toSet());
|
||||
if (containsAny.size() > 0){
|
||||
vendors.stream().filter(r -> contains(containsAny, r.getVendor())).sorted().limit(5).forEach(r -> v.add(r.getVendor()));
|
||||
}
|
||||
if (any.size() > 0){
|
||||
vendors.stream().filter(r -> contains(any, r.getVendor())).sorted().limit(5).forEach(r -> v.add(r.getVendor()));
|
||||
}
|
||||
|
||||
for (TimeEntry<Offer> entry : offers) {
|
||||
vendors.stream().filter(r -> {
|
||||
Offer offer = entry.obj;
|
||||
if (offer.getVendor().equals(r.getVendor())) return true;
|
||||
Offer sell = r.getVendor().getSell(offer.getItem());
|
||||
return sell != null && sell.getCount() >= offer.getCount();
|
||||
}).sorted().limit(5).forEach(r -> v.add(r.getVendor()));
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,70 +27,26 @@ import java.util.stream.Stream;
|
||||
public class Scorer {
|
||||
private final static Logger LOG = LoggerFactory.getLogger(Scorer.class);
|
||||
|
||||
private final Map<Item, Offer> sellOffers;
|
||||
private final Map<Item, Offer> buyOffers;
|
||||
private final FilteredMarket market;
|
||||
private final Profile profile;
|
||||
|
||||
private final double avgProfit;
|
||||
private final double minProfit;
|
||||
private final double maxProfit;
|
||||
private final double maxScore;
|
||||
private final double avgDistance;
|
||||
|
||||
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().forEach(this::fillOffers);
|
||||
DoubleSummaryStatistics statProfit = computeProfit();
|
||||
minProfit = statProfit.getMin() / profile.getShip().getCargo();
|
||||
avgProfit = statProfit.getAverage() / profile.getShip().getCargo();
|
||||
maxProfit = statProfit.getMax() / profile.getShip().getCargo();
|
||||
|
||||
avgDistance = computeAvgDistance();
|
||||
maxScore = getScore(1, statProfit.getMax(), 0, 1, 0, 0);
|
||||
}
|
||||
|
||||
public Profile getProfile() {
|
||||
return profile;
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
}
|
||||
|
||||
private DoubleSummaryStatistics computeProfit(){
|
||||
return sellOffers.values().stream()
|
||||
.flatMap(this::mapToOrder)
|
||||
.collect(Collectors.summarizingDouble(Order::getProfit));
|
||||
}
|
||||
|
||||
private double computeAvgDistance(){
|
||||
OptionalDouble res = market.getVendors().mapToDouble(Vendor::getDistance).average();
|
||||
return res.orElse(0);
|
||||
}
|
||||
|
||||
public double getAvgProfit() {
|
||||
return avgProfit;
|
||||
}
|
||||
|
||||
public double getMaxProfit() {
|
||||
return maxProfit;
|
||||
}
|
||||
|
||||
public double getMaxScore() {
|
||||
return maxScore;
|
||||
}
|
||||
|
||||
public double getAvgDistance() {
|
||||
return avgDistance;
|
||||
}
|
||||
@@ -157,25 +113,113 @@ public class Scorer {
|
||||
return score;
|
||||
}
|
||||
|
||||
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 List<Order> getOrders(Vendor seller, Vendor buyer){
|
||||
FilteredVendor fSeller = market.getFiltered(seller);
|
||||
FilteredVendor fBuyer = market.getFiltered(buyer);
|
||||
return MarketUtils.getOrders(fSeller, fBuyer);
|
||||
}
|
||||
|
||||
public RatingComputer getRatingComputer(final Set<Vendor> vendors){
|
||||
return new RatingComputer(vendors);
|
||||
}
|
||||
|
||||
public class RatingComputer {
|
||||
private final Map<Item, Offer> sellOffers;
|
||||
private final Map<Item, Offer> buyOffers;
|
||||
|
||||
private final DoubleSummaryStatistics globalStat;
|
||||
private final double avgDistance;
|
||||
|
||||
private RatingComputer(final Set<Vendor> vendors) {
|
||||
sellOffers = new HashMap<>(100, 0.9f);
|
||||
buyOffers = new HashMap<>(100, 0.9f);
|
||||
market.getItems().forEach(i -> fillOffers(i, vendors));
|
||||
globalStat = computeProfit();
|
||||
avgDistance = vendors.stream().mapToDouble(Vendor::getDistance).average().orElse(0);
|
||||
}
|
||||
|
||||
private void fillOffers(Item item, Set<Vendor> vendors){
|
||||
Optional<Offer> offer = market.getSell(item).filter(o -> vendors.contains(o.getVendor())).findFirst();
|
||||
if (offer.isPresent()){
|
||||
sellOffers.put(item, offer.get());
|
||||
}
|
||||
offer = market.getBuy(item).filter(o -> vendors.contains(o.getVendor())).findFirst();
|
||||
if (offer.isPresent()){
|
||||
buyOffers.put(item, offer.get());
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
private DoubleSummaryStatistics computeProfit(){
|
||||
return sellOffers.values().stream()
|
||||
.flatMap(this::mapToOrder)
|
||||
.collect(Collectors.summarizingDouble(Order::getProfit));
|
||||
}
|
||||
|
||||
private DoubleSummaryStatistics computeProfits(Stream<Order> orders) {
|
||||
return orders.sorted(Comparator.<Order>reverseOrder())
|
||||
.limit(4)
|
||||
.filter(o -> o.getProfit() > 0)
|
||||
.collect(Collectors.summarizingDouble(Order::getProfit));
|
||||
}
|
||||
|
||||
public Rating getRating(Vendor vendor){
|
||||
Stream<Order> sell = vendor.getAllSellOffers().stream().flatMap(this::mapToOrder);
|
||||
Stream<Order> buy = vendor.getAllBuyOffers().stream().flatMap(this::mapToOrder);
|
||||
|
||||
DoubleSummaryStatistics sellStat = computeProfits(sell);
|
||||
DoubleSummaryStatistics buyStat = computeProfits(buy);
|
||||
|
||||
double sellRate = 0.5 * sellStat.getMax() / globalStat.getMax() + 2.5 * sellStat.getAverage() / globalStat.getAverage();
|
||||
double buyRate = 0.5 * buyStat.getMax() / globalStat.getMax() + 2 * buyStat.getAverage() / globalStat.getAverage();
|
||||
double distRate = 0.5 * (vendor.getDistance() > 0 ? (vendor.getDistance() < avgDistance ? 1-vendor.getDistance()/avgDistance : -1+avgDistance/vendor.getDistance()) : 0.0);
|
||||
|
||||
LOG.trace("Computed rate for {} = {}", vendor.getFullName(), sellRate + buyRate + distRate);
|
||||
LOG.trace("global - max: {} avg: {} min: {}", globalStat.getMax(), globalStat.getAverage(), globalStat.getMin());
|
||||
LOG.trace("sell - max: {} avg: {} min: {} rate: {}", sellStat.getMax(), sellStat.getAverage(), sellStat.getMin(), sellRate);
|
||||
LOG.trace("buy - max: {} avg: {} min: {} rate: {}", buyStat.getMax(), buyStat.getAverage(), buyStat.getMin(), buyRate);
|
||||
LOG.trace("distance: {} avg: {} rate: {}", vendor.getDistance(), avgDistance, distRate);
|
||||
|
||||
return new Rating(vendor, sellRate + buyRate + distRate);
|
||||
}
|
||||
}
|
||||
|
||||
public class Rating implements Comparable<Rating> {
|
||||
private final Vendor vendor;
|
||||
private final double rate;
|
||||
|
||||
public Rating(Vendor vendor, double rate) {
|
||||
this.vendor = vendor;
|
||||
this.rate = rate;
|
||||
}
|
||||
|
||||
public Vendor getVendor() {
|
||||
return vendor;
|
||||
}
|
||||
|
||||
public double getRate() {
|
||||
return rate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(Rating o) {
|
||||
return Double.compare(rate, o.rate);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -296,13 +296,26 @@ public class MarketAnalyzer {
|
||||
|
||||
private Collection<Vendor> getVendors(CrawlerSpecificator specificator, boolean withTransit){
|
||||
List<Vendor> transits = withTransit ? market.get().map(Place::asTransit).collect(Collectors.toList()) : new ArrayList<>();
|
||||
Collection<Vendor> vendors;
|
||||
Set<Vendor> vendors;
|
||||
if (!specificator.isFullScan() || specificator.getMinHop() >= profile.getLands()){
|
||||
vendors = market.getMarkets().filter(specificator::contains).collect(Collectors.toList());
|
||||
vendors = market.getMarkets().filter(specificator::contains).collect(Collectors.toSet());
|
||||
} else {
|
||||
vendors = market.getMarkets().collect(Collectors.toList());
|
||||
vendors = market.getMarkets().collect(Collectors.toSet());
|
||||
}
|
||||
vendors = specificator.getVendors(vendors);
|
||||
Scorer.RatingComputer ratings = searcher.getScorer().getRatingComputer(vendors);
|
||||
Collection<Scorer.Rating> removes = new ArrayList<>(500);
|
||||
vendors.removeIf(v -> {
|
||||
Scorer.Rating rating = ratings.getRating(v);
|
||||
if (rating.getRate() <= profile.getMinVendorRating()){
|
||||
if (specificator.contains(v)){
|
||||
removes.add(rating);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
vendors.addAll(specificator.getVendors(removes));
|
||||
vendors.addAll(transits);
|
||||
return vendors;
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ public class Profile {
|
||||
private int lands;
|
||||
private boolean refill;
|
||||
private int routesCount;
|
||||
private double minVendorRating;
|
||||
//Scorer multipliers
|
||||
private double distanceTime;
|
||||
private double jumpTime;
|
||||
@@ -31,6 +32,7 @@ public class Profile {
|
||||
jumps = 3;
|
||||
lands = 4;
|
||||
routesCount = 30;
|
||||
minVendorRating = 7;
|
||||
distanceTime = 0.3;
|
||||
fuelPrice = 100;
|
||||
landingTime = 80;
|
||||
@@ -49,6 +51,7 @@ public class Profile {
|
||||
this.lands = profile.lands;
|
||||
this.refill = profile.refill;
|
||||
this.routesCount = profile.routesCount;
|
||||
this.minVendorRating = profile.minVendorRating;
|
||||
this.distanceTime = profile.distanceTime;
|
||||
this.jumpTime = profile.jumpTime;
|
||||
this.landingTime = profile.landingTime;
|
||||
@@ -142,6 +145,14 @@ public class Profile {
|
||||
this.routesCount = routesCount;
|
||||
}
|
||||
|
||||
public double getMinVendorRating() {
|
||||
return minVendorRating;
|
||||
}
|
||||
|
||||
public void setMinVendorRating(double minVendorRating) {
|
||||
this.minVendorRating = minVendorRating;
|
||||
}
|
||||
|
||||
public double getDistanceTime() {
|
||||
return distanceTime;
|
||||
}
|
||||
@@ -230,6 +241,7 @@ public class Profile {
|
||||
profile.setLands(Integer.valueOf(values.getProperty("profile.lands", "4")));
|
||||
profile.setPathPriority(PATH_PRIORITY.valueOf(values.getProperty("profile.search.priority", "FAST")));
|
||||
profile.setRoutesCount(Integer.valueOf(values.getProperty("profile.search.routes", "30")));
|
||||
profile.setMinVendorRating(Double.valueOf(values.getProperty("profile.search.minRating", "7")));
|
||||
profile.setFuelPrice(Double.valueOf(values.getProperty("profile.search.fuel.price", "100")));
|
||||
profile.setDistanceTime(Double.valueOf(values.getProperty("profile.search.times.distance", "0.3")));
|
||||
profile.setLandingTime(Double.valueOf(values.getProperty("profile.search.times.landing", "80")));
|
||||
@@ -250,6 +262,7 @@ public class Profile {
|
||||
values.setProperty("profile.lands", String.valueOf(lands));
|
||||
values.setProperty("profile.search.priority", String.valueOf(pathPriority));
|
||||
values.setProperty("profile.search.routes", String.valueOf(routesCount));
|
||||
values.setProperty("profile.search.minRating", String.valueOf(minVendorRating));
|
||||
values.setProperty("profile.search.fuel.price", String.valueOf(fuelPrice));
|
||||
values.setProperty("profile.search.times.distance", String.valueOf(distanceTime));
|
||||
values.setProperty("profile.search.times.landing", String.valueOf(landingTime));
|
||||
|
||||
@@ -36,7 +36,7 @@ public class ScorerTest extends Assert {
|
||||
profile.setBalance(1000000);
|
||||
Scorer scorer = new Scorer(fWorld, profile);
|
||||
|
||||
double avgProfit = scorer.getAvgProfit() * profile.getShip().getCargo();
|
||||
double avgProfit = 750 * profile.getShip().getCargo();
|
||||
|
||||
double score = scorer.getScore(scorer.getAvgDistance(), 0, 1, 1, 0, 4);
|
||||
double score1 = scorer.getScore(scorer.getAvgDistance(), avgProfit/2, 1, 1, 0, 4);
|
||||
|
||||
Reference in New Issue
Block a user