Guest User

Untitled

a guest
Oct 15th, 2018
81
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.03 KB | None | 0 0
  1. {-# LANGUAGE RecordWildCards, TupleSections #-}
  2. module Main where
  3.  
  4. import Data.List(partition)
  5. import GTA.Data.JoinList(Semiring, JoinList, JoinListAlgebra(..),
  6. joinize, dejoinize, maxsumsolutionWith)
  7. import GTA.Core(GenericSemiring(..), CommutativeMonoid(..), Bag(..),
  8. hom, oplus, identity, (<.>), filterBy, aggregateBy)
  9. import Data.Vector.Bit(packInteger, pad)
  10. import Data.Bits(bit, (.|.), (.&.))
  11.  
  12. problem :: [(Double, Double)]
  13. problem = [ (6734, 1453),
  14. (2233, 10),
  15. (5530, 1424),
  16. (401, 841),
  17. (3082, 1644),
  18. (7608, 4458),
  19. (7573, 3716),
  20. (7265, 1268),
  21. (6898, 1885),
  22. (1112, 2049) ]
  23.  
  24. main :: IO ()
  25. main = print $ tsp [ [ to `distance` from | to <- problem ] | from <- problem ]
  26. where len = length problem
  27. distance (a,b) (c,d) = sqrt $ (a-c)^2 + (b-d)^2
  28.  
  29. edges :: Int -> Semiring (Int,Int) s -> s
  30. edges n = edgesJ n $ joinize [0..n-1]
  31.  
  32. edgesJ :: Int -> JoinList Int -> Semiring (Int, Int) s -> s
  33. edgesJ n xs (GenericSemiring {..}) = permute' xs
  34. where permute' = hom (JoinListAlgebra { times = times,
  35. single = single',
  36. nil = nil })
  37. single' s = foldr (oplus . single . (s,)) identity $
  38. filter (s /=) [0..n-1]
  39. JoinListAlgebra {..} = algebra
  40. CommutativeMonoid {..} = monoid
  41.  
  42. -- 閉路Tester(閉路しかないかを判定する 複数あるかもしれない)
  43. circuits n = (Nothing /=) <.> circuits'
  44. where circuits' = JoinListAlgebra{..}
  45. Nothing `times` ys = Nothing
  46. xs `times` Nothing = Nothing
  47. Just Nothing `times` ys = ys
  48. xs `times` Just Nothing = xs
  49. Just (Just (s, e)) `times` Just (Just (s', e')) =
  50. if 0 == packInteger ((s .&. s') .|. (e .&. e'))
  51. then Just (Just (s .|. s', e .|. e'))
  52. else Nothing
  53. single (s, e) = Just $ Just (pad n (bit s), pad n (bit e))
  54. nil = Just Nothing
  55.  
  56. -- 連結Tester(選択したエッジが繋ってるかを判定する)
  57. connected n = ((1 ==) . length) <.> connected'
  58. where connected' = JoinListAlgebra{..}
  59. xs `times` ys = foldr (#) [] (xs ++ ys)
  60. a # xs = foldr (.|.) a ss : ts
  61. where (ss, ts) = partition ((0 /=) . packInteger . (a .&.)) xs
  62. single (a,b) = [pad n (bit a) .|. pad n (bit b)]
  63. nil = []
  64.  
  65. -- 通行禁止のエッジを指定するTester
  66. forbid edge = id <.> fobidden'
  67. where fobidden' = JoinListAlgebra{..}
  68. times = (&&)
  69. single (a,b) = edge /= (a,b) && edge /= (b,a)
  70. nil = True
  71.  
  72. -- TSPを解く
  73. tsp problem = map snd . dejoinize . head $ ans
  74. where
  75. (c, Bag ans) = edges size
  76. `filterBy` circuits size
  77. `filterBy` connected size
  78. -- `filterBy` forbid (0,2)
  79. `aggregateBy` maxsumsolutionWith cost
  80. size = length problem
  81. cost (a, b) = - problem !! a !! b
Add Comment
Please, Sign In to add comment