local-search-0.0.2: Control/Search/Local/Neighbourhood.hs
-----------------------------------------------------------------------------
-- |
-- Module : Control.Search.Local.Neighbourhood
-- Copyright : (c) Richard Senington & David Duke 2010
-- License : GPL-style
--
-- Maintainer : Richard Senington <sc06r2s@leeds.ac.uk>
-- Stability : provisional
-- Portability : portable
--
-- Simple Neighbourhood functions for the representation of problems to the library.
-- All neighbourhood functions must ultimately be of the form a->[a].
--
-- This module also contains some additional code for the modeling of problems and the
-- link between the model and the library.
-----------------------------------------------------------------------------
module Control.Search.Local.Neighbourhood (
exchange,
basicExchange,
NumericallyPriced(priceSolution)
) where
import Data.List
-- | following helper function pinched from http://www.polyomino.f2s.com/david/haskell/combinatorics.html
combinationsOf 0 _ = [[]]
combinationsOf _ [] = []
combinationsOf k (x:xs) = map (x:) (combinationsOf (k-1) xs) ++ combinationsOf k xs
{- | my code again from here on
The first type of neighbourhood is based upon combination exchange in a sequence of elements. This is appropriate for something like TSP, where
order matters, but would be less useful for SAT.
It takes 2 numbers as parameters, one of which is the number of exchanges to perform, the other the maximum distance within the list.
For example exchange 2 2, would change up to 2 elements in each neighbourhood, either adjacent or separated by 1 other element. -}
exchange :: Eq a=>Int->Int->[a]->[[a]]
exchange _ 0 inlist = [inlist]
exchange exchanges dist inlist = nub (map (implement inlist) variants)
where
len = (length inlist -1)
opts = [(x,x+y) | x<-[0..len],y<-[1..dist],x+y<= len]
variants = combinationsOf exchanges opts
implement :: [a]->[(Int,Int)]->[a]
implement i [] = i
implement i ((x,y):xs) = implement (begin++[x2]++middle++[x1]++rest') xs
where
(begin,x1:rest) = splitAt x i
(middle,x2:rest') = splitAt (y-x-1) rest
-- | We provide the most basic exchange system for testing
basicExchange :: Eq a=>[a]->[[a]]
basicExchange = exchange 1 1
{- |
Some transformations (and the manual inspector of the search process) need to be able to extract a numeric price from
a solution. To use these, the solution representation data type must be a part of the following class, please see
the example code. -}
class (Ord b,Num b)=>NumericallyPriced a b | a->b where
priceSolution :: a->b