Haskell 相交与数据。设置相交运行时
基于stackExchange上的另一个线程,我尝试使用Data.Set.intersection改进重复交集的运行时间,而不是Prelude的短整数列表交集(Bool) isswappable x y=(probmrisPrime 3(读取((显示x)+(显示y))==“prob prime”)&& ((probmrisPrime 3(读((显示y)+(显示x))=“prob prime”)) --米勒-拉宾概率素数检验 --输入:n>3,需要测试素性的奇数整数; --输入:k,一个决定测试准确性的参数 --米勒-拉宾试验用随机种子 mygen=mkStdGen 3212343141312330 问题质素k n |n`mod`2==0=“复合” |否则=见证循环n随机数 其中,randomAs=取k(randomRs(2,(n-2))(mygen))::[整数] 见证循环[]=“prob prime” 见证环n(hd:lst) |x==1 | | x==n-1=witnessloop n(lst) |否则=检查(s-1)x 其中x=功率hd d n 1 d=千分之n s=千分位n 检查0 u=“复合” 检查s x |newx==1=“复合” |newx==n-1=witnessloop n(lst) |否则=检查(s-1)newx 其中newx=(x^2)`mod`n millerrabines num=系数2(num-1) 千分位数=quot(num-1)(2^(千分位数)) 因子2数值 |num`rem`2==0=1+factor2(quot num 2) |否则=0 整数->整数->整数->整数->整数->整数 功率b 0 m r=r 功率b e m r | e`mod`2==1=功率(b*b`mod`m)(e`div`2)m(r*b`mod`m) 功率b e m r=功率(b*b`mod`m)(e`div`2)m r 集合::Int->[[Integer]] --集合1=[[3]] --用下一个素数检查所有以前的集合,并将任何新的带有n的集合追加到列表中 集合2=[[3]] --从prime==7开始,因为任何5的prime总是被5除 设置n=检查(取(n-2)个查找集)(素数!!n) 检查[]n=[[n]] 检查(x:xs)n |不可切换==[]=(x++[n]):(检查xs(n)) |否则=(勾选(removecandidates xs)n) 哪里 --如果输入n可与所有内容交换,则返回null 不可交换=snd(分区(可交换n)x)Haskell 相交与数据。设置相交运行时,haskell,set,intersection,Haskell,Set,Intersection,基于stackExchange上的另一个线程,我尝试使用Data.Set.intersection改进重复交集的运行时间,而不是Prelude的短整数列表交集(Bool) isswappable x y=(probmrisPrime 3(读取((显示x)+(显示y))==“prob prime”)&& ((probmrisPrime 3(读((显示y)+(显示x))=“prob prime”)) --米勒-拉宾概率素数检验 --输入:n>3,需要测试素性的奇数整数; --输入:k,一个决定测试准
ReXvCeNeDealsList= [X] XI席认为你的结论(“代码>数据。SET。交叉/<代码>是最大的成本中心”)您的数据不支持,只说明
检查。removecandidates
是最大的成本中心。是否可以按集合进行所有操作,这样您就不会在集合
和[]之间来回转换
在您的内部循环中?对于少于5个元素的列表,我希望列表交集的性能优于转换为集合、使用集合交集以及转换回列表。我试图提供帮助,但我无法真正理解代码应该做什么。也许可以填写类型并提供可运行的内容?而不是我已经在上面添加了一些澄清意见。同时添加了完全可执行的代码我认为您的结论(“Data.Set.intersection是最大的成本中心”)您的数据不支持,只说明检查。removecandidates
是最大的成本中心。是否可以按集合进行所有操作,这样您就不会在集合
和[]之间来回转换
在您的内部循环中?对于少于5个元素的列表,我希望列表交集的性能优于转换为集合、使用集合交集以及转换回列表。我试图提供帮助,但我无法真正理解代码应该做什么。也许可以填写类型并提供可运行的内容?而不是我在上面添加了一些澄清意见。还添加了完全可执行的代码
S.intersection (S.fromList [1..10000]) (S.fromList [5000..200000])
(0.25 secs, 125337020 bytes)
--Check takes a list of integers and then checks if another integer n is
--"swappable" Swappable integers are two integers that, when concatenated, are prime. Any new sets created with n are returned
check ::[[Integer]] -> Integer -> [[Integer]]
check [] n = [[n]]
check (x:xs) n
|nonswappable == [] = (x++[n]):(check xs (n))
|otherwise = (check (removecandidates xs) n)
where
--nonswappable returns null if the input n isswappable with everything
--isswappable:: Integer->Integer->Bool This function concatenates two numbers and checks if they are prime.
nonswappable = snd(partition (isswappable n) x)
--removecandidates strikes out candidate lists in the list containing a nonswappable number in the set just checked
removecandidates list = filter ((==[]).(intersect nonswappable)) list
total time = 5.30 secs (5304 ticks @ 1000 us, 1 processor)
total alloc = 2,676,617,968 bytes (excludes profiling overheads)
COST CENTRE MODULE %time %alloc
powm Main 29.3 36.2
isswappable Main 26.3 25.3
check.removecandidates Main 15.9 18.5
probmrisPrime.randomAs Main 6.9 3.8
individual inherited
COST CENTRE MODULE no. entries %time %alloc %time %alloc
primes Main 110 1 0.0 0.0 0.2 0.5
sieve Main 111 573 0.2 0.5 0.2 0.5
findsets Main 104 1 0.0 0.0 99.8 99.5
sets Main 105 571 0.2 0.2 99.8 99.5
check Main 106 55704 0.2 0.1 99.6 99.3
check.removecandidates Main 126 52920 15.9 18.5 15.9 18.5
check.nonswappable Main 107 55135 0.4 0.2 83.5 80.7
--Check takes a list of integers and then checks if another integer n is
--"swappable" Swappable integers are two integers that, when concatenated, are prime. Any new sets created with n are returned
check ::[[Integer]] -> Integer -> [[Integer]]
check [] n = [[n]]
check (x:xs) n
|nonswappable == [] = (x++[n]):(check xs (n))
|otherwise = (check (removecandidates xs) n)
where
--nonswappable returns null if the input n is swappable with everything
--isswappable:: Integer->Integer->Bool This function concatenates two numbers and checks if they are prime.
nonswappable = snd(partition (isswappable n) x)
--removecandidates strikes out candate lists in the list containing a nonswappable number in the set just checked
removecandidates list = filter ((==[]).(S.toList.S.intersection setnonswappable.setx)) list
where
setnonswappable = S.fromList nonswappable
setx lst = S.fromList lst
total time = 7.36 secs (7361 ticks @ 1000 us, 1 processor)
total alloc = 3,019,801,528 bytes (excludes profiling overheads)
COST CENTRE MODULE %time %alloc
check.removecandidates Main 30.7 21.8
powm Main 21.6 32.1
isswappable Main 20.6 22.4
check.removecandidates.setx Main 6.8 5.9
probmrisPrime.randomAs Main 4.9 3.4
individual inherited
COST CENTRE MODULE no. entries %time %alloc %time %alloc
MAIN MAIN 63 0 0.0 0.0
primes Main 112 1 0.0 0.0 0.3 0.4
sieve Main 113 573 0.3 0.4 0.3 0.4
findsets Main 106 1 0.0 0.0 99.7 99.6
sets Main 107 571 0.3 0.2 99.7 99.6
check Main 108 55704 0.2 0.1 99.4 99.4
check.removecandidates Main 128 52920 30.7 21.8 37.5 27.8
check.removecandidates.setx Main 130 4949177 6.8 5.9 6.8 5.9
check.removecandidates.setnonswappable Main 129 52446 0.0 0.0 0.0 0.0
module Main where
import Data.List
import System.Random
import qualified Data.Set as S
primes::[Integer]
primes = sieve (2:[3,5..])
sieve []=[]
sieve (x:xs) = x:sieve[y|y<-xs, (y `rem` x)/=0]
--isswappabble using probablistic prime
isswappable:: Integer->Integer->Bool
isswappable x y = (probmrisPrime 3 (read ((show x) ++ (show y))) == "prob prime") &&
((probmrisPrime 3 (read ((show y) ++ (show x))) == "prob prime"))
--miller rabine probablistic prime test
--Input: n > 3, an odd integer to be tested for primality;
--Input: k, a parameter that determines the accuracy of the test
--random seed for miller-rabine test
mygen = mkStdGen 32123432141312332130
probmrisPrime k n
| n `mod` 2 == 0 = "composite"
|otherwise = witnessloop n randomAs
where randomAs = take k (randomRs (2, (n-2)) (mygen))::[Integer]
witnessloop _ [] = "prob prime"
witnessloop n (hd:lst)
| x == 1 || x==n-1 = witnessloop n (lst)
| otherwise = checks (s-1) x
where x = powm hd d n 1
d = millerrabined n
s = millerrabines n
checks 0 _ = "composite"
checks s x
| newx == 1 = "composite"
| newx == n-1 = witnessloop n (lst)
| otherwise = checks (s-1) newx
where newx = (x^2) `mod` n
millerrabines num=factor2 (num-1)
millerrabined num=quot (num-1) (2^(millerrabines num))
factor2 num
| num `rem` 2 ==0 = 1 + factor2 (quot num 2)
| otherwise = 0
powm :: Integer -> Integer -> Integer -> Integer -> Integer
powm b 0 m r = r
powm b e m r | e `mod` 2 == 1 = powm (b * b `mod` m) (e `div` 2) m (r * b `mod` m)
powm b e m r = powm (b * b `mod` m) (e `div` 2) m r
sets :: Int->[[Integer]]
--sets 1 = [[3]]
--checks all the previous sets with the next prime number and appends any new sets with n to the list
sets 2 = [[3]]
--start with prime == 7 since any prime with 5 will always divide by 5
sets n = check (take (n-2) findsets) (primes!!n)
check [] n = [[n]]
check (x:xs) n
|nonswappable == [] = (x++[n]):(check xs (n))
|otherwise = (check (removecandidates xs) n)
where
--returns null if the input n is swappable with everything
nonswappable = snd(partition (isswappable n) x)
removecandidates list = [x| x<-list, intersect nonswappable x == [] ]
{-replacement logic using Data.Set
removecandidates list = filter ((==[]).(intersect nonswappable)) list
removecandidates list = filter ((==[]).(S.toList.S.intersection setnonswappable.setx)) list
where
setnonswappable = S.fromList nonswappable--
setx lst = S.fromList lst -}
--generate all the sets
findsets= concat(map sets [2..])
--find sets of certain length
findGroups list len = [x| x<-list, length x >= len]
main = do
putStrLn $ show ( take 1 (findGroups (findsets) 5))