mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-01-31 11:01:40 +00:00
Added contribution from Ian Clarke.
This commit is contained in:
parent
529deac28b
commit
f42f6c0b2c
101
grendel/filters/Applet.java
Normal file
101
grendel/filters/Applet.java
Normal file
@ -0,0 +1,101 @@
|
||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the GFilt filter package, as integrated into
|
||||
* the Grendel mail/news reader.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ian Clarke.
|
||||
* Portions created by Ian Clarke are
|
||||
* Copyright (C) 2000 Ian Clarke. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
|
||||
package grendel.filters; // formerly GFilt
|
||||
|
||||
import java.awt.*;
|
||||
import java.applet.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
public class Applet extends java.applet.Applet
|
||||
{
|
||||
|
||||
/**
|
||||
* The constructor, creates the Applet
|
||||
*/
|
||||
public Applet()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the browser or applet viewer to inform
|
||||
* this applet that it has been loaded into the system. It is always
|
||||
* called before the first time that the <code>start</code> method is
|
||||
* called.
|
||||
* <p>
|
||||
* A subclass of <code>Applet</code> should override this method if
|
||||
* it has initialization to perform. For example, an applet with
|
||||
* threads would use the <code>init</code> method to create the
|
||||
* threads and the <code>destroy</code> method to kill them.
|
||||
* <p>
|
||||
* The implementation of this method provided by the
|
||||
* <code>Applet</code> class does nothing.
|
||||
*/
|
||||
public void init()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the browser or applet viewer to inform
|
||||
* this applet that it should start its execution. It is called after
|
||||
* the <code>init</code> method and each time the applet is revisited
|
||||
* in a Web page.
|
||||
* <p>
|
||||
* A subclass of <code>Applet</code> should override this method if
|
||||
* it has any operation that it wants to perform each time the Web
|
||||
* page containing it is visited. For example, an applet with
|
||||
* animation might want to use the <code>start</code> method to
|
||||
* resume animation, and the <code>stop</code> method to suspend the
|
||||
* animation.
|
||||
* <p>
|
||||
* The implementation of this method provided by the
|
||||
* <code>Applet</code> class does nothing.
|
||||
*
|
||||
*/
|
||||
public void start()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by the browser or applet viewer to inform
|
||||
* this applet that it should stop its execution. It is called when
|
||||
* the Web page that contains this applet has been replaced by
|
||||
* another page, and also just before the applet is to be destroyed.
|
||||
* <p>
|
||||
* A subclass of <code>Applet</code> should override this method if
|
||||
* it has any operation that it wants to perform each time the Web
|
||||
* page containing it is no longer visible. For example, an applet
|
||||
* with animation might want to use the <code>start</code> method to
|
||||
* resume animation, and the <code>stop</code> method to suspend the
|
||||
* animation.
|
||||
* <p>
|
||||
* The implementation of this method provided by the
|
||||
* <code>Applet</code> class does nothing.
|
||||
*
|
||||
*/
|
||||
public void stop()
|
||||
{
|
||||
}
|
||||
|
||||
}
|
194
grendel/filters/Breeder.java
Normal file
194
grendel/filters/Breeder.java
Normal file
@ -0,0 +1,194 @@
|
||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the GFilt filter package, as integrated into
|
||||
* the Grendel mail/news reader.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ian Clarke.
|
||||
* Portions created by Ian Clarke are
|
||||
* Copyright (C) 2000 Ian Clarke. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
package grendel.filters; // formerly GFilt
|
||||
|
||||
public class Breeder
|
||||
{
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
/**
|
||||
* A list of strings that should "pass" the filter
|
||||
**/
|
||||
String[] pos = {"sdfviawnasdvb","asdciainasdf","erpianwdr"};
|
||||
|
||||
/**
|
||||
* A list of strings that should "fail" the filter
|
||||
**/
|
||||
String[] neg = {"sdfviarnasdvb","asdciwanasdf","eriyanwdr"};
|
||||
|
||||
System.out.println("Best: "+evolve(pos, neg, 500));
|
||||
}
|
||||
|
||||
public static Filter evolve(String[] pos, String[] neg, int popSz)
|
||||
{
|
||||
Breeder b = new Breeder(pos,neg,popSz);
|
||||
float bestScore = 0, lastBestScore = -1;
|
||||
int BSrun=0;
|
||||
for (int x=0; (x<1000 && BSrun < 20); x++)
|
||||
{
|
||||
b.scoreAll();
|
||||
bestScore = b.getBestScore();
|
||||
if (bestScore == lastBestScore)
|
||||
{
|
||||
BSrun++;
|
||||
}
|
||||
else
|
||||
{
|
||||
BSrun = 0;
|
||||
lastBestScore = bestScore;
|
||||
}
|
||||
System.out.println(""+x+":"+bestScore+":"+b.getBest());
|
||||
b.updatePop();
|
||||
}
|
||||
return b.getBest();
|
||||
}
|
||||
|
||||
protected String[] positives, negatives;
|
||||
protected float[] scores;
|
||||
protected int totalScore = 0;
|
||||
protected Filter[] population;
|
||||
protected java.util.Random r = new java.util.Random();
|
||||
protected Mutator mut;
|
||||
|
||||
public Breeder(String[] p, String[] n, int popSz)
|
||||
{
|
||||
this(p, n, null);
|
||||
population = new Filter[popSz];
|
||||
for (int x=0; x<population.length; x++)
|
||||
{
|
||||
population[x] = new Filter();
|
||||
int np = (Math.abs(r.nextInt()) % 10) + 2;
|
||||
for (int y=0; y<np; y++)
|
||||
{
|
||||
mut.addPattern(population[x]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public Breeder(String[] p, String[] n, Filter[] f)
|
||||
{
|
||||
positives = p;
|
||||
negatives = n;
|
||||
population = f;
|
||||
StringBuffer sb = new StringBuffer();
|
||||
for (int x=0; x<p.length; x++)
|
||||
{
|
||||
sb.append(p[x]);
|
||||
}
|
||||
mut = new Mutator(sb.toString());
|
||||
}
|
||||
|
||||
public void updatePop()
|
||||
{
|
||||
Filter[] nextPop = new Filter[population.length];
|
||||
nextPop[0] = getBest();
|
||||
nextPop[1] = new Filter();
|
||||
int np = (Math.abs(r.nextInt()) % 10) + 2;
|
||||
for (int y=0; y<np; y++)
|
||||
{
|
||||
mut.addPattern(nextPop[1]);
|
||||
}
|
||||
for (int x=2; x<nextPop.length; x++)
|
||||
{
|
||||
nextPop[x] = selectRandFilt().duplicate();
|
||||
for (int p=0; p<2;p++)
|
||||
mut.mutate(nextPop[x]);
|
||||
}
|
||||
population = nextPop;
|
||||
}
|
||||
|
||||
public float getBestScore()
|
||||
{
|
||||
float bestScore = scores[0];
|
||||
for (int x=1; x<population.length; x++)
|
||||
{
|
||||
if (scores[x] > bestScore)
|
||||
{
|
||||
bestScore = scores[x];
|
||||
}
|
||||
}
|
||||
return bestScore;
|
||||
}
|
||||
|
||||
public Filter getBest()
|
||||
{
|
||||
Filter best = population[0];
|
||||
float bestScore = scores[0];
|
||||
for (int x=1; x<population.length; x++)
|
||||
{
|
||||
if (scores[x] > bestScore)
|
||||
{
|
||||
bestScore = scores[x];
|
||||
best = population[x];
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
|
||||
protected Filter selectRandFilt()
|
||||
{
|
||||
int p=0, x = Math.abs(r.nextInt()) % totalScore;
|
||||
while(x>=0)
|
||||
{
|
||||
x -= scores[p];
|
||||
p++;
|
||||
}
|
||||
return population[p-1];
|
||||
}
|
||||
|
||||
public void scoreAll()
|
||||
{
|
||||
scores = new float[population.length];
|
||||
float s;
|
||||
totalScore = 0;
|
||||
for (int x=0; x<population.length; x++)
|
||||
{
|
||||
s = score(population[x]);
|
||||
scores[x] = s;
|
||||
totalScore += s;
|
||||
}
|
||||
}
|
||||
|
||||
protected float score(Filter f)
|
||||
{
|
||||
int score = 0;
|
||||
for (int x=0; x<positives.length; x++)
|
||||
{
|
||||
if (f.match(positives[x]))
|
||||
score++;
|
||||
}
|
||||
for (int x=0; x<negatives.length; x++)
|
||||
{
|
||||
if (!(f.match(negatives[x])))
|
||||
score++;
|
||||
}
|
||||
return score + ((float) score/((float) (f.getTLength()+30)));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
238
grendel/filters/Filter.java
Normal file
238
grendel/filters/Filter.java
Normal file
@ -0,0 +1,238 @@
|
||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the GFilt filter package, as integrated into
|
||||
* the Grendel mail/news reader.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ian Clarke.
|
||||
* Portions created by Ian Clarke are
|
||||
* Copyright (C) 2000 Ian Clarke. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
package grendel.filters; // formerly GFilt
|
||||
import java.util.*;
|
||||
|
||||
public class Filter {
|
||||
/**
|
||||
* Set to true to output debugging information
|
||||
**/
|
||||
public boolean debug = false;
|
||||
Pattern patterns = null;
|
||||
|
||||
/**
|
||||
* Get the number of patterns in the filter
|
||||
* @return The number of patterns in the filter
|
||||
**/
|
||||
public int getLength() {
|
||||
Pattern cur = patterns;
|
||||
int r = 0;
|
||||
while (cur != null) {
|
||||
cur = cur.next;
|
||||
r++;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public int getTLength() {
|
||||
Pattern cur = patterns;
|
||||
int r = 0;
|
||||
while (cur != null)
|
||||
{
|
||||
r += cur.str.length() + 1;
|
||||
cur = cur.next;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
public void setString(String str, int p) {
|
||||
Pattern pat = patterns;
|
||||
for (int x = 0; x < p; x++) {
|
||||
pat = pat.next;
|
||||
}
|
||||
pat.str = str;
|
||||
}
|
||||
public void setAnd(boolean and, int p) {
|
||||
Pattern pat = patterns;
|
||||
for (int x = 0; x < p; x++) {
|
||||
pat = pat.next;
|
||||
}
|
||||
pat.and = and;
|
||||
}
|
||||
|
||||
public void del(int p) {
|
||||
if (p == 0) {
|
||||
patterns = patterns.next;
|
||||
} else {
|
||||
Pattern cur = patterns;
|
||||
for (int x = 0; x < (p - 1); x++) {
|
||||
cur = cur.next;
|
||||
}
|
||||
cur.next = cur.next.next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public String getString(int p) {
|
||||
Pattern pat = patterns;
|
||||
for (int x = 0; x < p; x++) {
|
||||
pat = pat.next;
|
||||
}
|
||||
|
||||
return pat.str;
|
||||
|
||||
}
|
||||
|
||||
public boolean getAnd(int p) {
|
||||
Pattern pat = patterns;
|
||||
for (int x = 0; x < p; x++) {
|
||||
pat = pat.next;
|
||||
}
|
||||
return pat.and;
|
||||
}
|
||||
|
||||
public void insert(String s, boolean and, int p) {
|
||||
Pattern n = new Pattern(s, and);
|
||||
Pattern cur = patterns;
|
||||
if (p == 0) {
|
||||
n.next = patterns;
|
||||
patterns = n;
|
||||
} else {
|
||||
for (int x = 0; x < p - 1; x++) {
|
||||
cur = cur.next;
|
||||
}
|
||||
n.next = cur.next;
|
||||
cur.next = n;
|
||||
}
|
||||
}
|
||||
|
||||
public void push(String s, boolean and) {
|
||||
|
||||
if (patterns == null) {
|
||||
patterns = new Pattern(s, and);
|
||||
} else {
|
||||
Pattern p = patterns;
|
||||
|
||||
while (p.next != null) {
|
||||
p = p.next;
|
||||
}
|
||||
p.next = new Pattern(s, and);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean match(String str) {
|
||||
return match(str, 0, patterns);
|
||||
}
|
||||
|
||||
public Filter duplicate()
|
||||
{
|
||||
Filter n = new Filter();
|
||||
Pattern cur = patterns;
|
||||
while(cur != null)
|
||||
{
|
||||
n.push(cur.str, cur.and);
|
||||
cur = cur.next;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
protected boolean match(String str, int pos, Pattern pat)
|
||||
{
|
||||
if (pat == null)
|
||||
{
|
||||
System.err.println("Attempted to match with empty pattern list");
|
||||
return false;
|
||||
}
|
||||
int p = str.indexOf(pat.str, pos);
|
||||
if (debug)
|
||||
System.err.print("Matching "+pat.str + " from "+pos + " - ");
|
||||
if (p == -1) {
|
||||
if (debug)
|
||||
System.err.print("Not found - ");
|
||||
if (pat.next == null) {
|
||||
if (debug)
|
||||
System.err.println("Last pattern - failing");
|
||||
return false;
|
||||
}
|
||||
if (pat.and) {
|
||||
if (debug)
|
||||
System.err.println("And relationship - failing");
|
||||
return false;
|
||||
} else {
|
||||
if (debug)
|
||||
System.err.println("Or relationship - recursing");
|
||||
return match(str, pos, pat.next);
|
||||
}
|
||||
} else {
|
||||
if (debug)
|
||||
System.err.print("Found at "+p + " - ");
|
||||
Pattern tPat = pat;
|
||||
while (!(tPat.and)) {
|
||||
if (tPat.next == null) {
|
||||
if (debug)
|
||||
System.err.println("Last one - success");
|
||||
return true;
|
||||
}
|
||||
tPat = tPat.next;
|
||||
}
|
||||
if (tPat.next == null) {
|
||||
if (debug)
|
||||
System.err.println("All others are 'or' - success");
|
||||
return true;
|
||||
}
|
||||
if (debug)
|
||||
System.err.println("Skipping to end of or group");
|
||||
if (match(str, p + pat.str.length(), tPat.next))
|
||||
return true;
|
||||
else {
|
||||
if (debug)
|
||||
System.err.println("Backtracking..");
|
||||
return (match(str, pos, pat.next));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
StringBuffer s = new StringBuffer();
|
||||
Pattern cur = patterns;
|
||||
while (cur != null) {
|
||||
String andV;
|
||||
if (cur.and)
|
||||
andV = " and then ";
|
||||
else
|
||||
andV = "or";
|
||||
if (cur.next != null)
|
||||
s.append("\""+cur.str + "\" "+andV + " ");
|
||||
else
|
||||
s.append("\""+cur.str + "\"");
|
||||
cur = cur.next;
|
||||
}
|
||||
return s.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class Pattern {
|
||||
public boolean and;
|
||||
public Pattern next = null;
|
||||
public String str;
|
||||
public Pattern(String s, boolean a) {
|
||||
and = a;
|
||||
str = s;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
136
grendel/filters/Mutator.java
Normal file
136
grendel/filters/Mutator.java
Normal file
@ -0,0 +1,136 @@
|
||||
/* -*- Mode: java; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is the GFilt filter package, as integrated into
|
||||
* the Grendel mail/news reader.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Ian Clarke.
|
||||
* Portions created by Ian Clarke are
|
||||
* Copyright (C) 2000 Ian Clarke. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
|
||||
package grendel.filters; // formerly GFilt
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* Allows a filter to be mutated in a variety of ways, using a
|
||||
* string as a source for new material
|
||||
**/
|
||||
public class Mutator
|
||||
{
|
||||
String source;
|
||||
Random r = new Random();
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Mutator s = new Mutator("abcdefghijklmnopqrstuvwxyz");
|
||||
for (int x=0; x<10; x++)
|
||||
System.out.println("\"vwxyz\" -> \""+s.modify("vwxyz")+"\"");
|
||||
}
|
||||
|
||||
public Mutator(String s)
|
||||
{
|
||||
source = s;
|
||||
}
|
||||
|
||||
public void mutate(Filter f)
|
||||
{
|
||||
int p = Math.abs(r.nextInt()) % 4;
|
||||
int ps;
|
||||
ps = (Math.abs(r.nextInt()) % f.getLength());
|
||||
if ((p==0) && (f.getLength() > 1))
|
||||
{ // Delete a pattern
|
||||
f.del(ps);
|
||||
}
|
||||
else if (p==1)
|
||||
{ // Modify a string in a pattern
|
||||
String s = f.getString(ps);
|
||||
f.setString(modify(s), ps);
|
||||
}
|
||||
else if (p==2)
|
||||
{ // Invert the 'and' in a pattern
|
||||
f.setAnd(!(f.getAnd(ps)), ps);
|
||||
}
|
||||
else if (p==3)
|
||||
{ // Add a new pattern
|
||||
addPattern(f);
|
||||
}
|
||||
}
|
||||
|
||||
public void addPattern(Filter f)
|
||||
{
|
||||
|
||||
int ps;
|
||||
if (f.getLength() > 0)
|
||||
ps = (Math.abs(r.nextInt()) % f.getLength());
|
||||
else
|
||||
ps = 0;
|
||||
int len = Math.abs(r.nextInt()) % 10;
|
||||
int pos = Math.abs(r.nextInt()) % (source.length()-len);
|
||||
f.insert(source.substring(pos, pos+len),
|
||||
((r.nextInt() % 2) == 0), ps);
|
||||
}
|
||||
|
||||
public Filter breed(Filter a, Filter b)
|
||||
{
|
||||
Filter shorter, longer, ret = new Filter();
|
||||
if (a.getLength() < b.getLength())
|
||||
{
|
||||
shorter = a;
|
||||
longer = b;
|
||||
}
|
||||
else
|
||||
{
|
||||
shorter = b;
|
||||
longer = a;
|
||||
}
|
||||
int p = (Math.abs(r.nextInt()) % shorter.getLength());
|
||||
for(int x=0; x<p; x++)
|
||||
{
|
||||
ret.push(shorter.getString(x), shorter.getAnd(x));
|
||||
}
|
||||
for(int x=p; x<longer.getLength(); x++)
|
||||
{
|
||||
ret.push(longer.getString(x), longer.getAnd(x));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
protected String modify(String s)
|
||||
{
|
||||
int len = s.length();
|
||||
len += (Math.abs(r.nextInt()) % 6) - 3;
|
||||
if (len < 1)
|
||||
len = 1;
|
||||
int pos = source.indexOf(s);
|
||||
if (pos == -1)
|
||||
{
|
||||
pos = (Math.abs(r.nextInt())% (source.length()-len));
|
||||
}
|
||||
else
|
||||
{
|
||||
pos += (Math.abs(r.nextInt()) % 6) - 3;
|
||||
}
|
||||
if (pos < 1)
|
||||
pos = 1;
|
||||
|
||||
if ((source.length() - pos) < len)
|
||||
{
|
||||
len = source.length() - pos;
|
||||
}
|
||||
|
||||
return source.substring(pos, pos+len);
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user