hoihoi
Mijn aanpak hierbij is de volgende aanpak:
Probleem is dat ik alleen maar oplossingen genereer waarin nummers meerdere malen worden gebruikt. Dat is niet de bedoeling (tenzij er maar 1 oplossing uit zou komen, dat zou ik wel best vinden
).
Weet iemand waar dit fout gaat? Ik heb mijn constraints al eens gecheckt en genummerd (heck zelfs een plaatje in elkaar gepaint) maar ik zie het gewoon niet. Of maak ik hier een mega-denkfout? Ook lijkt mijn input-data gewoon prima te zijn.
Members only:
Alleen zichtbaar voor ingelogde gebruikers.
Inloggen
Mijn aanpak hierbij is de volgende aanpak:
- Ik bereken voor elk vlak alle mogelijkheden op basis van de artiesten. De nummers van de artiesten heb ik in 2 arrays gezet. Voor elk vlak klopt de structuur; de nummers passen in elkaar en er zitten geen duplicaten tussen.
- Elk vlak levert een setje oplossingen voor dat vlak op in een lijst. De correlatie tussen de vlakken wordt niet gecheckt; er kunnen dus nummers in bijvoorbeeld vlak a en b zitten. Dit gebeurt in de regels 40 tot en met 120. Niet heel mooi, maar ik weet ook niet 1-2-3 hoe ik dit minder lelijk kan coden. Wel check ik hier of elk vlak an sich klopt (met de ifjes in de inner loops)
- Idealiter zou ik alle combinaties van alle vlakken achter elkaar zetten en daarna de constraints tussen de vlakken valideren. Dat is niet heel haalbaar, er zijn 1180*34*29*190*17*163 = 612560585200 combinaties mogelijk, dus ik moet wat prematuur optimaliseren.
- Gevolg is dus dat ik vanaf r140 tot en met r165 een voor een alle vlakken combineer als deze geen constraint schenden. Mocht dat wel het geval zijn dan stop ik al. Constraints hierbij zijn de invulvelden die "over de rand" gaan. Deze constraints heb ik genummerd, en zijn hier te vinden:

Constraint 1 is dus de verbinding tussen vlakken B en C. - Aan het eind controleer ik of de hele oplossing allemaal unieke nummers bevat. Dit doe ik door alle values uit mijn vlakken bij elkaar te kieperen in een list en een set. Als de lengte gelijk is dan zijn alle waarden uniek.
Python:
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
| stones= {(0,3,5),(0,4,6),(0,4,9),(1,1,2),(1,9,6),(2,2,5),(4,0,2),(6,2,7),(7,2,0),(7,3,3),(7,3,7),(7,4,8),(7,9,4),(8,1,2),(8,3,1),(8,8,3),(9,7,0)} beatles={(0,3,9),(0,4,5),(0,7,6),(0,9,2),(1,0,4),(1,2,6),(1,6,8),(3,0,1),(3,0,8),(3,9,3),(4,3,0),(4,4,1),(4,4,6),(5,1,0),(5,9,4),(6,4,3),(6,4,8),(6,5,3),(6,6,0),(7,0,2),(8,2,5),(8,6,3),(8,7,1),(8,7,4),(9,3,5)} oplossingen={"a":[], "b":[], "c":[], "d":[], "e":[], "f":[]} def oplossing_contains_only_unique_values(o): values=list(o["vlak_a"].values())+list(o["vlak_b"].values())+list(o["vlak_c"].values())+list(o["vlak_d"].values())+list(o["vlak_e"].values())+list(o["vlak_f"].values()) if len(values) == len(set(values)): return True return False def pretty_print_oplossing(o): print (" {0} ".format(o["vlak_a"]["ra2"][1])) print (" {0}{1}{2} ".format(o["vlak_a"]["ha1"][0],o["vlak_a"]["ha1"][1],o["vlak_a"]["ha1"][2])) print (" {0}{1}A{2}{3} ".format(o["vlak_a"]["ra4"][1],o["vlak_a"]["ra4"][0],o["vlak_a"]["ra5"][0],o["vlak_a"]["ra5"][1])) print (" {0}{1}{2} ".format(o["vlak_a"]["ha6"][0],o["vlak_a"]["ha6"][1],o["vlak_a"]["ha6"][2])) print (" {0} {1} {2} {3} ".format(o["vlak_a"]["ra4"][1],o["vlak_a"]["ra7"][1],o["vlak_a"]["ra5"][1],o["vlak_a"]["ra2"][1])) print (" {0}{1}{2} {3}{4}{5} {6}{7}{8} {9}{10}{11} ".format(o["vlak_b"]["hb1"][0],o["vlak_b"]["hb1"][1],o["vlak_b"]["hb1"][2],o["vlak_c"]["hc1"][0],o["vlak_c"]["hc1"][1],o["vlak_c"]["hc1"][2],o["vlak_d"]["hd1"][0],o["vlak_d"]["hd1"][1],o["vlak_d"]["hd1"][2],o["vlak_e"]["he1"][0],o["vlak_e"]["he1"][1],o["vlak_e"]["he1"][2])) print ("{0}{1}B{2}{3}{4}C{5}{6}{7}D{8}{9}{10}E{11}{12}".format(o["vlak_e"]["re3"][1],o["vlak_b"]["vb1"][1],o["vlak_b"]["rb3"][0],o["vlak_b"]["rb3"][1],o["vlak_b"]["rb3"][2],o["vlak_c"]["rc3"][0],o["vlak_c"]["rc3"][1],o["vlak_c"]["rc3"][2],o["vlak_d"]["rd3"][0],o["vlak_d"]["rd3"][1],o["vlak_d"]["rd3"][2],o["vlak_e"]["re3"][0],o["vlak_e"]["re3"][1])) print (" {0}{1}{2} {3}{4}{5} {6}{7}{8} {9}{10}{11} ".format(o["vlak_b"]["hb4"][0],o["vlak_b"]["hb4"][1],o["vlak_b"]["hb4"][2],o["vlak_c"]["hc4"][0],o["vlak_c"]["hc4"][1],o["vlak_c"]["hc4"][2],o["vlak_d"]["hd4"][0],o["vlak_d"]["hd4"][1],o["vlak_d"]["hd4"][2],o["vlak_e"]["he4"][0],o["vlak_e"]["he4"][1],o["vlak_e"]["he4"][2])) print (" {0} {1} {2} {3} ".format(o["vlak_b"]["rb5"][1],o["vlak_c"]["rc5"][1],o["vlak_d"]["rd5"][1],o["vlak_e"]["re5"][1])) print (" {0}{1}{2} ".format(o["vlak_f"]["hf1"][0],o["vlak_f"]["hf1"][1],o["vlak_f"]["hf1"][2])) print (" {0}{1}F{2}{3} ".format(o["vlak_b"]["rb5"][1],o["vlak_b"]["rb5"][2],o["vlak_d"]["rd5"][2],o["vlak_d"]["rd5"][1])) print (" {0}{1}{2} ".format(o["vlak_f"]["vf1"][2],o["vlak_e"]["re5"][2],o["vlak_f"]["vf2"][2])) print (" {0} ".format(o["vlak_e"]["re5"][1])) # check of alle elementen in listOfValues uniek zijn def valuesAreUnique(listOfValues): if len(listOfValues) == len(set(listOfValues)): return True else: return False #ha1 = horizontaal , A1. etc. Hierbij geldt dan ook dat ra2 de rij is die over de ribbe gaat en die bij a2 begint. # vlakken B,D en E zijn qua opbouw gelijk, alleen andere invulling stones/beatles # bereken alle mogelijke oplossingen voor vlak A en stop die in oplossingen["a"]. # De if's zitten bewust niet in de innerloop omdat dit de code HEEL veel trager maakt (Veel meer iteraties)... maar wel stukken leesbaarder. for ha1 in beatles: for ha6 in beatles: if ha6 != ha1: for va1 in beatles: if ha1[0]==va1[0] and va1[2]== ha6[0] and valuesAreUnique([ha1,ha6,va1]): for va3 in beatles: if va3[0] == ha1[2] and va3[2]== ha6[2] and valuesAreUnique([ha1,ha6,va1,va3]): for ra2 in beatles: if ra2[0] == ha1[1] and valuesAreUnique([ha1,ha6,va1,va3,ra2]): for ra4 in beatles: if ra4[0] == va1[1] and valuesAreUnique([ha1,ha6,va1,va3,ra2,ra4]): for ra5 in stones: if ra5[0] == va3[1] and valuesAreUnique([ha1,ha6,va1,va3,ra2,ra4,ra5]): for ra7 in stones: if ra7[0] == ha6[1] and valuesAreUnique([ha1,ha6,va1,va3,ra2,ra4,ra5,ra7]): oplossing={"ha1":ha1, "ha6":ha6, "va1":va1, "va3":va3, "ra2":ra2, "ra4":ra4, "ra5":ra5, "ra7":ra7} oplossingen["a"].append(oplossing) for hb1 in beatles: for hb4 in beatles: if valuesAreUnique([hb1,hb4]): for vb1 in beatles: if vb1[0] == hb1[0] and vb1[2]== hb4[0] and valuesAreUnique([hb1,hb4,vb1]): for vb2 in stones: if vb2[0] == hb1[2] and vb2[2]== hb4[2] and valuesAreUnique([hb1,hb4,vb1,vb2]): for rb3 in stones: if rb3[0] == vb2[1] and valuesAreUnique([hb1,hb4,vb1,vb2,rb3]): for rb5 in stones: if rb5[0] == hb4[1] and valuesAreUnique([hb1,hb4,vb1,vb2,rb3,rb5]): oplossing={"hb1":hb1, "hb4":hb4, "vb1":vb1, "vb2":vb2, "rb3":rb3, "rb5":rb5} oplossingen["b"].append(oplossing) for hc1 in stones: for hc4 in beatles: if valuesAreUnique([hc1,hc4]): for vc1 in stones: if vc1[0] == hc1[0] and vc1[2]==hc4[0] and valuesAreUnique([hc1,hc4,vc1]): for vc2 in stones: if vc2[0] == hc1[2] and vc1[2]==hc4[2] and valuesAreUnique([hc1,hc4,vc1,vc2]): for rc3 in beatles: if rc3[0] == vc2[1] and valuesAreUnique([hc1,hc4,vc1,vc2,rc3]): for rc5 in stones: if rc5[0] == hc4[1] and valuesAreUnique([hc1,hc4,vc1,vc2,rc3,rc5]): oplossing={"hc1":hc1, "hc4":hc4, "vc1":vc1, "vc2":vc2, "rc3":rc3, "rc5":rc5} oplossingen["c"].append(oplossing) for hd1 in beatles: for hd4 in beatles: if valuesAreUnique([hd1,hd4]): for vd1 in beatles: if vd1[0] == hd1[0] and vd1[2]== hd4[0] and valuesAreUnique([hd1,hd4,vd1]): for vd2 in beatles: if vd2[0] == hd1[2] and vd2[2]== hd4[2] and valuesAreUnique([hd1,hd4,vd1,vd2]): for rd3 in stones: if rd3[0] == vd2[1] and valuesAreUnique([hd1,hd4,vd1,vd2,rd3]): for rd5 in stones: if rd5[0] == hd4[1] and valuesAreUnique([hd1,hd4,vd1,vd2,rd3,rd5]): oplossing={"hd1":hd1, "hd4":hd4, "vd1":vd1, "vd2":vd2, "rd3":rd3, "rd5":rd5} oplossingen["d"].append(oplossing) for he1 in beatles: for he4 in beatles: if valuesAreUnique([he1,he4]): for ve1 in stones: if ve1[0] == he1[0] and ve1[2]== he4[0] and valuesAreUnique([he1,he4,ve1]): for ve2 in stones: if ve2[0] == he1[2] and ve2[2]== he4[2] and valuesAreUnique([he1,he4,ve1,ve2]): for re3 in beatles: if re3[0] == ve2[1] and valuesAreUnique([he1,he4,ve1,ve2,re3]): for re5 in stones: if re5[0] == he4[1] and valuesAreUnique([he1,he4,ve1,ve2,re3,re5]): oplossing={"he1":he1, "he4":he4, "ve1":ve1, "ve2":ve2, "re3":re3, "re5":re5} oplossingen["e"].append(oplossing) for hf1 in beatles: for vf1 in beatles: if valuesAreUnique([hf1,vf1]) and hf1[0] == vf1[0]: for vf2 in beatles: if vf2[0]== hf1[2] and valuesAreUnique([hf1,vf1,vf2]): oplossing={"hf1":hf1,"vf1":vf1,"vf2":vf2} oplossingen["f"].append(oplossing) print ("Oplossingen gevonden in A: {0}".format(len(oplossingen["a"]))) print ("Oplossingen gevonden in B: {0}".format(len(oplossingen["b"]))) print ("Oplossingen gevonden in C: {0}".format(len(oplossingen["c"]))) print ("Oplossingen gevonden in D: {0}".format(len(oplossingen["d"]))) print ("Oplossingen gevonden in E: {0}".format(len(oplossingen["e"]))) print ("Oplossingen gevonden in F: {0}".format(len(oplossingen["f"]))) # oplossingen per kubus waarbij de we dus de 6 vlakken matchen # de vergelijkingen staan met plaatje en al hier: # https://github.com/boudewijne/nbv/blob/master/nbv_2014/beatles-kubus.png # we gaan nu kijken welke vlakken met elkaar matchen om een kubus te maken. kubus_oplossingen=[] for vlak_a in oplossingen["a"]: for vlak_b in oplossingen["b"]: # check 2 if vlak_a["ra4"][2] == vlak_b["hb1"][1] : for vlak_c in oplossingen["c"]: # check 1 + 3 if vlak_b["rb3"][2] == vlak_c["vc1"][1] and vlak_a["ra7"][2] == vlak_c["hc1"][1]: for vlak_d in oplossingen["d"]: # check 4+5: (765k oplossingen) if vlak_c["rc3"][2]==vlak_d["vd1"][1] and vlak_a["ra5"][2]==vlak_d["hd1"][1]: for vlak_e in oplossingen["e"]: # check 6 + 7 (17604 oplossingen) if vlak_a["ra2"][2]==vlak_e["he1"][1] and vlak_e["re3"][2]==vlak_b["vb1"][1]: #check 8 (4890 oplossingen) if vlak_d["rd3"][2] == vlak_e["ve1"][1]: for vlak_f in oplossingen["f"]: # check 9 (615 oplossingen) if vlak_b["rb5"][2] == vlak_f["vf1"][1]: # check 10 (78 oplossingen) if vlak_d["rd5"][2] == vlak_f["vf2"][1]: # check 11 (18 oplossingen) if vlak_c["rc5"][2] == vlak_f["hf1"][1]: oplossing={"vlak_a":vlak_a, "vlak_b":vlak_b, "vlak_c":vlak_c, "vlak_d":vlak_d, "vlak_e":vlak_e, "vlak_f":vlak_f} kubus_oplossingen.append(oplossing) print ("Kubus plossingen gevonden: {0}".format(len(kubus_oplossingen))) kubus_oplossingen=list(filter(lambda x: oplossing_contains_only_unique_values(x), kubus_oplossingen)) print ("Kubus plossingen gevonden met unieke waarden: {0}".format(len(kubus_oplossingen))) print_counter=1 for oplossing in kubus_oplossingen: print ("\nOplossing {}".format(print_counter)) #pretty_print_oplossing(oplossing) print (" {0}{1}{2} ".format(oplossing["vlak_f"]["vf1"][2],oplossing["vlak_e"]["re5"][2],oplossing["vlak_f"]["vf2"][2])) print_counter+=1 |
Probleem is dat ik alleen maar oplossingen genereer waarin nummers meerdere malen worden gebruikt. Dat is niet de bedoeling (tenzij er maar 1 oplossing uit zou komen, dat zou ik wel best vinden
Weet iemand waar dit fout gaat? Ik heb mijn constraints al eens gecheckt en genummerd (heck zelfs een plaatje in elkaar gepaint) maar ik zie het gewoon niet. Of maak ik hier een mega-denkfout? Ook lijkt mijn input-data gewoon prima te zijn.