implement offers crawler builder
This commit is contained in:
@@ -8,6 +8,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
public class CrawlerSpecificator {
|
public class CrawlerSpecificator {
|
||||||
private final List<Vendor> any;
|
private final List<Vendor> any;
|
||||||
@@ -69,17 +70,33 @@ public class CrawlerSpecificator {
|
|||||||
this.groupCount = groupCount;
|
this.groupCount = groupCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VendorsCrawlerSpecification build(Consumer<List<Edge<Vendor>>> onFoundFunc, RouteSpecification<Vendor> andSpec, boolean loop){
|
private RouteSpecification<Vendor> buildOffersSpec(Collection<Vendor> vendors){
|
||||||
|
RouteSpecification<Vendor> res = null;
|
||||||
|
for (Offer offer : offers) {
|
||||||
|
List<Vendor> sellers = vendors.stream().filter(v -> {
|
||||||
|
Offer sell = v.getSell(offer.getItem());
|
||||||
|
return sell != null && sell.getCount() >= offer.getCount();
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
if (res != null){
|
||||||
|
res = res.and(RouteSpecificationByTargets.containAny(sellers));
|
||||||
|
} else {
|
||||||
|
res = RouteSpecificationByTargets.containAny(sellers);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public VendorsCrawlerSpecification build(Collection<Vendor> vendors, Consumer<List<Edge<Vendor>>> onFoundFunc, RouteSpecification<Vendor> andSpec, boolean loop){
|
||||||
RouteSpecification<Vendor> spec;
|
RouteSpecification<Vendor> spec;
|
||||||
RouteSpecification<Vendor> res = null;
|
RouteSpecification<Vendor> res = null;
|
||||||
if (!all.isEmpty()){
|
if (!all.isEmpty()){
|
||||||
spec = all.size() > 1 ? RouteSpecificationByTargets.all(all) : new RouteSpecificationByTarget<>(all.get(0));
|
spec = RouteSpecificationByTargets.all(all);
|
||||||
res = spec;
|
res = spec;
|
||||||
}
|
}
|
||||||
if (!any.isEmpty()){
|
if (!any.isEmpty()){
|
||||||
spec = any.size() > 1 ? RouteSpecificationByTargets.any(any) : new RouteSpecificationByTarget<>(any.get(0));
|
spec = any.size() > 1 ? RouteSpecificationByTargets.any(any) : new RouteSpecificationByTarget<>(any.get(0));
|
||||||
if (res != null){
|
if (res != null){
|
||||||
res.and(spec);
|
res = res.and(spec);
|
||||||
} else {
|
} else {
|
||||||
res = spec;
|
res = spec;
|
||||||
}
|
}
|
||||||
@@ -87,14 +104,22 @@ public class CrawlerSpecificator {
|
|||||||
if (!containsAny.isEmpty()){
|
if (!containsAny.isEmpty()){
|
||||||
spec = RouteSpecificationByTargets.containAny(containsAny);
|
spec = RouteSpecificationByTargets.containAny(containsAny);
|
||||||
if (res != null){
|
if (res != null){
|
||||||
res.and(spec);
|
res = res.and(spec);
|
||||||
|
} else {
|
||||||
|
res = spec;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!offers.isEmpty()){
|
||||||
|
spec = buildOffersSpec(vendors);
|
||||||
|
if (res != null){
|
||||||
|
res = res.and(spec);
|
||||||
} else {
|
} else {
|
||||||
res = spec;
|
res = spec;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (andSpec != null){
|
if (andSpec != null){
|
||||||
if (res != null){
|
if (res != null){
|
||||||
res.and(andSpec);
|
res = res.and(andSpec);
|
||||||
} else {
|
} else {
|
||||||
res = andSpec;
|
res = andSpec;
|
||||||
}
|
}
|
||||||
@@ -109,8 +134,8 @@ public class CrawlerSpecificator {
|
|||||||
return (VendorsCrawlerSpecification) crawlerSpecification;
|
return (VendorsCrawlerSpecification) crawlerSpecification;
|
||||||
}
|
}
|
||||||
|
|
||||||
public VendorsCrawlerSpecification build(Consumer<List<Edge<Vendor>>> onFoundFunc){
|
public VendorsCrawlerSpecification build(Collection<Vendor> vendors, Consumer<List<Edge<Vendor>>> onFoundFunc){
|
||||||
return build(onFoundFunc, null, false);
|
return build(vendors, onFoundFunc, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,6 +76,10 @@ public class Route implements Comparable<Route> {
|
|||||||
return profit / time;
|
return profit / time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int getJumps(){
|
||||||
|
return entries.size();
|
||||||
|
}
|
||||||
|
|
||||||
public void add(RouteEntry entry){
|
public void add(RouteEntry entry){
|
||||||
LOG.trace("Add entry {} to route {}", entry, this);
|
LOG.trace("Add entry {} to route {}", entry, this);
|
||||||
entries.add(entry);
|
entries.add(entry);
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ public class RouteSearcher {
|
|||||||
vGraph.build(source, vendors);
|
vGraph.build(source, vendors);
|
||||||
LOG.trace("Graph is builds");
|
LOG.trace("Graph is builds");
|
||||||
RouteCollector collector = new RouteCollector();
|
RouteCollector collector = new RouteCollector();
|
||||||
Crawler<Vendor> crawler = vGraph.crawler(specificator.build(collector::add), callback);
|
Crawler<Vendor> crawler = vGraph.crawler(specificator.build(vendors, collector::add), callback);
|
||||||
crawler.setMaxSize(scorer.getProfile().getLands());
|
crawler.setMaxSize(scorer.getProfile().getLands());
|
||||||
crawler.findMin(target, count);
|
crawler.findMin(target, count);
|
||||||
return collector.get();
|
return collector.get();
|
||||||
@@ -117,10 +117,10 @@ public class RouteSearcher {
|
|||||||
LOG.trace("Graph is builds");
|
LOG.trace("Graph is builds");
|
||||||
RouteCollector collector = new RouteCollector();
|
RouteCollector collector = new RouteCollector();
|
||||||
specificator.setGroupCount(vendors.size());
|
specificator.setGroupCount(vendors.size());
|
||||||
Crawler<Vendor> crawler = vGraph.crawler(specificator.build(collector::add, new LoopRouteSpecification<>(true), true), callback);
|
Crawler<Vendor> crawler = vGraph.crawler(specificator.build(vendors, collector::add, new LoopRouteSpecification<>(true), true), callback);
|
||||||
crawler.setMaxSize(scorer.getProfile().getLands());
|
crawler.setMaxSize(scorer.getProfile().getLands());
|
||||||
crawler.findMin(source, vendors.size());
|
crawler.findMin(source, vendors.size());
|
||||||
crawler = vGraph.crawler(specificator.build(collector::add, new RouteSpecificationByTarget<>(source), false), callback);
|
crawler = vGraph.crawler(specificator.build(vendors, collector::add, new RouteSpecificationByTarget<>(source), false), callback);
|
||||||
crawler.setMaxSize(scorer.getProfile().getLands());
|
crawler.setMaxSize(scorer.getProfile().getLands());
|
||||||
crawler.findMin(source, 1);
|
crawler.findMin(source, 1);
|
||||||
List<Route> routes = collector.get();
|
List<Route> routes = collector.get();
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public class RouteSpecificationByTargets<T> implements RouteSpecification<T> {
|
|||||||
Collection<T> set = new ArrayList<>(targets.size());
|
Collection<T> set = new ArrayList<>(targets.size());
|
||||||
set.add(obj);
|
set.add(obj);
|
||||||
entry.routeIterator().forEachRemaining(e -> set.add(e.getTarget().getEntry()));
|
entry.routeIterator().forEachRemaining(e -> set.add(e.getTarget().getEntry()));
|
||||||
return targets.containsAll(set);
|
return set.containsAll(targets);
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean containsAny(Edge<T> edge, Traversal<T> entry) {
|
private boolean containsAny(Edge<T> edge, Traversal<T> entry) {
|
||||||
|
|||||||
@@ -0,0 +1,216 @@
|
|||||||
|
package ru.trader.analysis;
|
||||||
|
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import ru.trader.analysis.graph.Crawler;
|
||||||
|
import ru.trader.core.*;
|
||||||
|
import ru.trader.store.simple.SimpleOffer;
|
||||||
|
import ru.trader.store.simple.Store;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
public class CrawlerSpecificatorTest extends Assert{
|
||||||
|
private final static Logger LOG = LoggerFactory.getLogger(CrawlerSpecificatorTest.class);
|
||||||
|
|
||||||
|
private VendorsGraph vGraph;
|
||||||
|
private List<Vendor> vendors;
|
||||||
|
|
||||||
|
private Vendor ithaca_st;
|
||||||
|
private Vendor lhs3262_st;
|
||||||
|
private Vendor morgor_st;
|
||||||
|
private Vendor lhs3006_st;
|
||||||
|
private Vendor aulin_st;
|
||||||
|
private Vendor cmDraco_st;
|
||||||
|
private Vendor ovid_st;
|
||||||
|
private Vendor aulis_st;
|
||||||
|
|
||||||
|
private Item gold;
|
||||||
|
private Item personalweapons;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
InputStream is = getClass().getResourceAsStream("/world.xml");
|
||||||
|
Market world = Store.loadFromFile(is);
|
||||||
|
gold = world.getItem("gold");
|
||||||
|
personalweapons = world.getItem("personalweapons");
|
||||||
|
Place ithaca = world.get("Ithaca");
|
||||||
|
Place lhs3262 = world.get("LHS 3262");
|
||||||
|
Place morgor = world.get("Morgor");
|
||||||
|
Place lhs3006 = world.get("LHS 3006");
|
||||||
|
Place ovid = world.get("Ovid");
|
||||||
|
Place aulin = world.get("Aulin");
|
||||||
|
Place cmDraco = world.get("CM Draco");
|
||||||
|
Place aulis = world.get("Aulis");
|
||||||
|
|
||||||
|
ithaca_st = ithaca.get().iterator().next();
|
||||||
|
lhs3262_st = lhs3262.get().iterator().next();
|
||||||
|
morgor_st = morgor.get().iterator().next();
|
||||||
|
lhs3006_st = lhs3006.get().iterator().next();
|
||||||
|
aulin_st = aulin.get().iterator().next();
|
||||||
|
cmDraco_st = cmDraco.get().iterator().next();
|
||||||
|
ovid_st = ovid.get().iterator().next();
|
||||||
|
aulis_st = aulis.get().iterator().next();
|
||||||
|
|
||||||
|
MarketFilter filter = new MarketFilter();
|
||||||
|
FilteredMarket fWorld = new FilteredMarket(world, filter);
|
||||||
|
|
||||||
|
Ship ship = new Ship();
|
||||||
|
ship.setCargo(440); ship.setTank(15);
|
||||||
|
ship.setEngine(5, 'A'); ship.setMass(466);
|
||||||
|
Profile profile = new Profile(ship);
|
||||||
|
profile.setBalance(6000000); profile.setJumps(6);
|
||||||
|
profile.setRoutesCount(100); profile.setLands(3);
|
||||||
|
|
||||||
|
Scorer scorer = new Scorer(fWorld, profile);
|
||||||
|
LOG.info("Build vendors graph");
|
||||||
|
vGraph = new VendorsGraph(scorer, new AnalysisCallBack());
|
||||||
|
vendors = fWorld.getMarkets(true).collect(Collectors.toList());
|
||||||
|
Vendor ithaca_st = ithaca.get().iterator().next();
|
||||||
|
vGraph.build(ithaca_st, vendors);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testContainAll() throws Exception {
|
||||||
|
LOG.info("Test contain all");
|
||||||
|
List<Route> paths = new ArrayList<>();
|
||||||
|
CrawlerSpecificator specificator = new CrawlerSpecificator();
|
||||||
|
specificator.add(cmDraco_st, true);
|
||||||
|
specificator.add(aulin_st, true);
|
||||||
|
VendorsCrawlerSpecification spec = specificator.build(vendors, edges -> {paths.add(RouteSearcher.toRoute(edges, vGraph.getScorer()));});
|
||||||
|
|
||||||
|
Crawler<Vendor> crawler = vGraph.crawler(spec, new AnalysisCallBack());
|
||||||
|
crawler.setMaxSize(3);
|
||||||
|
crawler.findMin(lhs3262_st, 10);
|
||||||
|
assertEquals(10, paths.size());
|
||||||
|
for (Route path : paths) {
|
||||||
|
assertTrue(path.contains(Arrays.asList(cmDraco_st, aulin_st)));
|
||||||
|
}
|
||||||
|
paths.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAny() throws Exception {
|
||||||
|
LOG.info("Test any");
|
||||||
|
List<Route> paths = new ArrayList<>();
|
||||||
|
CrawlerSpecificator specificator = new CrawlerSpecificator();
|
||||||
|
specificator.add(morgor_st, false);
|
||||||
|
specificator.add(lhs3006_st, false);
|
||||||
|
VendorsCrawlerSpecification spec = specificator.build(vendors, edges -> {paths.add(RouteSearcher.toRoute(edges, vGraph.getScorer()));});
|
||||||
|
|
||||||
|
Crawler<Vendor> crawler = vGraph.crawler(spec, new AnalysisCallBack());
|
||||||
|
crawler.setMaxSize(3);
|
||||||
|
crawler.findMin(lhs3262_st, 10);
|
||||||
|
assertEquals(10, paths.size());
|
||||||
|
for (Route path : paths) {
|
||||||
|
Vendor target = path.get(path.getJumps()-1).getVendor();
|
||||||
|
assertTrue(target == morgor_st || target == lhs3006_st);
|
||||||
|
}
|
||||||
|
paths.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testContainAny() throws Exception {
|
||||||
|
LOG.info("Test contain any");
|
||||||
|
List<Route> paths = new ArrayList<>();
|
||||||
|
CrawlerSpecificator specificator = new CrawlerSpecificator();
|
||||||
|
specificator.any(Arrays.asList(aulin_st, morgor_st, lhs3006_st));
|
||||||
|
VendorsCrawlerSpecification spec = specificator.build(vendors, edges -> {paths.add(RouteSearcher.toRoute(edges, vGraph.getScorer()));});
|
||||||
|
|
||||||
|
Crawler<Vendor> crawler = vGraph.crawler(spec, new AnalysisCallBack());
|
||||||
|
crawler.setMaxSize(3);
|
||||||
|
crawler.findMin(lhs3262_st, 10);
|
||||||
|
assertEquals(10, paths.size());
|
||||||
|
for (Route path : paths) {
|
||||||
|
boolean contain = path.contains(Arrays.asList(aulin_st)) ||
|
||||||
|
path.contains(Arrays.asList(morgor_st)) ||
|
||||||
|
path.contains(Arrays.asList(lhs3006_st));
|
||||||
|
|
||||||
|
assertTrue(contain);
|
||||||
|
}
|
||||||
|
paths.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testContainAllAny() throws Exception {
|
||||||
|
LOG.info("Test contain all and any target");
|
||||||
|
List<Route> paths = new ArrayList<>();
|
||||||
|
CrawlerSpecificator specificator = new CrawlerSpecificator();
|
||||||
|
specificator.add(cmDraco_st, true);
|
||||||
|
specificator.add(aulin_st, true);
|
||||||
|
specificator.add(morgor_st, false);
|
||||||
|
specificator.add(lhs3006_st, false);
|
||||||
|
VendorsCrawlerSpecification spec = specificator.build(vendors, edges -> {paths.add(RouteSearcher.toRoute(edges, vGraph.getScorer()));});
|
||||||
|
|
||||||
|
Crawler<Vendor> crawler = vGraph.crawler(spec, new AnalysisCallBack());
|
||||||
|
crawler.setMaxSize(3);
|
||||||
|
crawler.findMin(lhs3262_st, 10);
|
||||||
|
assertEquals(4, paths.size());
|
||||||
|
for (Route path : paths) {
|
||||||
|
assertTrue(path.contains(Arrays.asList(cmDraco_st, aulin_st)));
|
||||||
|
Vendor target = path.get(path.getJumps()-1).getVendor();
|
||||||
|
assertTrue(target == morgor_st || target == lhs3006_st);
|
||||||
|
}
|
||||||
|
paths.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testOffers() throws Exception {
|
||||||
|
LOG.info("Test offer");
|
||||||
|
List<Route> paths = new ArrayList<>();
|
||||||
|
CrawlerSpecificator specificator = new CrawlerSpecificator();
|
||||||
|
Offer goldOffer = new SimpleOffer(OFFER_TYPE.BUY, gold, 0, 30);
|
||||||
|
Offer weaponOffer = new SimpleOffer(OFFER_TYPE.BUY, personalweapons, 0, 100);
|
||||||
|
specificator.buy(Arrays.asList(goldOffer, weaponOffer));
|
||||||
|
VendorsCrawlerSpecification spec = specificator.build(vendors, edges -> {paths.add(RouteSearcher.toRoute(edges, vGraph.getScorer()));});
|
||||||
|
|
||||||
|
Crawler<Vendor> crawler = vGraph.crawler(spec, new AnalysisCallBack());
|
||||||
|
crawler.setMaxSize(3);
|
||||||
|
crawler.findMin(lhs3262_st, 10);
|
||||||
|
assertEquals(10, paths.size());
|
||||||
|
for (Route path : paths) {
|
||||||
|
Collection<Vendor> vs = path.getVendors();
|
||||||
|
assertTrue(vs.stream().anyMatch(v -> v.hasSell(gold)) || vs.stream().anyMatch(v -> v.hasSell(personalweapons)));
|
||||||
|
}
|
||||||
|
paths.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testFull() throws Exception {
|
||||||
|
LOG.info("Test full");
|
||||||
|
List<Route> paths = new ArrayList<>();
|
||||||
|
CrawlerSpecificator specificator = new CrawlerSpecificator();
|
||||||
|
specificator.add(cmDraco_st, true);
|
||||||
|
specificator.add(aulin_st, true);
|
||||||
|
specificator.add(lhs3262_st, false);
|
||||||
|
specificator.add(lhs3006_st, false);
|
||||||
|
specificator.any(Arrays.asList(ovid_st, aulis_st));
|
||||||
|
Offer goldOffer = new SimpleOffer(OFFER_TYPE.BUY, gold, 0, 30);
|
||||||
|
Offer weaponOffer = new SimpleOffer(OFFER_TYPE.BUY, personalweapons, 0, 100);
|
||||||
|
specificator.buy(Arrays.asList(goldOffer, weaponOffer));
|
||||||
|
VendorsCrawlerSpecification spec = specificator.build(vendors, edges -> {paths.add(RouteSearcher.toRoute(edges, vGraph.getScorer()));});
|
||||||
|
|
||||||
|
Crawler<Vendor> crawler = vGraph.crawler(spec, new AnalysisCallBack());
|
||||||
|
crawler.setMaxSize(6);
|
||||||
|
crawler.findMin(ithaca_st, 10);
|
||||||
|
assertEquals(10, paths.size());
|
||||||
|
for (Route path : paths) {
|
||||||
|
Vendor target = path.get(path.getJumps()-1).getVendor();
|
||||||
|
assertTrue(target == lhs3262_st || target == lhs3006_st);
|
||||||
|
Collection<Vendor> vs = path.getVendors();
|
||||||
|
assertTrue(vs.contains(aulis_st)||vs.contains(ovid_st));
|
||||||
|
assertTrue(vs.containsAll(Arrays.asList(cmDraco_st, aulin_st)));
|
||||||
|
assertTrue(vs.stream().anyMatch(v -> v.hasSell(gold)) || vs.stream().anyMatch(v -> v.hasSell(personalweapons)));
|
||||||
|
}
|
||||||
|
paths.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user