Ho una serie di dati su una famiglia, e voglio che il software trovi un progetto di casa che si adatti ai dati (che include cose come le preferenze e se vogliono un pool.
L'attuale modo in cui lo sto facendo adesso è piuttosto ingenuo. Esiste un insieme predeterminato di relazioni tra categorie o ruoli, di stanze. Quindi, sulla base dei dati, alloco "aree piscine", per così dire: una certa area per le camere da letto, una certa area per le stanze della "sfera privata" e un'area per le stanze della "sfera pubblica". Attraversando questi "pool" con le stanze richieste ho creato gli oggetti Room
di cui ho bisogno. Tuttavia, anche le relazioni tra loro sono ingenue: ho appena creato un certo numero di variabili che rappresentano ruoli , come mainRoom
, bedroomHub
, diningTable
, ecc. E assegnate queste variabili a qualsiasi oggetto Room
che dovrebbe occupare questo ruolo tramite una serie di dichiarazioni if
.
Se la descrizione del testo non è abbastanza chiara, ecco il codice che ha implementato questa idea. E 'brutto e ridicolo ma è stato abbastanza buono per scopi dimostrativi (ho detto che questo era un lavoro per la mia tesi di Master of Architecture?)
// Constructor, of the House, no irony whatsoever
public House(Input input, BldgProgram bldgProgram)
{
mainList = new List<Room>();
Adjacencies = new List<Tuple<Room, Room>>();
Streetside = input.StreetSides;
MainStreet = input.MainStreet;
var privatePool = bldgProgram.PrivatePool / (GridSize * GridSize);
var publicPool = bldgProgram.PublicPool / (GridSize * GridSize);
var bedroomCount = bldgProgram.BedroomCount;
var kitchenPool = bldgProgram.KitchenPool / (GridSize * GridSize);
if(input.MainStreet == CardinalDirections.East || input.MainStreet == CardinalDirections.West)
Boundary = new Rectangle(input.PlotDepth / GridSize, input.PlotWidth / GridSize);
else
Boundary = new Rectangle(input.PlotWidth / GridSize, input.PlotDepth / GridSize);
var main = AddRoom<LivingRoom>("Main", 12 / GridSize, 16 / GridSize);
privatePool -= main.Area;
Room livingRoom;
if(privatePool > (24 / GridSize) * (12 / GridSize))
{
livingRoom = AddRoom<LivingRoom>(null, 24 / GridSize, 12 / GridSize);
privatePool -= livingRoom.Area;
PairRooms(main, livingRoom);
}
else
{
main.ExtendLength(privatePool);
livingRoom = main;
}
BedroomCtor(input, bldgProgram, bedroomCount, livingRoom);
var desiredRooms = input.Rooms;
Room diningRoom;
if(desiredRooms.HasFlag(InputRooms.DiningRoom)) // Sketch
{
var diningRoomSize = input.Total <= 8 ? 16
: Floor((input.Total - 8d) / 4) * 4 + 16;
// 12 * 16 for 8 people !! more for each extra 4 ppl add 4 ft.
diningRoom = AddRoom<DiningRoom>("Dining", 12 / GridSize, diningRoomSize / (12 * GridSize));
publicPool -= diningRoom.Area;
PairRooms(diningRoom, livingRoom);
}
else
{
livingRoom.ExtendLength(3);
diningRoom = livingRoom;
}
KitchenCtor(input.Total, bldgProgram.Kitchenette, livingRoom, diningRoom, desiredRooms);
#region Desired Rooms
// Ideally the code would cycle through those by the priority made by the client. or CRITERIA
// Check how many flags are satisfied. If the flags are more than a certain percentage:
// create a corridor/or private rooms hub, and connect the extra rooms to it.
// alternatively, if livingRoom has more than a certain number of connection,
// it is extended per extra connection.
//
// TODO TODO TODO
//
// if(publicPool > 0 && desiredRooms.HasFlag(InputRooms.Reception))
// {
// int receptionHallArea = Function(input.Total); // What would that be?
// var reception = AddRoom<Reception>(12 / GridSize, receptionHallArea / (12 * GridSize));
// PairRooms(main, reception);
// publicPool -= reception.Area;
// if(publicPool > receptionHallArea)
// {
// // new Reception Room for te other gender .. maybe?
// }
// else
// {
// reception.ExtendLength(publicPool);
// // There should be an entrypoint variable where I assign to the street in the end.
// }
// }
// if(privatePool > 0 && desiredRooms.HasFlag(InputRooms.Library))
// {
// }
// Go through rooms in desiredRooms. Check if privatePool has enough space.
// Library
// Office
// GameRoom
// w/e
#endregion
}
La regione commentata è qualcosa che intendevo implementare ma non ci sono mai riuscito.
La parte di organizzare effettivamente Room
s nello spazio fisico è in fondo alla mia mente, ed è considerata in cose come determinare la lunghezza di Corridor
. Tuttavia, si trova in un altro punto del codice e viene richiamato solo quando viene creato il grafico House
.
Ora mi sono già laureato, quindi questo progetto è ora un progetto personale piuttosto che uno scolastico. (La politica della mia scuola è che possediamo tutto il nostro lavoro: è una scuola d'arte e immagino che non vogliano rimanere bloccati con troppe cose.) Ho letto alcune cose sulla teoria dei grafi, considerando che potrebbe essere utile per risolvere il problema problema. Mentre non ho ancora idea come vorrei generare un grafico della casa in modo algoritmico, so un paio di cose da controllare:
- Deve essere planare, ish. (Forse dettare più piani se non planare?)
- Posso avere diversi tipi di bordi come porte, finestre, impianti idraulici (le stanze umide devono essere adiacenti), ecc.
- Diversi tipi di nodi: Roofed e Unroofed sono i due più ovvi.
- Ho un piccolo sforzo di Pathing (ho no un'idea su come iniziare con qualcosa di simile, ma se ho già un grafico posso giudicarlo con qualche sorta di algoritmo esistente, no?)
- Costruibilità: aree bilanciate tra diversi piani o quelle sale pubbliche
Una delle cose che ho scoperto è che i grafici sono spesso usati dall'intelligenza artificiale per trovare uno "stato mondiale" desiderato, ma tutto ciò che so del mio stato mondiale è che i criteri soddisfano. Gli algoritmi genetici sembrano essere una risposta diretta a questa domanda, e li uso già per il mio risolutore geometrico (senza molto successo ma questo è un altro argomento). Ho due problemi correlati con loro: sono orribilmente inefficienti (richiedono molto tempo) e anche quando sono dati in tempo sono completamente imprevedibili e imprecisi.
Il codice completo della mia classe House
, se vuoi vedere l'implementazione, può essere trovato qui. Da lì troverai l'intero progetto così com'è attualmente.
tl; dr Un architetto con poca esperienza di codifica sta cercando consigli per la progettazione di un algoritmo in grado di progettare case per lui. Mi manca qualcosa di completamente ovvio? C'è qualcosa che dovrei leggere? Qualunque progetto analogo posso guardare?
PS. Un problema specifico che non ho mai trovato una risposta chiara è come considero il "fuori"? È una cosa avere un enorme nodo a cui tutti i nodi possono connettersi (anche su più livelli)?