TheDarkSaint
TheDarkSaint

Reputation: 457

Is there a way to append or union two constraint streams?

I have a use case where I have to merge two constraint streams into a single constraint stream. In SQL, this would be something like UNION ALL. However, I can't seem to find a way to do so.

While my exact usecase is too large to be practical here, I can try to explain here. We have a portfolio of spectrum rights, representing the exclusive right to use a specific span of radio spectrum in a specific geographic area:

public class SpectrumRight {
   private int geometryId;
   private int lowerFrequency;
   private int upperFrequency;
   ...
}

We also have problem facts representing our existing spectrum rights portfolio

...
@ProblemFactCollectionProperty
public List<SpectrumRight> existingPortfolio;
...

Then we also have a collection of spectrum rights that are up for auction, packaged into a "CallSign" which is basically just a prepackaged collection of spectrum rights (may have different frequencies or different geographic areas):

@PlanningEntity
public class AuctionLicense {
    @PlanningId
    private String callSign;

    @PlanningVariable(...)
    private boolean buy;

    private List<SpectrumRight> spectrumRights;
    ...
}

Within our constraint stream, I'm trying to aggregate all of the spectrum rights that are in the existing portfolio, combined with all of the spectrum rights conveyed in the licenses that get purchased in the auction, in order to compute some metrics on the improvement in portfolio spectrum rights.

private Constraint computeAggregatedSpectrum(ConstraintFactory factor) {
    return factory.from(AuctionLicense.class)
             .filter(AuctionLicense::isBuy)
             .map(AuctionLicense::getSpectrumRights)
             .union(SpectrumRights.class) /*<-from existingPortfolio in Solution*/
             .groupBy(toSortedSet())
             .map(MetricsCalculator::computeAggregatedSpectrumMhzPops)
             .reward(...);
}

However, I can't seem to find a way to append or union two ConstraintStreams together. Is there a stream operation that can be used? Or another workaround?

Upvotes: 1

Views: 156

Answers (2)

Mark Wotton
Mark Wotton

Reputation: 642

fwiw this is now working in timefold 1.3.0 https://github.com/TimefoldAI/timefold-solver/issues/356

Upvotes: 1

Geoffrey De Smet
Geoffrey De Smet

Reputation: 27312

This sounds like an API gap.

Given a stream s1 of about-to-be-bought spectrum rights [A, B, C] and a stream s2 of existing spectrum rights [D, E]:

  • a join() of both s1.join(s2) would give a stream of [ {A,D}, {A,E}, {B,D}, {B,E}, {C,D}, {C,E} ] which is not what you need.
  • a concat(), union() or whatever we call it, doing s1.union(s2) would need to return [A, B, C, D, E]. This operation doesn't exist yet in the current ConstraintStreams API.

Let's create a jira.

Upvotes: 2

Related Questions