summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'src/knowledge/knowledge_get_random_sequence.c')
-rw-r--r--src/knowledge/knowledge_get_random_sequence.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/src/knowledge/knowledge_get_random_sequence.c b/src/knowledge/knowledge_get_random_sequence.c
new file mode 100644
index 0000000..60a075f
--- /dev/null
+++ b/src/knowledge/knowledge_get_random_sequence.c
@@ -0,0 +1,89 @@
+#include <stdlib.h>
+
+#include "../core/char.h"
+#include "../core/index.h"
+
+#include "../sequence/sequence.h"
+
+#include "../error/error.h"
+
+#include "knowledge.h"
+
+static int weighted_random_pick
+(
+ const struct JH_knowledge_sequence_collection sc [const restrict static 1],
+ const JH_index sum,
+ JH_index result [const restrict static 1]
+)
+{
+ JH_index accumulator, random_number;
+
+ accumulator = 0;
+
+ if (sum == 0)
+ {
+ return -1;
+ }
+
+ random_number = JH_index_random_up_to(sum);
+ /*@ ensures (0 <= random_number <= weights_sum); @*/
+
+ *result = 0;
+
+ for (;;)
+ {
+ accumulator += sc->sequences_ref[*result].occurrences;
+
+ if (accumulator < random_number)
+ {
+ *result += 1;
+ }
+ else
+ {
+ *result = sc->sequences_ref[*result].id;
+
+ return 0;
+ }
+ }
+}
+
+int JH_knowledge_copy_random_swt_sequence
+(
+ const struct JH_knowledge k [const static 1],
+ JH_index sequence [const restrict static 1],
+ const JH_index word_id,
+ const JH_index markov_order,
+ FILE io [const restrict static 1]
+)
+{
+ JH_index sequence_id;
+
+ if
+ (
+ weighted_random_pick
+ (
+ &(k->words[word_id].swt),
+ k->words[word_id].occurrences,
+ &sequence_id
+ ) < 0
+ )
+ {
+ JH_S_PROG_ERROR
+ (
+ io,
+ "Knowledge inconsistency; there are no acceptable markov sequences "
+ "linked to a word that has been picked as being an acceptable pillar."
+ )
+ ;
+ return -1;
+ }
+
+ memcpy
+ (
+ (void *) sequence,
+ (const void *) k->sequences[sequence_id],
+ (((size_t) (markov_order - 1)) * sizeof(JH_index))
+ );
+
+ return 0;
+}