home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Photo CD Demo 1
/
Demo.bin
/
graphtal
/
productn.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-10-19
|
4KB
|
162 lines
/*
* Production.C - methods for L-System productions.
*
* Copyright (C) 1992, Christoph Streit (streit@iam.unibe.ch)
* All rights reserved.
*
* This software may be freely copied, modified, and redistributed
* provided that this copyright notice is preserved on all copies.
*
* You may not distribute this software, in whole or in part, as part of
* any commercial product without the express consent of the authors.
*
* There is no warranty or other guarantee of fitness of this software
* for any purpose. It is provided solely "as is".
*
*/
#include <stdlib.h>
#include "Production.h"
#include "Error.h"
implementList(SuccessorList, SuccessorPtr);
implementList(ProductionList, ProductionPtr);
//___________________________________________________________ Predecessor
Predecessor::Predecessor(const Name& n, NameList* param)
: name(n), formalParam(param)
{}
Predecessor::~Predecessor()
{
if (formalParam) {
for (long i=0; i<formalParam->count(); i++)
delete formalParam->item(i);
delete formalParam;
}
}
//___________________________________________________________ Successor
Successor::Successor(double p, ProdModuleList* m)
: modules(m), _probability(p)
{}
Successor::~Successor()
{
if (modules) {
for (long i=0; i<modules->count(); i++)
delete modules->item(i);
delete modules;
}
}
// make a ModuleList out of the ProdModuleList of the successor
ModuleList* Successor::clone()
{
ModuleList* retval;
if (modules) {
retval = new ModuleList(modules->count());
for (register long i=0; i<modules->count(); i++)
retval->append(new Module(modules->item(i)));
}
else
retval = new ModuleList;
return retval;
}
ostream& operator<<(ostream& os, Successor& s)
{
os << "-> (" << s.probability() << ") ";
if (s.modules)
for (long i=0; i<s.modules->count(); i++)
os << *s.modules->item(i) << " ";
else
os << "(empty)";
return os;
}
//___________________________________________________________ Production
Production::Production(Predecessor* p, Expression* c, SuccessorList* s)
: _name(p->name), predecessor(p), condition(c), successors(s)
{
arg_count = (p->formalParam) ? (int)p->formalParam->count()
: 0;
stochastic = (successors->count() > 1);
}
Production::~Production()
{
delete predecessor;
if (condition) delete condition;
for (long i=0; i<successors->count(); i++)
delete successors->item(i);
delete successors;
}
// choose a successor out of the successor list and clone it
ModuleList* Production::cloneSuccessor()
{
// if we have more than one successor, choose by random
if (stochastic) {
double p = drand48();
for (register long i=0; i<successors->count(); i++)
if (p <= successors->item(i)->probability())
return successors->item(i)->clone();
// No successor choosen. VERY, VERY BAD!
Error(ERR_PANIC, "cloneSuccessor: no successor choosen");
return NULL;
}
else
return successors->item(0)->clone();
}
// The probabilities of the successor must cumulate to 1. In addition
// a preprocessing is done, e.g.:
// A -> (0.5) B => A -> (0.5) B
// -> (0.5) C -> (1.0) C
// => no arithmetic operation has to be performed will choosing a
// successor
int Production::cumulateProbability()
{
double sum = 0.0;
for (long i=0; i<successors->count(); i++) {
sum += successors->item(i)->probability();
successors->item(i)->probability() = sum;
}
return ((sum > 1.01) ? 1 : 0);
}
int Production::hashValue()
{
extern unsigned int modHash(const char*, long);
return modHash((const char*)_name, (long)arg_count);
}
ostream& operator<<(ostream& os, Production& p)
{
long i;
os << p.predecessor->name;
if (p.predecessor->formalParam) {
os << '(';
for (i=0; i<p.predecessor->formalParam->count()-1; i++)
os << *p.predecessor->formalParam->item(i) << ", ";
os << *p.predecessor->formalParam->item(i) << ")";
}
if (p.condition) os << " : " << *p.condition << ' ';
for (i=0; i<p.successors->count()-1; i++)
os << *p.successors->item(i) << "\n\t";
os << *p.successors->item(i) << '\n';
return os;
}