From 8d89c02113402652d9c91a80cd2540521ab47038 Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Sat, 7 Jan 2012 21:27:57 +0100 Subject: [PATCH] Pattern Probability Table: Introduce basic infrastructure --- Makefile | 2 +- patternprob.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++++++ patternprob.h | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 127 insertions(+), 1 deletion(-) create mode 100644 patternprob.c create mode 100644 patternprob.h diff --git a/Makefile b/Makefile index bfedb57..a19dc71 100644 --- a/Makefile +++ b/Makefile @@ -91,7 +91,7 @@ unexport INCLUDES INCLUDES=-I. -OBJS=board.o gtp.o move.o ownermap.o pattern3.o pattern.o patternsp.o playout.o probdist.o random.o stone.o timeinfo.o network.o fbook.o +OBJS=board.o gtp.o move.o ownermap.o pattern3.o pattern.o patternsp.o patternprob.o playout.o probdist.o random.o stone.o timeinfo.o network.o fbook.o SUBDIRS=random replay patternscan joseki montecarlo uct uct/policy playout tactics t-unit distributed all: all-recursive pachi diff --git a/patternprob.c b/patternprob.c new file mode 100644 index 0000000..6173417 --- /dev/null +++ b/patternprob.c @@ -0,0 +1,59 @@ +#define DEBUG +#include +#include +#include +#include + +#include "board.h" +#include "debug.h" +#include "pattern.h" +#include "patternsp.h" +#include "patternprob.h" + + +struct pattern_pdict * +pattern_pdict_init(char *filename, struct pattern_config *pc) +{ + if (!filename) + filename = "patterns.prob"; + FILE *f = fopen(filename, "r"); + if (!f) { + if (DEBUGL(1)) + fprintf(stderr, "No pattern probtable, will not use learned patterns.\n"); + return NULL; + } + + struct pattern_pdict *dict = calloc2(1, sizeof(*dict)); + dict->pc = pc; + dict->table = calloc2(pc->spat_dict->nspatials + 1, sizeof(*dict->table)); + + char sbuf[1024]; + while (fgets(sbuf, sizeof(sbuf), f)) { + struct pattern_prob *pb = calloc2(1, sizeof(*pb)); + int c, o; + + char *buf = sbuf; + if (buf[0] == '#') continue; + while (isspace(*buf)) buf++; + while (!isspace(*buf)) buf++; // we recompute the probability + while (isspace(*buf)) buf++; + c = strtol(buf, &buf, 10); + while (isspace(*buf)) buf++; + o = strtol(buf, &buf, 10); + pb->prob = (floating_t) c / o; + while (isspace(*buf)) buf++; + str2pattern(buf, &pb->p); + + uint32_t spi = pattern2spatial(dict, &pb->p); + if (!dict->table[spi]) { + dict->table[spi] = pb; + } else { + struct pattern_prob *ppb = dict->table[spi]; + while (ppb->next) ppb = ppb->next; + ppb->next = pb; + } + } + + fclose(f); + return dict; +} diff --git a/patternprob.h b/patternprob.h new file mode 100644 index 0000000..198a147 --- /dev/null +++ b/patternprob.h @@ -0,0 +1,67 @@ +#ifndef PACHI_PATTERNPROB_H +#define PACHI_PATTERNPROB_H + +/* Pattern probability table. */ + +#include + +#include "board.h" +#include "move.h" +#include "pattern.h" + + +/* The pattern probability table considers each pattern as a whole + * (not dividing it to individual features) and stores probability + * of the pattern being played. */ + +/* The table primary key is the pattern spatial (most distinctive + * feature); within a single primary key chain, the entries are + * unsorted (for now). */ + +struct pattern_prob { + struct pattern p; + floating_t prob; + struct pattern_prob *next; +}; + +struct pattern_pdict { + struct pattern_config *pc; + + struct pattern_prob **table; /* [pc->spat_dict->nspatials + 1] */ +}; + +/* Initialize the pdict data structure from a given file (pass NULL + * to use default filename). Returns NULL if the file with patterns + * has been found. */ +struct pattern_pdict *pattern_pdict_init(char *filename, struct pattern_config *pc); + +/* Return probability associated with given pattern. Returns NaN if + * the pattern cannot be found. */ +static floating_t pattern_prob(struct pattern_pdict *dict, struct pattern *p); + +/* Utility function - extract spatial id from a pattern. If the pattern + * has no spatial feature, it is represented by the highest spatial id + * plus one. */ +static uint32_t pattern2spatial(struct pattern_pdict *dict, struct pattern *p); + + +static inline floating_t +pattern_prob(struct pattern_pdict *dict, struct pattern *p) +{ + uint32_t spi = pattern2spatial(dict, p); + for (struct pattern_prob *pb = dict->table[spi]; pb; pb = pb->next) + if (pattern_eq(p, &pb->p)) + return pb->prob; + return NAN; // XXX: We assume quiet NAN existence +} + +static inline uint32_t +pattern2spatial(struct pattern_pdict *dict, struct pattern *p) +{ + for (int i = 0; i < p->n; i++) + if (p->f[i].id == FEAT_SPATIAL) + return p->f[i].payload; + return dict->pc->spat_dict->nspatials; +} + +#endif -- 2.11.4.GIT