Haskell Tree delete a node / calculate all possible paths - haskell

I have these structures:
data Tree = Leaf Points | Branch Points [Tree]
deriving(Eq,Show)
data Design = Design Tree Tree Int
deriving(Eq,Show)
data type Tree is a part of data type Design and Design holds two Trees:
type Points = [(Int,Int,Int,Int)]
design = Design mtree btree 180
I have to find all the possible paths:
numberPaths :: Design -> Int
and change the third Integer from Points and also 180 from design:
type Points = [(Int,Int,Int,Int)]
design = Design mtree btree 180
changeInt :: Design -> Design

Count paths
To find the number of paths in a tree, we recursively descend down the tree to count the number of subpaths for each node and then sum them up. So aside from having numberPaths as the interface, we also need another auxiliary function whose type signature is Tree -> Int. Let's call it descend.
descend :: Tree -> Int
We count Leaf as 1, and Branch as the sum of number of paths of its subtrees. So the descend becomes:
descend :: Tree -> Int
descend (Leaf _) = 1
descend (Branch _ subtress) = foldr (\tree sum -> sum + descend tree) 0 subtrees
The function numberPaths only need to call descend to count its two trees.
numberPaths :: Design -> Int
numberPaths (Design a b _) = descend a + descend b
Chang Int
The type signature of changeInt indicates that no Int value is introduced to change Design type. This, I think, does not make sense so I have taken the liberty of changing it into Int -> Design -> Design.
The implementation of changeInt follows a similar pattern. To change the tree we recursively walk down each level of the tree. We also introduce an auxiliary function changePoints.
changeTree :: Int -> Tree -> Tree
changeTree n (Leaf points) = Leaf $ changePoints n points
changeTree n (Branch points subtrees) = Branch points' subtrees'
where points' = changePoints n points
subtrees' = map (changeTree n) subtrees
changePoints :: Int -> Points -> Points
changePoints n points = map (\(x, y, _, z) -> (x, y, n, z)) points
The changeInt then only needs to call changeTree to finish the job.
changeInt :: Int -> Design -> Design
changeInt n (Design mtree btree _) = Design mtree' btree' n
where mtree' = changeTree n mtree
btree' = changeTree n btree

Related

In Haskell, how do I return the number of nodes in a binary tree?

Define, for a binary tree type Tree, a function which returns the number of nodes. I came up with this function but it does not run.
Error: Not in scope: data constructor'Node'
numberOfNodes :: Tree -> Int
numberOfNodes Null = 0
numberOfNodes (Node _ st1 st2) = 1 + max (st1)(st2)
The first issue is that you appear to be missing a definition for what a Tree is.
Generally we say it's either a Node with a value plus two subtrees, or it's empty.
Next, our recursive definition for the number of nodes in a (non-empty) tree should be:
number of nodes in left subtree + number of nodes in right subtree + 1
Here is a full definition:
data Tree a = Empty | Node a (Tree a) (Tree a) deriving (Show)
numberOfNodes :: Tree x -> Int
numberOfNodes Empty = 0
numberOfNodes (Node _ st1 st2) = 1 + numberOfNodes(st1) + numberOfNodes(st2)
(Note that we implement the Show typeclass so that we can print the tree)
If we define a binary tree with 3 nodes, see how it works:
myTree :: Tree Int
myTree =
Node 0
(Node 1 Empty Empty)
(Node 2 Empty Empty)
> numberOfNodes myTree
=> 3
Live Demo
The error indicates that you did not make a data constructor Node. Perhaps you made a data constructor Tree, for example:
data Tree a = Null | Tree a (Tree a) (Tree a)
using Tree as a data constructor is not wrong. But you need to decide what the name will be, and use that data constructor.
Anyway, you do not need to define a function to count the number of elements yourself. You can let Haskell make it an instance of Foldable, and then use length :: Foldable f => f a -> Int:
{-# LANGUAGE DeriveFoldable #-}
data Tree a = Null | Node a (Tree a) (Tree a) deriving (Foldable, Show)
If we for example define a sample tree like #AndyG wrote, we can calculate the number of Nodes as:
Prelude> length (Node 0 (Node 1 Null Null) (Node 2 Null Null))
3
If you implement the length yourself, you should make a recursive call to the subtrees, since you can not add up subtrees:
numberOfNodes :: Tree -> Int
numberOfNodes Null = 0
numberOfNodes (Node _ st1 st2) = 1 + numberOfNodes st1 + numberOfNodes st2
It seems you don't have the data type definition in scope. It should probably be
data Tree a = Null | Node a (Tree a) (Tree a)
Also, the code you show computes a tree's depth (in principle, after it's fixed). The total count of tree's nodes is the sum of the counts of nodes in its left and right sub-trees, give or take 1; not max.
Empty (leaf, Null) nodes should probably not be counted, i.e. their contribution to the total count should probably be 0. You decide.

Building Huffman tree using min-heap in Haskell

I am having a huge problem with this. I don't have any idea how to make Huffman tree since it is being built bottom-up (from the liefs to the root).
I am new to Haskell and functional programming. I have seen there are other posts similar to mine, but they did not help me.
This is my code
import Data.Map
type Value = Int
type Key = [Char]
type NodeValue = (Key,Value)
data Heap_ a = Empty
| Node a (Heap_ a) (Heap_ a)
deriving(Show, Eq)
type Heap a = Heap_ NodeValue
frequencyOfCharacters :: [Char] -> Map Key Value
frequencyOfCharacters [] = Data.Map.empty
frequencyOfCharacters (character:text) = insertWith (+) [character] 1 (frequencyOfCharacters text)
makeLeaf :: NodeValue -> Heap a
makeLeaf a = Node a Empty Empty
mergeHeaps :: Heap a -> Heap a -> Heap a
mergeHeaps Empty rightHeap = rightHeap
mergeHeaps leftHeap Empty = leftHeap
mergeHeaps leftHeap#(Node a lefta righta) rightHeap#(Node b leftb rightb)
| snd a < snd b = Node a (mergeHeaps lefta rightHeap) righta
| otherwise = Node b leftb (mergeHeaps leftHeap rightb)
addToHeap :: Heap a->NodeValue->Heap a
addToHeap Empty a = makeLeaf a
addToHeap h a = mergeHeaps h (makeLeaf a)
takeHeadFromHeap :: Heap a -> (NodeValue,Heap a)
takeHeadFromHeap Empty = (("",-1), Empty)
takeHeadFromHeap (Node a leftBranch rightBranch) = (a, mergeHeaps leftBranch rightBranch)
makeHeap :: Map Key Value -> Heap a
makeHeap map_ = makeHeap_ $ toList map_
makeHeap_ :: [(Key,Value)] -> Heap a
makeHeap_ [] = Empty
makeHeap_ (x:xs) = addToHeap (makeHeap_ xs) x
huffmanEntry :: [Char]-> Heap a
huffmanEntry text = makeHeap $ frequencyOfCharacters text
I am thinking about this data structure for Huffman tree
data HuffmanTree h = Leaf [Char]
| NodeHuff [Char] (HuffmanTree h) (HuffmanTree h)
deriving(Show, Eq)
but i have no idea how to make Huffman tree from min heap.
After this line of code in ghci min heap is made from input string
*Main> huffmanEntry "Aasdqweqweasd"
You need to make a Huffman Tree with a min heap, and you said "I have no idea how to make Huffman Tree from min heap". Let's figure out what you need to do before you start coding, especially in a language that you might not be familiar with.
I suppose we should check the internet for a way to make a Huffman Tree. How about the Wikipedia page on Huffman Coding? (https://en.wikipedia.org/wiki/Huffman_coding)
The simplest construction algorithm uses a priority queue where the
node with lowest probability is given highest priority:
Create a leaf node for each symbol and add it to the priority queue.
While there is more than one node in the queue:
Remove the two nodes of highest priority (lowest probability) from
the queue
Create a new internal node with these two nodes as
children and with probability equal to the sum of the two nodes'
probabilities.
Add the new node to the queue.
The remaining node is the root node and the tree is complete.
You already have code in place to find the frequency of each symbol in a given string - that's your frequencyOfCharacters function.
All you need now is a priority queue! You can definitely find a way to implement a priority queue using a min heap.
I hope this helps you piece the logic together.
If you want to deal with the problem step-by-step, why don't you start by trying to make a Huffman Tree using a working implementation of a priority queue (http://hackage.haskell.org/package/PSQueue)?
Once you're done with that, you can try to replace this readymade module with a small queue module of your own using a working implementation of a min heap (http://hackage.haskell.org/package/heap).
Finally, you can write a barebones min heap module by yourself (you have a lot of the code already) and replace the external heap module with that.
Update: Some more concrete suggestions on how to build the tree. This requires a little setup, so please bear with me. Suppose you have a Tree.hs module that allows you to work with binary trees:
module Tree where
-- Binary Tree
data Tree k v =
Empty
| Node (k, v) (Tree k v) (Tree k v)
deriving ( Show )
-- takes a (key, value) pair and returns a binary tree
-- containing one node with that pair
singleton :: (k, v) -> Tree k v
singleton = undefined
-- takes three things: a (key, value) pair, a binary tree t1
-- and another binary tree t2
-- then it constructs the tree
-- (key, val)
-- / \
-- t1 t2
joinWith :: (k, v) -> Tree k v -> Tree k v -> Tree k v
joinWith = undefined
-- returns the value associated with the (key, value) pair
-- stored in the root node of the binary tree
value :: Tree k v -> v
value = undefined
and you also have a Queue.hs module which lets you work with priority queues (I'm assuming you have a working min-heap module)
module Queue where
import Heap
-- a priority queue
type Queue k v = Heap k v
-- returns an empty queue
empty :: (Ord v) => Queue k v
empty = undefined
-- adds a (key, value) pair to the queue and returns a
-- new copy of the queue containing the inserted pair
enqueue :: (Ord v) => (k, v) -> Queue k v -> Queue k v
enqueue = undefined
-- removes the lowest-value (key, value) pair from the queue
-- and returns a tuple consisting of the removed pair
-- and a copy of the queue with the pair removed
dequeue :: (Ord v) => Queue k v -> ((k, v), Queue k v)
dequeue = undefined
-- returns the number of elements in the queue
size :: (Ord v) => Queue k v -> Int
size = undefined
Then this is how you might try to make a Huffman.hs module using the tools at your disposal.
module Huffman where
import Queue
import Tree
type HuffmanTree = Tree Char Int
-- takes a list of (character, frequency) pairs and turns them into
-- a Huffman Tree
makeHuffmanTree :: [(Char, Int)] -> HuffmanTree
makeHuffmanTree pairs = let
nodeList = map (\pair -> (singleton pair, snd pair)) pairs
nodeQueue = foldr enqueue empty nodeList
in
reduceNodes nodeQueue
-- takes pairs of nodes from the queue and combines them
-- till only one node containing the full Huffman Tree is
-- present in the queue
-- then this last node is dequeued and returned
reduceNodes :: Queue HuffmanTree Int -> HuffmanTree
reduceNodes q
| size q == 0 = error "no nodes!"
| size q == 1 = fst (fst (dequeue q))
| otherwise = let
((tree1, freq1), q') = dequeue q
((tree2, freq2), q'') = dequeue q'
freqSum = freq1 + freq2
newTree = joinWith ('.', freqSum) tree1 tree2
in
reduceNodes (enqueue (newTree, freqSum) q'')
Since the types check out, I successfully compiled a stack project with these modules. When you think you have the Huffman Tree-building code you want, you can just fill in the undefined functions with what they're actually supposed to do and you're good!

Binomial Heap implementation in Haskell

I'm trying to implement a Binomial Heap in Haskell, using the book "Purely Functional Data Structures" Chris Okasaki.
{- Implemetation of Binomial Heap-}
module BinomialHeap where
{- Definition of a Binomial Tree -}
data BTree a = Node Int a ([BTree a]) deriving Show
{- Definition of a Binomial Heap -}
data BHeap a = Heap [BTree a] deriving Show
empty :: BHeap a
empty = Heap []
{- Linking function tree -}
-- w/ larger root is
-- linked w/ tree w/ lower root -}
link :: Ord a => BTree a -> BTree a -> BTree a
link t1#(Node r x1 c1) t2#(Node _ x2 c2) =
if x1 < x2 then
Node (r+1) x1 (t2:c1)
else
Node (r+1) x2 (t1:c2)
root :: BTree a -> a
root (Node _ x _) = x
{- Gives the rank of the Binomial Tree-}
rank :: BTree a -> Int
rank (Node r _ _ ) = r
{- Insertion in the tree -}
-- Create a new singl. tree
-- Step through the existing trees in increasing order
-- until we find a missing rank
-- link tree of equal ranks
-- atm it's O(log n)
insTree :: Ord a => BTree a -> [BTree a] -> [BTree a]
insTree t [] = [t]
insTree t ts1#(t1':ts1') =
if rank t > rank t1' then
t:ts1
else
insTree (link t t1') ts1'
insert :: Ord a => BHeap a -> a -> BHeap a
insert (Heap ts) x = Heap $ insTree (Node 0 x []) ts
{- Merge of Heaps-}
-- We step through both list of tree in increasing order
-- link tree of equal root
merge :: Ord a => [BTree a] -> [BTree a] -> [BTree a]
merge [] ts = ts
merge ts [] = ts
merge ts1#(t1:ts1') ts2#(t2:ts2') =
if rank t1 < rank t2 then
t1:merge ts1' ts2
else if rank t2 < rank t1 then
t2:merge ts1 ts2'
else
insTree (link t1 t2) (merge ts1' ts2')
sampleHeap :: BHeap Int
sampleHeap = foldl insert empty [1, 2, 3]
The problem is that insertion gives me an output that isn't right :
Heap [Node 1 1 [Node 0 3 [],Node 0 2 []]]
The insertion primitive might not be correct. Okasaki says :
"To insert a new element into a heap, we first create a new singleton tree (rank 0). We then step through the existing trees in increasing order of rank until we find a missing rank, linking tree of equal rank as we go. Each link corresponds to a carry in binary arithmetic"
Can you help me find where there can be an error in the insertions primitives ?
Thank you.
From page 71 of Okasaki's paper (https://www.cs.cmu.edu/~rwh/theses/okasaki.pdf):
For reasons that will become clear later, we maintain the list of
trees representing a heap in increasing order of rank, but maintain
the list of trees representing the children of a node in decreasing
order of rank.
Let's look at your insTree function in light of this statement:
insTree :: Ord a => BTree a -> [BTree a] -> [BTree a]
insTree t [] = [t]
insTree t ts1#(t1':ts1') =
if rank t > rank t1' then
t:ts1
else
insTree (link t t1') ts1'
Pay attention to the case where the list of binomial trees isn't empty. The code there says if the rank of the tree being inserted is greater than the rank of next tree in the list, prepend the tree to the list. This violates the assumption that the list of trees representing a heap is organized in increasing order of rank. Reversing the sign from > to < in the comparison should fix the problem.

build a tree with given number of nodes

I have a datastructure for a tree with nodes that have either one or two childs. I can generate a random tree with a given maximum Depth. Now I want to generate these random three with a given maximum amount of nodes (/leafes). This is my structure:
import System.Random
data Tree a = Leaf
| NodeTwo (Tree a) (Tree a)
| NodeOne (Tree a)
deriving (Show)
create :: RandomGen g => Int -> Int -> Int -> Int -> g -> Tree a
create depth maxNodeOne maxNodeTwo maxLeaf g
| (depth == 0) = Leaf
| (x >= a && x < c && (maxNodeTwo /= 0))
= let (g1, g2) = split g in
NodeTwo (create (depth -1) maxNodeOne (maxNodeTwo-1)
maxLeaf g1) (create (depth -1) maxNodeOne
(maxNodeTwo-1) maxLeaf g2)
|(x >= c && x < 2*c && (maxNodeOne /= 0))
= NodeOne (create (depth -1)
(maxNodeOne -1) maxNodeTwo maxLeaf g')
| otherwise = Leaf
where (x, g') = next g
(a, b) = genRange g
c = (b - a) `div` 3
countFnk :: Tree a -> Int
countFnk (Leaf) = 0
countFnk (NodeOne a) = countFnk a
countFnk (NodeTwo a b) = 1 + countFnk a + countFnk b
countLam :: Tree a -> Int
countLam (Leaf) = 0
countLam (NodeOne a) = 1 + countLam a
countLam (NodeTwo a b) = countLam a + countLam b
countLeaf :: Tree a -> Int
countLeaf (Leaf) = 1
countLeaf (NodeOne a) = countLeaf a
countLeaf (NodeTwo a b) = countLeaf a + countLeaf b
This attempt fails ofcourse. I don't know how to decrement the counter(s) for the node(s) in the recursion. I also have functions which can get me the amount of nodes (/leafes) but I don't know how to use these functions in my create function since they need a finished tree to scan.
Thanks for your help.
The most obvious problem is in your NodeTwo case. You arrive at that point with a "budget" of NodeTwos and NodeOnes to spend. But you tell both branches of your new tree the same thing: "feel free to spend the whole total budget"! Of course if they both do that, you will wind up spending double your budget.
You need some way to negotiate a budget for each branch of the tree. There are a number of ways you could do this; for example, give one branch access to the whole budget, and give whatever is left to the second branch. Or you could decide before creating either branch how to divide the budget between them, and give each branch only a portion of your total budget.
Either of those two approaches probably introduce some bias in your randomness, which may or may not matter to you. You should think of a way to handle the budget accounting in a way that produces the kinds of random trees you want.
Once you've fixed this, you'll run into other problems: there are constraint sets for which it is impossible to build a tree fitting them! Most notably, if maxLeaf is zero, you can't create any kind of tree at all, since every tree has at least one leaf node somewhere. You'll have to be careful not to build any subtrees with too few leaves available to let them terminate.

Finding element in a binary tree

Assume I have a binary tree:
data Bst a = Empty | Node (Bst a) a (Bst a)
I have to write a function that searches for a value and returns the number of its children. If there is no node with this value, it returns -1. I was trying to write both BFS and DFS, and I failed with both.
Pattern matching is your friend. Your Bst can either be Empty or a Node, so at the toplevel, your search function will be
search Empty = ...
search (Node left x right) = ...
Can an Empty tree possibly contain the target value? With a Node the target value, if present, will be either the node value (x above), in the left subtree, in the right subtree—or perhaps some combination of these.
By “return[ing] the number of its children,” I assume you mean the total number of descendants of the Bst rooted at a Node whose value is the target, which is an interesting combination of problems. You will want another function, say numChildren, whose definition uses pattern matching as above. Considerations:
How many descendants does an Empty tree have?
In the Node case, x doesn’t count because you want descendants. If only you had a function to count the number of children in the left and right subtrees …
Here is a way to do this. Breath-first search can actually be a bit tricky to implement and this solution (findBFS) has aweful complexity (appending to the list is O(n)) but you'll get the gist.
First I have decided to split out the finding functions to return the tree where the node element matches. That simplifies splitting out the counting function. Also, it is easier to return the number of elements than the number of descendants and return -1 in case not found, so the numDesc functions rely on the numElements function.
data Tree a = Empty
| Node a (Tree a) (Tree a)
numElements :: Tree a -> Int
numElements Empty = 0
numElements (Node _ l r) = 1 + numElements l + numElements r
findDFS :: Eq a => a -> Tree a -> Tree a
findDFS _ Empty = Empty
findDFS x node#(Node y l r) | x == y = node
| otherwise = case findDFS x l of
node'#(Node _ _ _) -> node'
Empty -> findDFS x r
findBFS :: Eq a => a -> [Tree a] -> Tree a
findBFS x [] = Empty
findBFS x ((Empty):ts) = findBFS x ts
findBFS x (node#(Node y _ _):ts) | x == y = node
findBFS x ((Node _ l r):ts) = findBFS x (ts ++ [l,r])
numDescDFS :: Eq a => a -> Tree a -> Int
numDescDFS x t = numElements (findDFS x t) - 1
numDescBFS :: Eq a => a -> Tree a -> Int
numDescBFS x t = numElements (findBFS x [t]) - 1

Resources