/
main.cpp
294 lines (249 loc) · 8.87 KB
/
main.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
/*
======================================
| Aufgabe 1 |
| Der Script-Tim @ 33.BwInf 2014/'15 |
| |
======================================
*/
/* Benötigte Header einbinden */
#include <iostream>
#include <string>
#include <vector>
using namespace std;
//Klasse Behaelter; erleichtert die verarbeitung der Behälter
class Behaelter{
public:
unsigned int besitzer;
unsigned int kapazitaet;
unsigned int inhalt;
bool voll(void){ //voll?
return (inhalt >= kapazitaet) ? true: false;
}
bool leer(void){ //leer?
return (inhalt <= 0) ? true : false;
}
unsigned int frei(void){ //Freier Platz
return (kapazitaet - inhalt);
}
Behaelter(unsigned int b, unsigned int k, unsigned int i){
besitzer = b;
kapazitaet = k;
inhalt = i;
}
};
//Pfad-Struktur
struct StructPfad{
unsigned int source;
unsigned int target;
};
//Struktur eines Zustandes
struct StructZustaende{
vector<StructPfad> pfad;
vector<Behaelter> behaelter;
};
vector<StructZustaende> zustaende;
vector<vector<StructPfad>> loesungen; //Hier werden die Lösungen gesammelt
unsigned int SummeInhalt = 0; //Summe des Inhaltes insgesamt
/* In dieser Funktion wird die eigentliche Umfüllung vorgenommen: von behaelter[sourceID] => behaelter[targetID] */
vector<Behaelter> umfuellen(vector<Behaelter> behaelter, unsigned int sourceID, unsigned int targetID){
//Umfüllen
if (behaelter[sourceID].inhalt == behaelter[targetID].frei()){ //Passt genau
behaelter[sourceID].inhalt = 0;
behaelter[targetID].inhalt = behaelter[targetID].kapazitaet;
}else if (behaelter[sourceID].inhalt > behaelter[targetID].frei()){ //Zu viel Inhalt in source für target
behaelter[sourceID].inhalt -= behaelter[targetID].frei();
behaelter[targetID].inhalt = behaelter[targetID].kapazitaet;
}else{ //Zu wenig Inhalt in source für target
behaelter[targetID].inhalt += behaelter[sourceID].inhalt;
behaelter[sourceID].inhalt = 0;
}
return behaelter;
}
/* Ermittelt, ob ein Zustand 'zustand' bereits vorhanden ist */
bool zustandVorhanden(vector<Behaelter> zustand){
for(unsigned int x = 0; x < zustaende.size(); x++){
bool gleich = true;
for(unsigned int y = 0; y < zustand.size(); y++){
if (zustaende[x].behaelter[y].inhalt != zustand[y].inhalt) gleich = false;
}
if (gleich == true) return true;
}
return false;
}
/* Diese Funktion ermittelt zunächst, ob ein Zustand 'zustand' bereits vorhanden (in zustaende) inst.
Falls nein, wird der Zustand gesetzt.
Falls ja, wird die Anzahl der benötigten Umfüllungen verglichen; ist die aktuelle geringer, überschreibt sie die alte */
bool setZustand(vector<Behaelter> zustand, vector<StructPfad> pfad){
//Zustand vorhanden?
if (zustandVorhanden(zustand)){
unsigned int id = 0;
for(unsigned int x = 0; x < zustaende.size(); x++){
bool gleich = true;
for (unsigned int y = 0; y < zustaende[x].behaelter.size(); y++){
if (zustand[y].inhalt != zustaende[x].behaelter[y].inhalt ) gleich = false;
}
if (gleich == true) id = x;
}
if (zustaende[id].pfad.size() > pfad.size()){
//Zustand überschreiben
StructZustaende temp;
temp.pfad = pfad;
temp.behaelter = zustand;
zustaende[id] = temp;
}else{
return false;
}
}else{
//Zustand belegen
StructZustaende temp;
temp.pfad = pfad;
temp.behaelter = zustand;
zustaende.push_back(temp);
return true;
}
}
/* Überprüft, ob der Inhalt gleich auf die Personen verteilt ist */
bool checkGleichVerteilt(vector<Behaelter> behaelter){
int BesitzPerson[2] = {0, 0};
for (unsigned int x = 0; x < behaelter.size(); x++){
if (behaelter[x].besitzer == 1){
BesitzPerson[0] += behaelter[x].inhalt;
}else{
BesitzPerson[1] += behaelter[x].inhalt;
}
}
return (BesitzPerson[0] == (SummeInhalt/2) && BesitzPerson[0] == BesitzPerson[1]) ? true : false;
}
/* Schleifen- Funktion */
void loop (vector<Behaelter> behaelter, vector<StructPfad> pfad ){
//Gleich verteilt?
if (checkGleichVerteilt(behaelter)){
loesungen.push_back (pfad);//Lösungen hinzufügen
return; //und Ende
}
//Sonst wird die Schleife weiter vertieft
for(unsigned int sourceID = 0; sourceID < behaelter.size(); sourceID++){
for(unsigned int targetID = 0; targetID < behaelter.size(); targetID++){
if (sourceID != targetID && !behaelter[sourceID].leer() && !behaelter[targetID].voll()){
//Umfüllung simulieren
vector<Behaelter> tempBehaelter = umfuellen(behaelter, sourceID, targetID);
//Pfad vervollständigen
vector<StructPfad> tempPfad = pfad;
StructPfad temp;
temp.source = sourceID;
temp.target = targetID;
tempPfad.push_back (temp);
//Wenn der Zustand der nächsten Umfüllung noch nicht erreicht war oder den alten überschrieben hat, wird die Schleife fortgesetzt
if (setZustand(tempBehaelter, tempPfad)){
loop(tempBehaelter, tempPfad);
}
}
}
}
return;
}
int main(void){ //PROGRAMMSTART
cout << "\n";
cout << "**************************************************\n";
cout << "* Aufgabe 1 *\n";
cout << "* Der Script-Tim @ 33.BwInf 2014/'15 *\n";
cout << "**************************************************\n";
/* Eingabe der Behälter durch den Benutzer */
vector<Behaelter> behaelter;
char c = 'n';
do{
//Wenn c != '', eingabe
if (c == 'j'){
unsigned int besitzer = 0, kapazitaet = 0, inhalt = 0;
cout << "\n\n***** Neuen Behaelter erstellen *****";
do{
cout << "\nBesitzer des neuen Behaelters: [0/1]:";
cin >> besitzer;
}while(besitzer < 0 || besitzer > 1);
do{
cout << "\nKapazitaet des Behaelters [Ma(ss)e Wein]:";
cin >> kapazitaet;
}while(kapazitaet < 0);
do{
cout << "\nWein im Behaelter (Inhalt):";
cin >> inhalt;
}while(inhalt < 0 || inhalt > kapazitaet);
behaelter.push_back( * new Behaelter( besitzer, kapazitaet, inhalt));
}
//Liste der Behälter anzeigen
cout << "\n====== Behaelter: " << behaelter.size() << " ========";
for (unsigned int x = 0; x < behaelter.size(); x++){
cout << "\n [" << x << "] ( Besitzer: " << behaelter[x].besitzer << ", Kapazitaet: " << behaelter[x].kapazitaet << ", Inhalt: " << behaelter[x].inhalt << ")";;
}
cout << "\n\nEinen neuen Behaelter hinzufuegen?\n";
cout << " +----- Optionen: -----------+\n";
cout << " | j: Behaelter hinzufuegen |\n";
cout << " | n: Fortfahren |\n";
cout << " +---------------------------+\n";
cin >> c;
}while(c != 'n');
/* Summe der Inhalte insgesamt ermitteln */
for (unsigned int x = 0; x < behaelter.size(); x++){ SummeInhalt += behaelter[x].inhalt; }
cout << "\n\n === Vorgang gestartet, bitte warten... ===\n";
/* Schleifen initiieren */
for (unsigned int sourceID = 0; sourceID < behaelter.size(); sourceID++){
for(unsigned int targetID = 0; targetID < behaelter.size(); targetID++){
if (sourceID != targetID && !behaelter[sourceID].leer() && !behaelter[targetID].voll()){ //Umfüllung formal/logisch korrekt?
//Umfüllung simulieren
vector<Behaelter> tempBehaelter = umfuellen(behaelter, sourceID, targetID);
//Pfad erweitern
vector<StructPfad> tempPfad;
StructPfad temp;
temp.source = sourceID;
temp.target = targetID;
tempPfad.push_back (temp);
if (setZustand (tempBehaelter, tempPfad)){ //Wenn Zustand nicht gesetzt oder überschrieben, Schleife starten
loop(tempBehaelter, tempPfad);
}
}
}
//cout << "\n" << 100/behaelter.size()*sourceID << "%";
}
/* Lösungsweg(e) ausgeben */
cout << "\n\n=== Loesungswege ===";
if (loesungen.size() == 0){
cout << "\nEs wurde kein Loesungsweg gefunden.";
}else{
cout << "\nGefundene Loesungswege: " << loesungen.size();
//Kürzesten Lösungsweg ermitteln
int kuerzester = 1000000;
int kuerzesterID = 0;
for (unsigned int x = 0; x < loesungen.size(); x++){
if (loesungen[x].size() < kuerzester) { kuerzester = loesungen[x].size(); kuerzesterID = x; }
}
//Kürzesten Lösungsweg ausgeben
cout << "\nKuerzester Loesungsweg: " << loesungen[kuerzesterID].size() << " Umfuellungen:";
for (unsigned int x = 0; x < loesungen[kuerzesterID].size(); x++){
cout << "\n[" << loesungen[kuerzesterID][x].source << "] => [" << loesungen[kuerzesterID][x].target << "]";
}
int eingabe = 0;
cout << "\n\n==== Optionen =================";
cout << "\n= 1: Alle Loesungswege anzeigen =";
cout << "\n= Alles andere: Beenden =";
cout << "\n================================\n:";
cin >> eingabe;
if (eingabe == 1){
//Alle Lösungswege ausgeben
cout << "\n----------------- Alle Loesungswege:";
for (unsigned int x = 0; x < loesungen.size(); x++){
cout << "\n\nLoesungsweg Nr. " << x+1 << ": " << loesungen[x].size() << " Umfuellungen";
for(unsigned int y = 0; y < loesungen[x].size(); y++){
cout << "\n[" << loesungen[x][y].source << "] => [" << loesungen[x][y].target << "]";
}
}
}else{
return 0;
}
}
cin.sync();
cout << "\n\n<ENTER> zum Beenden:";
cin.get();
cout << "\n\n";
return 0;
}