Ich schrieb ein Sieb mit akka
Strömen prime Mitglieder einer beliebigen Quelle Int
zu finden:Wie kann ich mein Akka-Streams Prime-Sieb ändern, um Modulo-Checks für bekannte Primzahlen auszuschließen?
object Sieve extends App {
implicit val system = ActorSystem()
implicit val mat = ActorMaterializer(ActorMaterializerSettings(system))
implicit val ctx = implicitly[ExecutionContext](system.dispatcher)
val NaturalNumbers = Source.fromIterator(() => Iterator.from(2))
val IsPrimeByEurithmethes: Flow[Int, Int, _] = Flow[Int].filter {
case n: Int =>
(2 to Math.floor(Math.sqrt(n)).toInt).par.forall(n % _ != 0)
}
NaturalNumbers.via(IsPrimeByEurithmethes).throttle(100000, 1 second, 100000, ThrottleMode.Shaping).to(Sink.foreach(println)).run()
}
Ok, so scheint dies anständig gut zu funktionieren. Allerdings gibt es zumindest einige potenzielle Problembereiche:
- Die Modulo-Prüfungen werden ausgeführt unter Verwendung von
par.forall
, dh sie sind innerhalb derFlow
dassfilter
s völlig versteckt sind, aber ich kann sehen, wie es sinnvoll wäre, zu haben aMap
von dercandidate n
zu einer anderenMap
von jedern % _
. Könnte sein. - Ich überprüfe viel zu viele der Kandidaten unnötig - sowohl in Bezug auf die Überprüfung
n
, dass ich bereits wissen, sind nicht Prime auf der Grundlage der vorherigen Ergebnisse, und durch Überprüfungn % _
, die redundant sind. Tatsächlich, selbst wenn ich denke, dass dien
Primzahl ist, reicht es aus, nur die bekannten Primzahlen bis zu diesem Punkt zu überprüfen.
Der zweite Punkt ist meine unmittelbare Sorge.
Ich denke, dass ich ziemlich leicht beweisen kann, dass es einen effizienteren Weg gibt - indem man den source
herausfiltert, der jedem NEUEN Strich gegeben wird. So
dann ....
2, 3, 4, 5, 6, 7, 8, 9, 10, 11... => (after finding p=2)
2, 3, 5, 7, 9, , 11... => (after finding p=3)
2, 3, 5, 7, , 11... => ...
Jetzt, nach einem p
und Filtern der Quelle zu finden, müssen wir wissen, ob der nächste Kandidat ein p
ist. Nun, wir können sicher sagen, dass es eine Primzahl ist, wenn der größte bekannte Primzahl größer als seine Wurzel ist, was immer passiert, ich glaube, so genügt es, nur das nächste Element zu holen ...
2, 3, 4, 5, 6, 7, 8, 9, 10, 11... => (after finding p=2) PICK n(2) = 3
2, 3, 5, 7, 9, , 11... => (after finding p=3) PICK n(3) = 5
2, 3, 5, 7, , 11... => (after finding p=5) PICK n(5) = 7
Dies scheint darauf hinzu Ich mag es, das ursprünglich bereitgestellte Sieb neu zu schreiben, um weit weniger Kontrollen zu machen, die auf Kosten einer strengen sequenziellen Abhängigkeit gehen.
Eine weitere Idee - ich konnte die Einschränkung entfernen, indem Sie Dinge in Bezug auf die Symbole, wie das Mindestangebot an Modulo Kontrollen arbeiten, die Primalität erforderlich machen, usw.
Bin ich den Holzweg? Wenn nicht, wie kann ich auf diese Weise mit meiner Quelle herumspielen?
Also ... das funktioniert :) aber es ist nicht mit der substreaming, dass ich bin irgendwie suchen zu verwenden und Sie auch erwähnt –