1 /*
2  *  Make.org Core API
3  *  Copyright (C) 2018 Make.org
4  *
5  * This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU Affero General Public License as
7  *  published by the Free Software Foundation, either version 3 of the
8  *  License, or (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU Affero General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Affero General Public License
16  *  along with this program.  If not, see <https://www.gnu.org/licenses/>.
17  *
18  */
19 
20 package org.make.api.sequence
21 
22 import org.make.api.proposal.ProposalScorer
23 import org.make.api.proposal.ProposalScorer.VotesCounter
24 import org.make.api.technical.MakeRandom
25 import org.make.core.DateHelper._
26 import org.make.core.proposal.ProposalKeywordKey
27 import org.make.core.proposal.indexed.Zone.{Consensus, Controversy}
28 import org.make.core.proposal.indexed.{IndexedProposal, Zone}
29 import org.make.core.sequence.{
30   ExplorationSequenceConfiguration,
31   ExplorationSortAlgorithm,
32   SpecificSequenceConfiguration
33 }
34 import org.make.core.sequence.ExplorationSequenceConfiguration.SequenceThresholds
35 import org.make.core.technical.CollectionUtils.ImprovedSeq
36 import org.make.core.technical.RefinedTypes.Ratio
37 import eu.timepit.refined.auto._
38 
39 import scala.Ordering.Double.IeeeOrdering
40 import scala.annotation.tailrec
41 import scala.collection.mutable.{HashSet => MSet}
42 
43 object SelectionAlgorithm {
44 
45   object ExplorationSelectionAlgorithm {
46     def selectProposalsForSequence(
47       configuration: ExplorationSequenceConfiguration,
48       nonSequenceVotesWeight: Double,
49       includedProposals: Seq[IndexedProposal],
50       newProposals: Seq[IndexedProposal],
51       testedProposals: Seq[IndexedProposal],
52       userSegment: Option[String]
53     ): Seq[IndexedProposal] = {
54 
55       // Choose new proposals first and complete with enough tested proposals.
56       // this setting will give more sequence fallbacks in the beginning of consultations
57       // but should remove the need of fallback in the end of consultations, in the "vote-only" phase
58       val chosenNewProposals: Seq[IndexedProposal] = chooseNewProposals(configuration, includedProposals, newProposals)
59 
60       val testedProposalsConfiguration = createTestedProposalsConfiguration(
61         configuration,
62         nonSequenceVotesWeight,
63         includedProposals,
64         userSegment,
65         chosenNewProposals.size
66       )
67 
68       val deDuplicatedTestedProposals = removeAuthorDuplication(chosenNewProposals, testedProposals)
69       val chosenTestedProposals = chooseTestedProposal(deDuplicatedTestedProposals, testedProposalsConfiguration)
70 
71       includedProposals ++ MakeRandom.shuffleSeq(chosenNewProposals ++ chosenTestedProposals)
72     }
73 
74     private def chooseNewProposals(
75       configuration: ExplorationSequenceConfiguration,
76       includedProposals: Seq[IndexedProposal],
77       newProposals: Seq[IndexedProposal]
78     ): Seq[IndexedProposal] = {
79       val availableSpace = configuration.sequenceSize - includedProposals.size
80       val neededNewProposals = Math.ceil(configuration.newRatio * availableSpace).toInt
81 
82       NewProposalsChooser.choose(newProposals, neededNewProposals)
83     }
84 
85     private def createTestedProposalsConfiguration(
86       configuration: ExplorationSequenceConfiguration,
87       nonSequenceVotesWeight: Double,
88       includedProposals: Seq[IndexedProposal],
89       userSegment: Option[String],
90       chosenNewProposalsCount: Int
91     ): TestedProposalsSelectionConfiguration = {
92       val votesCounter: VotesCounter = if (userSegment.isDefined) {
93         VotesCounter.SegmentVotesCounter
94       } else {
95         VotesCounter.SequenceVotesCounter
96       }
97 
98       val neededTested = Math.max(configuration.sequenceSize - chosenNewProposalsCount - includedProposals.size, 0)
99       val neededControversies: Int = Math.round(neededTested * configuration.controversyRatio).toInt
100       val neededTops = neededTested - neededControversies
101 
102       val controversySorter = Sorter.parse(configuration.controversySorter)
103       val topSorter = Sorter.parse(configuration.topSorter)
104 
105       TestedProposalsSelectionConfiguration(
106         votesCounter = votesCounter,
107         ratio = nonSequenceVotesWeight,
108         neededControversies = neededControversies,
109         controversySorter = controversySorter,
110         neededTops = neededTops,
111         topSorter = topSorter,
112         keywordsThreshold = configuration.keywordsThreshold,
113         candidatesPoolSize = configuration.candidatesPoolSize,
114         sequenceThreshold = configuration.sequenceThresholds
115       )
116     }
117 
118     @SuppressWarnings(Array("org.wartremover.warts.MutableDataStructures"))
119     def resolveIgnoredKeywords(proposals: Seq[IndexedProposal], keywordsThreshold: Ratio): MSet[ProposalKeywordKey] = {
120       if (proposals.isEmpty) {
121         MSet.empty
122       } else {
123         val maxOccurrences = Math.floor(keywordsThreshold * proposals.size).toInt
124         proposals
125           .flatMap(_.keywords)
126           .countOccurencesBy[ProposalKeywordKey](_.key)
127           .collect {
128             case (key, occurences) if occurences >= maxOccurrences => key
129           }
130           .to(MSet)
131       }
132     }
133 
134     private def chooseTestedProposal(
135       testedProposals: Seq[IndexedProposal],
136       configuration: TestedProposalsSelectionConfiguration
137     ): Seq[IndexedProposal] = {
138       val (tops, controversies) =
139         testedProposals
140           .zip(
141             testedProposals
142               .map(proposal => {
143                 ProposalScorer(proposal.votes, configuration.votesCounter, configuration.ratio)
144               })
145           )
146           .collect({
147             case (proposal, scorer) if scorer.sampledZone(configuration.sequenceThreshold) == Consensus =>
148               ZonedProposal(proposal, Consensus, scorer.topScore.sample)
149             case (proposal, scorer) if scorer.sampledZone(configuration.sequenceThreshold) == Controversy =>
150               ZonedProposal(proposal, Controversy, scorer.controversy.sample)
151           })
152           .partition(_.zone == Consensus)
153 
154       // Applying the different selection algorithms consists in sorting the proposals in some order,
155       // and then take enough of them, using the same de-duplication + equalizer everytime.
156 
157       val sortedControversies = configuration.controversySorter.sort(controversies)
158       val sortedTops = configuration.topSorter.sort(tops)
159 
160       val ignoredKeywords = resolveIgnoredKeywords(testedProposals, configuration.keywordsThreshold)
161 
162       val chosenControversies = TestedProposalsChooser.choose(
163         sortedControversies,
164         configuration.neededControversies,
165         ignoredKeywords,
166         configuration.candidatesPoolSize
167       )
168       val availableTops = removeAuthorDuplication(chosenControversies, sortedTops)
169       chosenControversies ++
170         TestedProposalsChooser.choose(
171           availableTops,
172           configuration.neededTops,
173           ignoredKeywords,
174           configuration.candidatesPoolSize
175         )
176     }
177 
178     @SuppressWarnings(Array("org.wartremover.warts.MutableDataStructures"))
179     private def removeAuthorDuplication(
180       chosenProposals: Seq[IndexedProposal],
181       candidates: Seq[IndexedProposal]
182     ): Seq[IndexedProposal] = {
183       val chosenAuthors = chosenProposals.map(_.author.userId).to(MSet)
184       candidates.filterNot(p => chosenAuthors.contains(p.author.userId))
185     }
186 
187     final case class TestedProposalsSelectionConfiguration(
188       votesCounter: VotesCounter,
189       ratio: Double,
190       neededControversies: Int,
191       controversySorter: Sorter,
192       neededTops: Int,
193       topSorter: Sorter,
194       keywordsThreshold: Ratio,
195       candidatesPoolSize: Int,
196       sequenceThreshold: SequenceThresholds
197     )
198 
199     final case class ZonedProposal(proposal: IndexedProposal, zone: Zone, score: Double)
200 
201     sealed trait Sorter {
202       def sort(proposals: Seq[ZonedProposal]): Seq[IndexedProposal]
203     }
204 
205     object Sorter {
206       def parse(name: ExplorationSortAlgorithm): Sorter = {
207         name match {
208           case ExplorationSortAlgorithm.Bandit    => BanditSorter
209           case ExplorationSortAlgorithm.Equalizer => EqualizerSorter
210           case ExplorationSortAlgorithm.Random    => RandomSorter
211         }
212       }
213     }
214 
215     object BanditSorter extends Sorter {
216       override def sort(proposals: Seq[ZonedProposal]): Seq[IndexedProposal] = {
217         proposals.sortBy(-_.score).map(_.proposal)
218       }
219     }
220 
221     object RandomSorter extends Sorter {
222       override def sort(proposals: Seq[ZonedProposal]): Seq[IndexedProposal] = {
223         MakeRandom.shuffleSeq(proposals).map(_.proposal)
224       }
225     }
226 
227     object EqualizerSorter extends Sorter {
228       override def sort(proposals: Seq[ZonedProposal]): Seq[IndexedProposal] = {
229         proposals.map(_.proposal).sortBy(_.votesSequenceCount)
230       }
231     }
232 
233     object NewProposalsChooser {
234       def choose(candidates: Seq[IndexedProposal], neededCount: Int): Seq[IndexedProposal] = {
235         candidates.sortBy(_.createdAt).distinctBy(_.author.userId).take(neededCount)
236       }
237     }
238 
239     object TestedProposalsChooser {
240 
241       /**
242         * Chooses some proposals in a sorted list of proposals and preserve a few properties:
243         * - no keyword duplication in the list (ie. a given keyword should appear only once)
244         * - no author duplication in the list
245         * - proposals with fewer votes will be boosted (see below)
246         *
247         * In order to boost the proposals with fewer votes, instead of taking the first element of the list,
248         * the one with the fewest number of sequence votes in the 10 first proposals is chosen.
249         * The proposal pool is then cleaned of proposals sharing any keyword / author with that proposal
250         * before choosing the next proposal.
251         *
252         * @param candidates the whole pool of proposals from which to choose
253         * @param neededCount the target number of proposals needed
254         * @param ignoredKeywords keywords that shouldn't be used to deduplicate proposals
255         * @return a list consisting of at most the required number of proposals, without any duplication.
256         *         The result can be empty or contain fewer elements than required.
257         */
258       def choose(
259         candidates: Seq[IndexedProposal],
260         neededCount: Int,
261         ignoredKeywords: MSet[ProposalKeywordKey],
262         candidatesPoolSize: Int
263       ): Seq[IndexedProposal] = {
264         chooseRecursively(List.empty, candidates, neededCount, ignoredKeywords, candidatesPoolSize)
265       }
266 
267       @tailrec
268       private def chooseRecursively(
269         accumulator: List[IndexedProposal],
270         candidates: Seq[IndexedProposal],
271         neededCount: Int,
272         ignoredKeywords: MSet[ProposalKeywordKey],
273         candidatesPoolSize: Int
274       ): Seq[IndexedProposal] = {
275         if (neededCount <= 0) {
276           accumulator
277         } else {
278           candidates.take(candidatesPoolSize).minByOption(_.votesSequenceCount) match {
279             case None => accumulator
280             case Some(chosen) =>
281               val newAccumulator = chosen :: accumulator
282               if (neededCount <= 1) {
283                 newAccumulator
284               } else {
285                 chooseRecursively(
286                   accumulator = newAccumulator,
287                   candidates = deduplicate(chosen, candidates, ignoredKeywords),
288                   neededCount = neededCount - 1,
289                   ignoredKeywords,
290                   candidatesPoolSize
291                 )
292               }
293           }
294         }
295       }
296 
297       @SuppressWarnings(Array("org.wartremover.warts.MutableDataStructures"))
298       private def deduplicate(
299         chosen: IndexedProposal,
300         candidates: Seq[IndexedProposal],
301         ignoredKeywords: MSet[ProposalKeywordKey]
302       ): Seq[IndexedProposal] = {
303         val forbiddenKeywords = chosen.keywords.filterNot(k => ignoredKeywords.contains(k.key)).to(MSet)
304         candidates.filter { proposal =>
305           !proposal.keywords.exists(forbiddenKeywords.contains) && chosen.author.userId != proposal.author.userId
306         }
307       }
308     }
309   }
310 
311   object RoundRobinSelectionAlgorithm {
312 
313     /*
314     Returns the list of proposal to display in the sequence
315     The proposals are chosen such that:
316     - if they are imposed proposals (includeList) they will appear first
317     - the rest is only new proposals to test (less than newProposalVoteCount votes)
318     - new proposals are tested in a round robin mode until they reach newProposalVoteCount votes
319     - tested proposals are filtered out if their engagement rate is too low
320     - the non imposed proposals are ordered randomly
321      */
322     def selectProposalsForSequence(
323       sequenceConfiguration: SpecificSequenceConfiguration,
324       includedProposals: Seq[IndexedProposal],
325       newProposals: Seq[IndexedProposal],
326       testedProposals: Seq[IndexedProposal]
327     ): Seq[IndexedProposal] = {
328 
329       val proposalsPool: Seq[IndexedProposal] = newProposals ++ testedProposals
330 
331       // balance proposals between new and tested
332       val sequenceSize: Int = sequenceConfiguration.sequenceSize
333       val includedSize: Int = includedProposals.size
334 
335       val proposalsToChoose: Int = sequenceSize - includedSize
336 
337       val proposals = proposalsPool.sortBy(_.votesSequenceCount).take(proposalsToChoose)
338 
339       includedProposals ++ MakeRandom.shuffleSeq(proposals)
340     }
341 
342   }
343 
344   object RandomSelectionAlgorithm {
345 
346     def selectProposalsForSequence(
347       sequenceConfiguration: SpecificSequenceConfiguration,
348       includedProposals: Seq[IndexedProposal],
349       newProposals: Seq[IndexedProposal],
350       testedProposals: Seq[IndexedProposal]
351     ): Seq[IndexedProposal] = {
352 
353       val excludedIds = includedProposals.map(_.id)
354       val candidates = (newProposals ++ testedProposals)
355         .filter(p => !excludedIds.contains(p.id))
356       val shuffled = MakeRandom.shuffleSeq(candidates)
357       includedProposals ++ shuffled.take(sequenceConfiguration.sequenceSize - includedProposals.size)
358     }
359   }
360 }
Line Stmt Id Pos Tree Symbol Tests Code
58 30114 2335 - 2401 Apply org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.chooseNewProposals org.make.api.sequence.sequencesimulationtest ExplorationSelectionAlgorithm.this.chooseNewProposals(configuration, includedProposals, newProposals)
60 28457 2444 - 2622 Apply org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.createTestedProposalsConfiguration org.make.api.sequence.sequencesimulationtest ExplorationSelectionAlgorithm.this.createTestedProposalsConfiguration(configuration, nonSequenceVotesWeight, includedProposals, userSegment, chosenNewProposals.size)
65 29260 2591 - 2614 Select scala.collection.SeqOps.size org.make.api.sequence.sequencesimulationtest chosenNewProposals.size
68 29809 2664 - 2724 Apply org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.removeAuthorDuplication org.make.api.sequence.sequencesimulationtest ExplorationSelectionAlgorithm.this.removeAuthorDuplication(chosenNewProposals, testedProposals)
69 29407 2759 - 2838 Apply org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.chooseTestedProposal org.make.api.sequence.sequencesimulationtest ExplorationSelectionAlgorithm.this.chooseTestedProposal(deDuplicatedTestedProposals, testedProposalsConfiguration)
71 29148 2846 - 2933 Apply scala.collection.IterableOps.++ org.make.api.sequence.sequencesimulationtest includedProposals.++[org.make.core.proposal.indexed.IndexedProposal](org.make.api.technical.MakeRandom.shuffleSeq[org.make.core.proposal.indexed.IndexedProposal](chosenNewProposals.++[org.make.core.proposal.indexed.IndexedProposal](chosenTestedProposals)))
71 28669 2889 - 2932 Apply scala.collection.IterableOps.++ org.make.api.sequence.sequencesimulationtest chosenNewProposals.++[org.make.core.proposal.indexed.IndexedProposal](chosenTestedProposals)
71 29949 2867 - 2933 Apply org.make.api.technical.MakeRandom.shuffleSeq org.make.api.sequence.sequencesimulationtest org.make.api.technical.MakeRandom.shuffleSeq[org.make.core.proposal.indexed.IndexedProposal](chosenNewProposals.++[org.make.core.proposal.indexed.IndexedProposal](chosenTestedProposals))
79 29361 3208 - 3230 Select scala.collection.SeqOps.size org.make.api.sequence.sequencesimulationtest includedProposals.size
79 28430 3179 - 3230 Apply scala.Int.- org.make.api.sequence.sequencesimulationtest eu.timepit.refined.auto.autoUnwrap[eu.timepit.refined.api.Refined, Int, eu.timepit.refined.numeric.Positive](configuration.sequenceSize)(api.this.RefType.refinedRefType).-(includedProposals.size)
79 28307 3179 - 3205 Select org.make.core.sequence.ExplorationSequenceConfiguration.sequenceSize org.make.api.sequence.sequencesimulationtest configuration.sequenceSize
79 30118 3193 - 3193 Select eu.timepit.refined.api.RefType.refinedRefType org.make.api.sequence.sequencesimulationtest api.this.RefType.refinedRefType
80 29379 3262 - 3318 Select scala.Double.toInt org.make.api.sequence.sequencesimulationtest java.lang.Math.ceil(eu.timepit.refined.auto.autoUnwrap[eu.timepit.refined.api.Refined, Double, eu.timepit.refined.numeric.Interval.Closed[Int(0),Int(1)]](configuration.newRatio)(api.this.RefType.refinedRefType).*(availableSpace)).toInt
80 29814 3272 - 3311 Apply scala.Double.* org.make.api.sequence.sequencesimulationtest eu.timepit.refined.auto.autoUnwrap[eu.timepit.refined.api.Refined, Double, eu.timepit.refined.numeric.Interval.Closed[Int(0),Int(1)]](configuration.newRatio)(api.this.RefType.refinedRefType).*(availableSpace)
82 28540 3326 - 3386 Apply org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.NewProposalsChooser.choose org.make.api.sequence.sequencesimulationtest ExplorationSelectionAlgorithm.this.NewProposalsChooser.choose(newProposals, neededNewProposals)
92 30051 3748 - 3769 Select scala.Option.isDefined org.make.api.sequence.sequencesimulationtest userSegment.isDefined
93 29177 3781 - 3813 Select org.make.api.proposal.ProposalScorer.VotesCounter.SegmentVotesCounter org.make.api.proposal.ProposalScorer.VotesCounter.SegmentVotesCounter
93 28312 3781 - 3813 Block org.make.api.proposal.ProposalScorer.VotesCounter.SegmentVotesCounter org.make.api.proposal.ProposalScorer.VotesCounter.SegmentVotesCounter
95 29228 3837 - 3870 Block org.make.api.proposal.ProposalScorer.VotesCounter.SequenceVotesCounter org.make.api.sequence.sequencesimulationtest org.make.api.proposal.ProposalScorer.VotesCounter.SequenceVotesCounter
95 30173 3837 - 3870 Select org.make.api.proposal.ProposalScorer.VotesCounter.SequenceVotesCounter org.make.api.sequence.sequencesimulationtest org.make.api.proposal.ProposalScorer.VotesCounter.SequenceVotesCounter
98 28654 3914 - 3991 Apply scala.Int.- org.make.api.sequence.sequencesimulationtest eu.timepit.refined.auto.autoUnwrap[eu.timepit.refined.api.Refined, Int, eu.timepit.refined.numeric.Positive](configuration.sequenceSize)(api.this.RefType.refinedRefType).-(chosenNewProposalsCount).-(includedProposals.size)
98 29024 3969 - 3991 Select scala.collection.SeqOps.size org.make.api.sequence.sequencesimulationtest includedProposals.size
98 28399 3914 - 3940 Select org.make.core.sequence.ExplorationSequenceConfiguration.sequenceSize org.make.api.sequence.sequencesimulationtest configuration.sequenceSize
98 29882 3928 - 3928 Select eu.timepit.refined.api.RefType.refinedRefType org.make.api.sequence.sequencesimulationtest api.this.RefType.refinedRefType
98 29185 3905 - 3995 Apply java.lang.Math.max org.make.api.sequence.sequencesimulationtest java.lang.Math.max(eu.timepit.refined.auto.autoUnwrap[eu.timepit.refined.api.Refined, Int, eu.timepit.refined.numeric.Positive](configuration.sequenceSize)(api.this.RefType.refinedRefType).-(chosenNewProposalsCount).-(includedProposals.size), 0)
98 29921 3993 - 3994 Literal <nosymbol> org.make.api.sequence.sequencesimulationtest 0
99 30175 4073 - 4073 Select eu.timepit.refined.api.RefType.refinedRefType org.make.api.sequence.sequencesimulationtest api.this.RefType.refinedRefType
99 29887 4033 - 4096 Select scala.Long.toInt org.make.api.sequence.sequencesimulationtest java.lang.Math.round(neededTested.*(eu.timepit.refined.auto.autoUnwrap[eu.timepit.refined.api.Refined, Double, eu.timepit.refined.numeric.Interval.Closed[Int(0),Int(1)]](configuration.controversyRatio)(api.this.RefType.refinedRefType))).toInt
99 28456 4044 - 4089 Apply scala.Int.* org.make.api.sequence.sequencesimulationtest neededTested.*(eu.timepit.refined.auto.autoUnwrap[eu.timepit.refined.api.Refined, Double, eu.timepit.refined.numeric.Interval.Closed[Int(0),Int(1)]](configuration.controversyRatio)(api.this.RefType.refinedRefType))
99 28381 4059 - 4089 Select org.make.core.sequence.ExplorationSequenceConfiguration.controversyRatio org.make.api.sequence.sequencesimulationtest configuration.controversyRatio
99 29332 4059 - 4089 ApplyToImplicitArgs eu.timepit.refined.auto.autoUnwrap org.make.api.sequence.sequencesimulationtest eu.timepit.refined.auto.autoUnwrap[eu.timepit.refined.api.Refined, Double, eu.timepit.refined.numeric.Interval.Closed[Int(0),Int(1)]](configuration.controversyRatio)(api.this.RefType.refinedRefType)
100 29004 4120 - 4154 Apply scala.Int.- org.make.api.sequence.sequencesimulationtest neededTested.-(neededControversies)
102 30015 4186 - 4231 Apply org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.Sorter.parse org.make.api.sequence.sequencesimulationtest ExplorationSelectionAlgorithm.this.Sorter.parse(configuration.controversySorter)
102 28656 4199 - 4230 Select org.make.core.sequence.ExplorationSequenceConfiguration.controversySorter org.make.api.sequence.sequencesimulationtest configuration.controversySorter
103 29145 4267 - 4290 Select org.make.core.sequence.ExplorationSequenceConfiguration.topSorter org.make.api.sequence.sequencesimulationtest configuration.topSorter
103 28384 4254 - 4291 Apply org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.Sorter.parse org.make.api.sequence.sequencesimulationtest ExplorationSelectionAlgorithm.this.Sorter.parse(configuration.topSorter)
105 29850 4299 - 4769 Apply org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.TestedProposalsSelectionConfiguration.apply org.make.api.sequence.sequencesimulationtest ExplorationSelectionAlgorithm.this.TestedProposalsSelectionConfiguration.apply(votesCounter, nonSequenceVotesWeight, neededControversies, controversySorter, neededTops, topSorter, configuration.keywordsThreshold, configuration.candidatesPoolSize, configuration.sequenceThresholds)
112 29714 4605 - 4636 Select org.make.core.sequence.ExplorationSequenceConfiguration.keywordsThreshold org.make.api.sequence.sequencesimulationtest configuration.keywordsThreshold
113 29335 4667 - 4699 Select org.make.core.sequence.ExplorationSequenceConfiguration.candidatesPoolSize org.make.api.sequence.sequencesimulationtest configuration.candidatesPoolSize
114 28459 4729 - 4761 Select org.make.core.sequence.ExplorationSequenceConfiguration.sequenceThresholds org.make.api.sequence.sequencesimulationtest configuration.sequenceThresholds
120 29011 4983 - 5000 Select scala.collection.SeqOps.isEmpty org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest proposals.isEmpty
121 29970 5012 - 5022 Block scala.collection.mutable.HashSet.empty org.make.api.sequence.selectionalgorithmtest scala.collection.mutable.HashSet.empty[org.make.core.proposal.ProposalKeywordKey]
121 28573 5012 - 5022 TypeApply scala.collection.mutable.HashSet.empty org.make.api.sequence.selectionalgorithmtest scala.collection.mutable.HashSet.empty[org.make.core.proposal.ProposalKeywordKey]
122 29328 5036 - 5359 Block <nosymbol> org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest { val maxOccurrences: Int = java.lang.Math.floor(eu.timepit.refined.auto.autoUnwrap[eu.timepit.refined.api.Refined, Double, eu.timepit.refined.numeric.Interval.Closed[Int(0),Int(1)]](keywordsThreshold)(api.this.RefType.refinedRefType).*(proposals.size)).toInt; org.make.core.technical.CollectionUtils.ImprovedSeq[org.make.core.proposal.indexed.IndexedProposalKeyword](proposals.flatMap[org.make.core.proposal.indexed.IndexedProposalKeyword](((x$1: org.make.core.proposal.indexed.IndexedProposal) => x$1.keywords))).countOccurencesBy[org.make.core.proposal.ProposalKeywordKey](((x$2: org.make.core.proposal.indexed.IndexedProposalKeyword) => x$2.key)).collect[org.make.core.proposal.ProposalKeywordKey](({ @SerialVersionUID(value = 0) final <synthetic> class $anonfun extends scala.runtime.AbstractPartialFunction[(org.make.core.proposal.ProposalKeywordKey, Int),org.make.core.proposal.ProposalKeywordKey] with java.io.Serializable { def <init>(): <$anon: ((org.make.core.proposal.ProposalKeywordKey, Int)) => org.make.core.proposal.ProposalKeywordKey> = { $anonfun.super.<init>(); () }; final override def applyOrElse[A1 <: (org.make.core.proposal.ProposalKeywordKey, Int), B1 >: org.make.core.proposal.ProposalKeywordKey](x1: A1, default: A1 => B1): B1 = ((x1.asInstanceOf[(org.make.core.proposal.ProposalKeywordKey, Int)]: (org.make.core.proposal.ProposalKeywordKey, Int)): (org.make.core.proposal.ProposalKeywordKey, Int) @unchecked) match { case (_1: org.make.core.proposal.ProposalKeywordKey, _2: Int): (org.make.core.proposal.ProposalKeywordKey, Int)((key @ _), (occurences @ _)) if occurences.>=(maxOccurrences) => key case (defaultCase$ @ _) => default.apply(x1) }; final def isDefinedAt(x1: (org.make.core.proposal.ProposalKeywordKey, Int)): Boolean = ((x1.asInstanceOf[(org.make.core.proposal.ProposalKeywordKey, Int)]: (org.make.core.proposal.ProposalKeywordKey, Int)): (org.make.core.proposal.ProposalKeywordKey, Int) @unchecked) match { case (_1: org.make.core.proposal.ProposalKeywordKey, _2: Int): (org.make.core.proposal.ProposalKeywordKey, Int)((key @ _), (occurences @ _)) if occurences.>=(maxOccurrences) => true case (defaultCase$ @ _) => false } }; new $anonfun() }: PartialFunction[(org.make.core.proposal.ProposalKeywordKey, Int),org.make.core.proposal.ProposalKeywordKey])).to[scala.collection.mutable.HashSet[org.make.core.proposal.ProposalKeywordKey]](collection.this.IterableFactory.toFactory[org.make.core.proposal.ProposalKeywordKey, [A]scala.collection.mutable.HashSet[A]](scala.collection.mutable.HashSet)) }
123 28272 5098 - 5112 Select scala.collection.SeqOps.size org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest proposals.size
123 29151 5078 - 5078 Select eu.timepit.refined.api.RefType.refinedRefType org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest api.this.RefType.refinedRefType
123 29722 5078 - 5112 Apply scala.Double.* org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest eu.timepit.refined.auto.autoUnwrap[eu.timepit.refined.api.Refined, Double, eu.timepit.refined.numeric.Interval.Closed[Int(0),Int(1)]](keywordsThreshold)(api.this.RefType.refinedRefType).*(proposals.size)
123 29296 5067 - 5119 Select scala.Double.toInt org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest java.lang.Math.floor(eu.timepit.refined.auto.autoUnwrap[eu.timepit.refined.api.Refined, Double, eu.timepit.refined.numeric.Interval.Closed[Int(0),Int(1)]](keywordsThreshold)(api.this.RefType.refinedRefType).*(proposals.size)).toInt
125 28535 5157 - 5167 Select org.make.core.proposal.indexed.IndexedProposal.keywords org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest x$1.keywords
125 29857 5128 - 5168 Apply scala.collection.IterableOps.flatMap org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest proposals.flatMap[org.make.core.proposal.indexed.IndexedProposalKeyword](((x$1: org.make.core.proposal.indexed.IndexedProposal) => x$1.keywords))
126 28971 5218 - 5223 Select org.make.core.proposal.indexed.IndexedProposalKeyword.key org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest x$2.key
127 29918 5244 - 5244 Apply org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.$anonfun.<init> org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest new $anonfun()
128 28579 5284 - 5312 Apply scala.Int.>= org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest occurences.>=(maxOccurrences)
130 28275 5346 - 5350 ApplyImplicitView scala.collection.IterableFactory.toFactory org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest collection.this.IterableFactory.toFactory[org.make.core.proposal.ProposalKeywordKey, [A]scala.collection.mutable.HashSet[A]](scala.collection.mutable.HashSet)
130 29225 5346 - 5350 Select scala.collection.mutable.HashSet org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest scala.collection.mutable.HashSet
130 29676 5128 - 5351 Apply scala.collection.IterableOnceOps.to org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest org.make.core.technical.CollectionUtils.ImprovedSeq[org.make.core.proposal.indexed.IndexedProposalKeyword](proposals.flatMap[org.make.core.proposal.indexed.IndexedProposalKeyword](((x$1: org.make.core.proposal.indexed.IndexedProposal) => x$1.keywords))).countOccurencesBy[org.make.core.proposal.ProposalKeywordKey](((x$2: org.make.core.proposal.indexed.IndexedProposalKeyword) => x$2.key)).collect[org.make.core.proposal.ProposalKeywordKey](({ @SerialVersionUID(value = 0) final <synthetic> class $anonfun extends scala.runtime.AbstractPartialFunction[(org.make.core.proposal.ProposalKeywordKey, Int),org.make.core.proposal.ProposalKeywordKey] with java.io.Serializable { def <init>(): <$anon: ((org.make.core.proposal.ProposalKeywordKey, Int)) => org.make.core.proposal.ProposalKeywordKey> = { $anonfun.super.<init>(); () }; final override def applyOrElse[A1 <: (org.make.core.proposal.ProposalKeywordKey, Int), B1 >: org.make.core.proposal.ProposalKeywordKey](x1: A1, default: A1 => B1): B1 = ((x1.asInstanceOf[(org.make.core.proposal.ProposalKeywordKey, Int)]: (org.make.core.proposal.ProposalKeywordKey, Int)): (org.make.core.proposal.ProposalKeywordKey, Int) @unchecked) match { case (_1: org.make.core.proposal.ProposalKeywordKey, _2: Int): (org.make.core.proposal.ProposalKeywordKey, Int)((key @ _), (occurences @ _)) if occurences.>=(maxOccurrences) => key case (defaultCase$ @ _) => default.apply(x1) }; final def isDefinedAt(x1: (org.make.core.proposal.ProposalKeywordKey, Int)): Boolean = ((x1.asInstanceOf[(org.make.core.proposal.ProposalKeywordKey, Int)]: (org.make.core.proposal.ProposalKeywordKey, Int)): (org.make.core.proposal.ProposalKeywordKey, Int) @unchecked) match { case (_1: org.make.core.proposal.ProposalKeywordKey, _2: Int): (org.make.core.proposal.ProposalKeywordKey, Int)((key @ _), (occurences @ _)) if occurences.>=(maxOccurrences) => true case (defaultCase$ @ _) => false } }; new $anonfun() }: PartialFunction[(org.make.core.proposal.ProposalKeywordKey, Int),org.make.core.proposal.ProposalKeywordKey])).to[scala.collection.mutable.HashSet[org.make.core.proposal.ProposalKeywordKey]](collection.this.IterableFactory.toFactory[org.make.core.proposal.ProposalKeywordKey, [A]scala.collection.mutable.HashSet[A]](scala.collection.mutable.HashSet))
138 29841 5558 - 5558 Select scala.Tuple2._2 org.make.api.sequence.sequencesimulationtest x$4._2
138 28402 5552 - 5552 Select scala.Tuple2._1 org.make.api.sequence.sequencesimulationtest x$4._1
157 28979 6472 - 6523 Apply org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.Sorter.sort org.make.api.sequence.sequencesimulationtest configuration.controversySorter.sort(controversies)
158 30406 6547 - 6581 Apply org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.Sorter.sort org.make.api.sequence.sequencesimulationtest configuration.topSorter.sort(tops)
160 29089 6611 - 6683 Apply org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.resolveIgnoredKeywords org.make.api.sequence.sequencesimulationtest ExplorationSelectionAlgorithm.this.resolveIgnoredKeywords(testedProposals, configuration.keywordsThreshold)
160 30011 6651 - 6682 Select org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.TestedProposalsSelectionConfiguration.keywordsThreshold org.make.api.sequence.sequencesimulationtest configuration.keywordsThreshold
162 29334 6717 - 6893 Apply org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.TestedProposalsChooser.choose org.make.api.sequence.sequencesimulationtest ExplorationSelectionAlgorithm.this.TestedProposalsChooser.choose(sortedControversies, configuration.neededControversies, ignoredKeywords, configuration.candidatesPoolSize)
164 28347 6785 - 6818 Select org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.TestedProposalsSelectionConfiguration.neededControversies org.make.api.sequence.sequencesimulationtest configuration.neededControversies
166 29686 6853 - 6885 Select org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.TestedProposalsSelectionConfiguration.candidatesPoolSize org.make.api.sequence.sequencesimulationtest configuration.candidatesPoolSize
168 28501 6920 - 6976 Apply org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.removeAuthorDuplication org.make.api.sequence.sequencesimulationtest ExplorationSelectionAlgorithm.this.removeAuthorDuplication(chosenControversies, sortedTops)
169 30020 6983 - 7185 Apply scala.collection.IterableOps.++ org.make.api.sequence.sequencesimulationtest chosenControversies.++[org.make.core.proposal.indexed.IndexedProposal](ExplorationSelectionAlgorithm.this.TestedProposalsChooser.choose(availableTops, configuration.neededTops, ignoredKeywords, configuration.candidatesPoolSize))
170 30430 7014 - 7185 Apply org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.TestedProposalsChooser.choose org.make.api.sequence.sequencesimulationtest ExplorationSelectionAlgorithm.this.TestedProposalsChooser.choose(availableTops, configuration.neededTops, ignoredKeywords, configuration.candidatesPoolSize)
172 29847 7080 - 7104 Select org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.TestedProposalsSelectionConfiguration.neededTops org.make.api.sequence.sequencesimulationtest configuration.neededTops
174 29076 7143 - 7175 Select org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.TestedProposalsSelectionConfiguration.candidatesPoolSize org.make.api.sequence.sequencesimulationtest configuration.candidatesPoolSize
183 29315 7452 - 7497 Apply scala.collection.IterableOnceOps.to org.make.api.sequence.sequencesimulationtest chosenProposals.map[org.make.core.user.UserId](((x$5: org.make.core.proposal.indexed.IndexedProposal) => x$5.author.userId)).to[scala.collection.mutable.HashSet[org.make.core.user.UserId]](collection.this.IterableFactory.toFactory[org.make.core.user.UserId, [A]scala.collection.mutable.HashSet[A]](scala.collection.mutable.HashSet))
183 29764 7492 - 7496 ApplyImplicitView scala.collection.IterableFactory.toFactory org.make.api.sequence.sequencesimulationtest collection.this.IterableFactory.toFactory[org.make.core.user.UserId, [A]scala.collection.mutable.HashSet[A]](scala.collection.mutable.HashSet)
183 28352 7492 - 7496 Select scala.collection.mutable.HashSet org.make.api.sequence.sequencesimulationtest scala.collection.mutable.HashSet
183 29194 7472 - 7487 Select org.make.core.proposal.indexed.IndexedAuthor.userId org.make.api.sequence.sequencesimulationtest x$5.author.userId
184 29816 7530 - 7569 Apply scala.collection.mutable.HashSet.contains org.make.api.sequence.sequencesimulationtest chosenAuthors.contains(p.author.userId)
184 28508 7553 - 7568 Select org.make.core.proposal.indexed.IndexedAuthor.userId org.make.api.sequence.sequencesimulationtest p.author.userId
184 29057 7504 - 7570 Apply scala.collection.IterableOps.filterNot org.make.api.sequence.sequencesimulationtest candidates.filterNot(((p: org.make.core.proposal.indexed.IndexedProposal) => chosenAuthors.contains(p.author.userId)))
208 30399 8265 - 8277 Select org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.BanditSorter org.make.api.sequence.sequencesimulationtest ExplorationSelectionAlgorithm.this.BanditSorter
209 29987 8331 - 8346 Select org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.EqualizerSorter ExplorationSelectionAlgorithm.this.EqualizerSorter
210 29121 8400 - 8412 Select org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.RandomSorter ExplorationSelectionAlgorithm.this.RandomSorter
217 28467 8568 - 8610 Apply scala.collection.IterableOps.map org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest proposals.sortBy[Double](((x$6: org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.ZonedProposal) => x$6.score.unary_-))(scala.`package`.Ordering.Double.IeeeOrdering).map[org.make.core.proposal.indexed.IndexedProposal](((x$7: org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.ZonedProposal) => x$7.proposal))
217 29672 8584 - 8584 Select scala.math.Ordering.Double.IeeeOrdering org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest scala.`package`.Ordering.Double.IeeeOrdering
217 28882 8599 - 8609 Select org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.ZonedProposal.proposal org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest x$7.proposal
217 28358 8585 - 8593 Select scala.Double.unary_- org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest x$6.score.unary_-
223 29821 8793 - 8803 Select org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.ZonedProposal.proposal org.make.api.sequence.selectionalgorithmtest x$8.proposal
223 29061 8756 - 8804 Apply scala.collection.IterableOps.map org.make.api.sequence.selectionalgorithmtest org.make.api.technical.MakeRandom.shuffleSeq[org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.ZonedProposal](proposals).map[org.make.core.proposal.indexed.IndexedProposal](((x$8: org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.ZonedProposal) => x$8.proposal))
229 30363 8967 - 8977 Select org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.ZonedProposal.proposal org.make.api.sequence.selectionalgorithmtest x$9.proposal
229 29107 8985 - 8985 Select scala.math.Ordering.Int org.make.api.sequence.selectionalgorithmtest math.this.Ordering.Int
229 28323 8953 - 9007 ApplyToImplicitArgs scala.collection.SeqOps.sortBy org.make.api.sequence.selectionalgorithmtest proposals.map[org.make.core.proposal.indexed.IndexedProposal](((x$9: org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.ZonedProposal) => x$9.proposal)).sortBy[Int](((x$10: org.make.core.proposal.indexed.IndexedProposal) => x$10.votesSequenceCount))(math.this.Ordering.Int)
229 29957 8986 - 9006 Select org.make.core.proposal.indexed.IndexedProposal.votesSequenceCount org.make.api.sequence.selectionalgorithmtest x$10.votesSequenceCount
235 29680 9159 - 9235 Apply scala.collection.IterableOps.take org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest candidates.sortBy[java.time.ZonedDateTime](((x$11: org.make.core.proposal.indexed.IndexedProposal) => x$11.createdAt))(org.make.core.DateHelper.OrderedJavaTime).distinctBy[org.make.core.user.UserId](((x$12: org.make.core.proposal.indexed.IndexedProposal) => x$12.author.userId)).take(neededCount)
264 28858 10636 - 10646 TypeApply scala.collection.immutable.List.empty org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest scala.`package`.List.empty[Nothing]
264 28496 10618 - 10709 Apply org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.TestedProposalsChooser.chooseRecursively org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest TestedProposalsChooser.this.chooseRecursively(scala.`package`.List.empty[Nothing], candidates, neededCount, ignoredKeywords, candidatesPoolSize)
275 29826 11012 - 11028 Apply scala.Int.<= org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest neededCount.<=(0)
276 28948 11042 - 11053 Ident org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.TestedProposalsChooser.accumulator accumulator
278 30369 11129 - 11149 Select org.make.core.proposal.indexed.IndexedProposal.votesSequenceCount org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest x$13.votesSequenceCount
278 29192 11081 - 11150 ApplyToImplicitArgs scala.collection.IterableOnceOps.minByOption org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest candidates.take(candidatesPoolSize).minByOption[Int](((x$13: org.make.core.proposal.indexed.IndexedProposal) => x$13.votesSequenceCount))(math.this.Ordering.Int)
278 29601 11081 - 11708 Match <nosymbol> org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest candidates.take(candidatesPoolSize).minByOption[Int](((x$13: org.make.core.proposal.indexed.IndexedProposal) => x$13.votesSequenceCount))(math.this.Ordering.Int) match { case scala.None => accumulator case (value: org.make.core.proposal.indexed.IndexedProposal): Some[org.make.core.proposal.indexed.IndexedProposal]((chosen @ _)) => { val newAccumulator: List[org.make.core.proposal.indexed.IndexedProposal] = { final <synthetic> <artifact> val rassoc$1: org.make.core.proposal.indexed.IndexedProposal = chosen; accumulator.::[org.make.core.proposal.indexed.IndexedProposal](rassoc$1) }; if (neededCount.<=(1)) newAccumulator else TestedProposalsChooser.this.chooseRecursively(newAccumulator, TestedProposalsChooser.this.deduplicate(chosen, candidates, ignoredKeywords), neededCount.-(1), ignoredKeywords, candidatesPoolSize) } }
278 29532 11128 - 11128 Select scala.math.Ordering.Int org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest math.this.Ordering.Int
281 28327 11271 - 11285 Apply scala.collection.immutable.List.:: org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest accumulator.::[org.make.core.proposal.indexed.IndexedProposal](rassoc$1)
282 29644 11304 - 11320 Apply scala.Int.<= org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest neededCount.<=(1)
283 28863 11340 - 11354 Ident org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.TestedProposalsChooser.newAccumulator org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest newAccumulator
285 28950 11394 - 11680 Apply org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.TestedProposalsChooser.chooseRecursively org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest TestedProposalsChooser.this.chooseRecursively(newAccumulator, TestedProposalsChooser.this.deduplicate(chosen, candidates, ignoredKeywords), neededCount.-(1), ignoredKeywords, candidatesPoolSize)
285 30328 11394 - 11680 Block org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.TestedProposalsChooser.chooseRecursively org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest TestedProposalsChooser.this.chooseRecursively(newAccumulator, TestedProposalsChooser.this.deduplicate(chosen, candidates, ignoredKeywords), neededCount.-(1), ignoredKeywords, candidatesPoolSize)
287 28504 11492 - 11540 Apply org.make.api.sequence.SelectionAlgorithm.ExplorationSelectionAlgorithm.TestedProposalsChooser.deduplicate org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest TestedProposalsChooser.this.deduplicate(chosen, candidates, ignoredKeywords)
288 29893 11574 - 11589 Apply scala.Int.- org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest neededCount.-(1)
303 29197 12084 - 12089 Select org.make.core.proposal.indexed.IndexedProposalKeyword.key org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest k.key
303 28464 12028 - 12100 Apply scala.collection.IterableOnceOps.to org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest chosen.keywords.filterNot(((k: org.make.core.proposal.indexed.IndexedProposalKeyword) => ignoredKeywords.contains(k.key))).to[scala.collection.mutable.HashSet[org.make.core.proposal.indexed.IndexedProposalKeyword]](collection.this.IterableFactory.toFactory[org.make.core.proposal.indexed.IndexedProposalKeyword, [A]scala.collection.mutable.HashSet[A]](scala.collection.mutable.HashSet))
303 29648 12095 - 12099 Select scala.collection.mutable.HashSet org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest scala.collection.mutable.HashSet
303 28310 12059 - 12090 Apply scala.collection.mutable.HashSet.contains org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest ignoredKeywords.contains(k.key)
303 28824 12095 - 12099 ApplyImplicitView scala.collection.IterableFactory.toFactory org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest collection.this.IterableFactory.toFactory[org.make.core.proposal.indexed.IndexedProposalKeyword, [A]scala.collection.mutable.HashSet[A]](scala.collection.mutable.HashSet)
304 29157 12109 - 12264 Apply scala.collection.IterableOps.filter org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest candidates.filter(((proposal: org.make.core.proposal.indexed.IndexedProposal) => proposal.keywords.exists(((elem: org.make.core.proposal.indexed.IndexedProposalKeyword) => forbiddenKeywords.contains(elem))).unary_!.&&(chosen.author.userId.!=(proposal.author.userId))))
305 30335 12208 - 12254 Apply java.lang.Object.!= org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest chosen.author.userId.!=(proposal.author.userId)
305 29895 12177 - 12203 Apply scala.collection.mutable.HashSet.contains org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest forbiddenKeywords.contains(elem)
305 29610 12151 - 12254 Apply scala.Boolean.&& org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest proposal.keywords.exists(((elem: org.make.core.proposal.indexed.IndexedProposalKeyword) => forbiddenKeywords.contains(elem))).unary_!.&&(chosen.author.userId.!=(proposal.author.userId))
305 29021 12232 - 12254 Select org.make.core.proposal.indexed.IndexedAuthor.userId org.make.api.sequence.sequencesimulationtest,org.make.api.sequence.selectionalgorithmtest proposal.author.userId
329 28317 13133 - 13164 Apply scala.collection.IterableOps.++ org.make.api.sequence.selectionalgorithmtest newProposals.++[org.make.core.proposal.indexed.IndexedProposal](testedProposals)
332 30299 13246 - 13280 ApplyToImplicitArgs eu.timepit.refined.auto.autoUnwrap org.make.api.sequence.selectionalgorithmtest eu.timepit.refined.auto.autoUnwrap[eu.timepit.refined.api.Refined, Int, eu.timepit.refined.numeric.Positive](sequenceConfiguration.sequenceSize)(api.this.RefType.refinedRefType)
332 29730 13246 - 13280 Select org.make.core.sequence.SpecificSequenceConfiguration.sequenceSize org.make.api.sequence.selectionalgorithmtest sequenceConfiguration.sequenceSize
332 28896 13268 - 13268 Select eu.timepit.refined.api.RefType.refinedRefType org.make.api.sequence.selectionalgorithmtest api.this.RefType.refinedRefType
333 29865 13311 - 13333 Select scala.collection.SeqOps.size org.make.api.sequence.selectionalgorithmtest includedProposals.size
335 29026 13370 - 13397 Apply scala.Int.- org.make.api.sequence.selectionalgorithmtest sequenceSize.-(includedSize)
337 30419 13421 - 13487 Apply scala.collection.IterableOps.take org.make.api.sequence.selectionalgorithmtest proposalsPool.sortBy[Int](((x$14: org.make.core.proposal.indexed.IndexedProposal) => x$14.votesSequenceCount))(math.this.Ordering.Int).take(proposalsToChoose)
339 29163 13495 - 13548 Apply scala.collection.IterableOps.++ org.make.api.sequence.selectionalgorithmtest includedProposals.++[org.make.core.proposal.indexed.IndexedProposal](org.make.api.technical.MakeRandom.shuffleSeq[org.make.core.proposal.indexed.IndexedProposal](proposals))
339 29574 13516 - 13548 Apply org.make.api.technical.MakeRandom.shuffleSeq org.make.api.sequence.selectionalgorithmtest org.make.api.technical.MakeRandom.shuffleSeq[org.make.core.proposal.indexed.IndexedProposal](proposals)
353 29733 13884 - 13911 Apply scala.collection.IterableOps.map org.make.api.sequence.selectionalgorithmtest includedProposals.map[org.make.core.proposal.ProposalId](((x$15: org.make.core.proposal.indexed.IndexedProposal) => x$15.id))
353 28279 13906 - 13910 Select org.make.core.proposal.indexed.IndexedProposal.id org.make.api.sequence.selectionalgorithmtest x$15.id
355 30258 13990 - 14017 Select scala.Boolean.unary_! org.make.api.sequence.selectionalgorithmtest excludedIds.contains[org.make.core.proposal.ProposalId](p.id).unary_!
355 28861 14012 - 14016 Select org.make.core.proposal.indexed.IndexedProposal.id org.make.api.sequence.selectionalgorithmtest p.id
355 29797 13936 - 14018 Apply scala.collection.IterableOps.filter org.make.api.sequence.selectionalgorithmtest newProposals.++[org.make.core.proposal.indexed.IndexedProposal](testedProposals).filter(((p: org.make.core.proposal.indexed.IndexedProposal) => excludedIds.contains[org.make.core.proposal.ProposalId](p.id).unary_!))
356 28985 14040 - 14073 Apply org.make.api.technical.MakeRandom.shuffleSeq org.make.api.sequence.selectionalgorithmtest org.make.api.technical.MakeRandom.shuffleSeq[org.make.core.proposal.indexed.IndexedProposal](candidates)
357 28287 14115 - 14174 Apply scala.Int.- org.make.api.sequence.selectionalgorithmtest eu.timepit.refined.auto.autoUnwrap[eu.timepit.refined.api.Refined, Int, eu.timepit.refined.numeric.Positive](sequenceConfiguration.sequenceSize)(api.this.RefType.refinedRefType).-(includedProposals.size)
357 29737 14101 - 14175 Apply scala.collection.IterableOps.take org.make.api.sequence.selectionalgorithmtest shuffled.take(eu.timepit.refined.auto.autoUnwrap[eu.timepit.refined.api.Refined, Int, eu.timepit.refined.numeric.Positive](sequenceConfiguration.sequenceSize)(api.this.RefType.refinedRefType).-(includedProposals.size))
357 29536 14137 - 14137 Select eu.timepit.refined.api.RefType.refinedRefType org.make.api.sequence.selectionalgorithmtest api.this.RefType.refinedRefType
357 28821 14080 - 14175 Apply scala.collection.IterableOps.++ org.make.api.sequence.selectionalgorithmtest includedProposals.++[org.make.core.proposal.indexed.IndexedProposal](shuffled.take(eu.timepit.refined.auto.autoUnwrap[eu.timepit.refined.api.Refined, Int, eu.timepit.refined.numeric.Positive](sequenceConfiguration.sequenceSize)(api.this.RefType.refinedRefType).-(includedProposals.size)))
357 30325 14115 - 14149 Select org.make.core.sequence.SpecificSequenceConfiguration.sequenceSize org.make.api.sequence.selectionalgorithmtest sequenceConfiguration.sequenceSize
357 29132 14152 - 14174 Select scala.collection.SeqOps.size org.make.api.sequence.selectionalgorithmtest includedProposals.size