View
223
Download
1
Embed Size (px)
Citation preview
SpamBGon + Unix email
The SpamBGon design allows integration with standard UNIX mail handling
UNIX mail processing looks like this: Remote sender -> local mail daemon
(MTA; e.g. sendmail or exim) MTA looks for ~/.forward file MTA pipes mail through .forward .forward decides what to do with mail Can call filter program procmail
from .forward
Putting the parts together Tell .forward to filter your mail through
the procmail program:|/usr/bin/procmail -f-
Set up a .procmailrc file with the following rules:# PATH must include javaPATH=/bin:/usr/bin:/usr/local/binMAILDIR=$HOME/mymaildir:0fw|java BSFTest -k stuff ...
:0:* ^X-Spam-Status: SPAMmy-spam-folder
For More Info...
man procmail man procmailrc man exim man spamassassin
A*
The Basic Setup, Reprise
Puzzle game: set of states+moves Apply a move/action to a state to
generate a next state Group of all states reachable in some
single move from state s are the children/ successors of s
Whole thing forms a directed graph; possibly acyclic, but more usually possessing cycles
Every move associated with a cost: c(s,a,s’)=cost to go from s to s’ via a
Object: find min cost path from start to goal
Some Terminology
Start
Goal
Some Terminology
Start
GoalStates that have been visited; had all childrengenerated == “closed”
Some Terminology
Start
GoalStates that have been generated, but notexamined; children not generated == “open”
Some Terminology
Start
Goal“Open” set forms a “fringe” or “frontier”around closed set.
Some Terminology
Start
GoalGenerating children for s moves it from opento closed and expands frontier. Adds its children to open.
s
Some Terminology
Start
Goal
s
Length of shortest path from start to s: g(s)
Some Terminology
Start
Goal
s
Length of shortest path from start to s: g(s)
Note! May bemultiple paths to s --not guaranteed thatfirst path to s isshortest path to it!
Some Terminology
Start
Goal
s
Estimated shortest dist froms to goal == h(s)(this is the heuristic function)
h(s)
Some Terminology
Start
Goal
s
g(s)+h(s)=f(s)Estimated total cost fromstart to goal
h(s)
Search Strategies
Closed list (set) things can be ignored Hard problem: which open list (set) thing
do we examine next? Strategies:
Smallest h(s)
Search Strategies
Closed list (set) things can be ignored Hard problem: which open list (set) thing
do we examine next? Strategies:
Smallest h(s) -- “greedy” search
Search Strategies
Closed list (set) things can be ignored Hard problem: which open list (set) thing
do we examine next? Strategies:
Smallest h(s) -- “greedy” search Smallest g(s)
Search Strategies
Closed list (set) things can be ignored Hard problem: which open list (set) thing
do we examine next? Strategies:
Smallest h(s) -- “greedy” search Smallest g(s) -- Breadth-first search
(BFS)
Search Strategies
CLOSED list (set) things can be ignored Hard problem: which OPEN list (set) thing
do we examine next? Strategies:
Smallest h(s) -- “greedy” search Smallest g(s) -- Breadth-first search
(BFS) Ignore h() and g(); just take things off
OPEN in LIFO order
Search Strategies
CLOSED list (set) things can be ignored Hard problem: which OPEN list (set) thing
do we examine next? Strategies:
Smallest h(s) -- “greedy” search Smallest g(s) -- Breadth-first search
(BFS) Ignore h() and g(); just take things off
OPEN in LIFO order -- Depth-first search (DFS)
Search Strategies
CLOSED list (set) things can be ignored Hard problem: which OPEN list (set) thing
do we examine next? Strategies:
Smallest h(s) -- “greedy” search Smallest g(s) -- Breadth-first search (BFS) Ignore h() and g(); just take things off
OPEN in LIFO order -- Depth-first search (DFS)
Smallest f(s) -- “Algorithm A”
From “A” to “A*” Unless we add additional conditions,
Algorithm A is not guaranteed to do any better than anything else
Recall roll of h(s) -- the heuristic Estimate of smallest cost from s to goal
We will restrict h(s) to be admissible Defn: Let h*(s) be the true min cost to
goal Defn: Heuristic h(s) is admissible iff
h(s)≤h*(s) s An admissible heuristic is an underestimate
of how hard it is to get to the goal -- optimistic
Algorithm A + admissible h() -> A*
From A* to Dijkstra’s A* guarantees:
When the goal is first opened, we will have the shortest path to the goal
I.e., as soon as you find the goal, you can stop and know you have the optimal path
Does not guarantee that you have the shortest path to any other node
Need additional constraint on heuristic Defn: Iff h(s)≤c(s,a,s’)+h(s’) then h(s) is
monotonic (a.k.a., consistent) A* + monotonic heuristic Dijkstra’s alg Guarantees that first path to any node is
shortest
Exercise
For the 15-puzzle (4^2-1) c(s,a,s’)=1 a, s s’ Examine the following heuristics: are they
admissible? Monotonic? Are they equivalent to other things you’ve seen? h(s)=0 s h(s)=37.2 s h(s)= s h(s)=“# tiles out of place” s
Can you construct an admissible, but non-monotonic heuristic?
Keeping Track...
Problem: if h() is not monotonic, can’t guarantee that you’re truly finished with anything on CLOSED
Might be able to find something a second time by a shorter path
Keeping Track...
Start
Goal
Keeping Track...
Start
Goal
s
Keeping Track...
Start
Goal
s
Keeping Track...
Start
Goal
s
Keeping Track...
Problem: if h() is not monotonic, can’t guarantee that you’re truly finished with anything on CLOSED
Might be able to find something a second time by a shorter path
Could have better path to something on CLOSED or on OPEN
Have to update that node with new “best path” to it Also have to handle all children!
How?
The Algorithm, Piece by Piece
CLOSED={}; OPEN={ START }
The Algorithm, Piece by Piece CLOSED={}; OPEN={ START } while (!OPEN.isEmpty())
s=OPEN.getFirst();
The Algorithm, Piece by Piece CLOSED={}; OPEN={ START } while (!OPEN.isEmpty())
s=OPEN.getFirst(); if (s.goalP()) { return path-to-s; }
The Algorithm, Piece by Piece CLOSED={}; OPEN={ START } while (!OPEN.isEmpty())
s=OPEN.getFirst(); if (s.goalP()) { return path-to-s; } cIter=s.children();
The Algorithm, Piece by Piece CLOSED={}; OPEN={ START } while (!OPEN.isEmpty())
s=OPEN.getFirst(); if (s.goalP()) { return path-to-s; } cIter=s.children(); while (cIter.hasNext())
The Algorithm, Piece by Piece CLOSED={}; OPEN={ START } while (!OPEN.isEmpty())
s=OPEN.getFirst(); if (s.goalP()) { return path-to-s; } cIter=s.children(); while (cIter.hasNext())
child=cIter.next();
The Algorithm, Piece by Piece CLOSED={}; OPEN={ START } while (!OPEN.isEmpty())
s=OPEN.getFirst(); if (s.goalP()) { return path-to-s; } cIter=s.children(); while (cIter.hasNext())
child=cIter.next(); if (CLOSED.contains(child)) {
if (child.heuristic() < CLOSED.get(child).heuristic())
The Algorithm, Piece by Piece CLOSED={}; OPEN={ START } while (!OPEN.isEmpty())
s=OPEN.getFirst(); if (s.goalP()) { return path-to-s; } cIter=s.children(); while (cIter.hasNext())
child=cIter.next(); if (CLOSED.contains(child)) {
if (child.heuristic() < CLOSED.get(child).heuristic()) {
// remove child from CLOSED; // insert child into OPEN; // discard version from CLOSED. // Why?
}
The Algorithm, Piece by Piece CLOSED={}; OPEN={ START } while (!OPEN.isEmpty())
s=OPEN.getFirst(); if (s.goalP()) { return path-to-s; } cIter=s.children(); while (cIter.hasNext())
child=cIter.next(); if (CLOSED.contains(child)) {
if (child.heuristic() < CLOSED.get(child).heuristic()) {
// remove child from CLOSED; // insert child into OPEN; // discard version from CLOSED. // Why?
} else { // discard child and cont }
}
The Algorithm, Piece by Piece else if (OPEN.contains(child))
if (child.heuristic() <
OPEN.get(child).heuristic()) {
The Algorithm, Piece by Piece else if (OPEN.contains(child))
if (child.heuristic() <
OPEN.get(child).heuristic()) { // remove prev version of child from // OPEN and insert new child }
The Algorithm, Piece by Piece else if (OPEN.contains(child))
if (child.heuristic() <
OPEN.get(child).heuristic()) { // remove prev version of child from // OPEN and insert new child } else { // discard child and continue }
}
The Algorithm, Piece by Piece else if (OPEN.contains(child))
if (child.heuristic() <
OPEN.get(child).heuristic()) { // remove prev version of child from // OPEN and insert new child } else { // discard child and continue }
} else { // child not on OPEN or CLOSED OPEN.insert(child); }
The Algorithm, Piece by Piece else if (OPEN.contains(child))
if (child.heuristic() <
OPEN.get(child).heuristic()) { // remove prev version of child from // OPEN and insert new child } else { // discard child and continue }
} else { // child not on OPEN or CLOSED OPEN.insert(child); }
CLOSED.insert(s);