creating office shelf

This commit is contained in:
Thomas Weinhold 2023-01-25 23:44:48 +01:00
commit 06d1d3474a
34 changed files with 551 additions and 0 deletions

176
OfficeShelf/zuschnitt.py Normal file
View file

@ -0,0 +1,176 @@
import time
class LengthError(ValueError):
pass
class Cut(object):
def __init__(self, l):
self.Length = l
class CutableRod(object):
def __init__(self):
self.Length = 6000
self.CutThickness = 0
self.Remainder = self.Length
self.Cuts = []
def addCut(self, cut):
if not self.canAddCut(cut):
raise LengthError("Cut.Length=%i, Remainder=%i" % (cut.Length, self.Remainder))
self.Cuts.append(cut)
self.Remainder -= cut.Length
self.Remainder -= self.CutThickness
def copy(self):
new_rod = CutableRod()
new_rod.Length = self.Length
new_rod.CutThickness = self.CutThickness
new_rod.Remainder = self.Remainder
for c in self.Cuts:
new_rod.Cuts.append(c)
return new_rod
def canAddCut(self, cut):
return self.Remainder >= cut.Length
def variety(self):
""" Amount of different cut lengths
"""
lengths = []
for cut in self.Cuts:
if cut.Length not in lengths:
lengths.append(cut.Length)
return len(lengths)
class CutSolution(object):
def __init__(self):
self.Rods = []
def isBetterThan(self, other):
if self.rods() != other.rods():
return self.rods() < other.rods()
elif self.remainder() != other.remainder():
return self.remainder() < other.remainder()
elif self.variety() != other.variety():
return self.variety() < other.variety()
else:
return False
def copy(self):
new_solution = CutSolution()
for r in self.Rods:
new_solution.Rods.append(r.copy())
return new_solution
def variety(self):
variety = 0
for r in self.Rods:
v = r.variety()
if v > 1:
variety += v
return variety
def rods(self):
return len(self.Rods)
def remainder(self):
remainder = 0
for r in self.Rods:
remainder += r.Remainder
return remainder
def print(self, short=False):
if not short:
print("\nSolution")
for idx_r in range(len(self.Rods)):
r = self.Rods[idx_r]
print("Rod ", idx_r, ": ", end="", sep="")
for idx_c in range(len(r.Cuts)):
c = r.Cuts[idx_c]
print(c.Length, " ", end="", sep="")
print("(-", r.Remainder, ")", sep="")
print("Rods=", self.rods(), ", Remainder=", self.remainder(), ", Variety=", self.variety(), sep="")
class CutRequest(object):
def __init__(self):
self.Cuts = []
self.CreatedSolutions = []
def add(self, amount, length):
for i in range(amount):
c = Cut(length)
self.Cuts.append(c)
def _iterate(self, current_solution, remaining_cuts):
if len(remaining_cuts) == 0:
return current_solution
best_solution = None
tested_lengths = []
for idx_try in range(len(remaining_cuts)):
cut = remaining_cuts[idx_try]
# avoid testing same length again
if cut.Length in tested_lengths:
continue
tested_lengths.append(cut.Length)
# create temporary solution for trial
trysol = CutSolution() if current_solution is None else current_solution.copy()
# add cut to temporary solution
if len(trysol.Rods) == 0 or not trysol.Rods[-1].canAddCut(cut):
trysol.Rods.append(CutableRod())
trysol.Rods[-1].addCut(cut)
# create list of remaining other cuts
remaining_cuts_without_try = []
for idx_other in range(len(remaining_cuts)):
if idx_other != idx_try:
cut_other = remaining_cuts[idx_other]
remaining_cuts_without_try.append(cut_other)
# solve for tried remaining cuts
trysol = self._iterate(trysol, remaining_cuts_without_try)
# keep best solution
if best_solution is None or trysol.isBetterThan(best_solution):
best_solution = trysol
if current_solution is None:
print("Better Solution: ", end="")
best_solution.print(True)
return best_solution
def arrangeCuts(self):
time_start = time.time()
solution = self._iterate(None, self.Cuts)
solution.print()
time_stop = time.time()
print("duration: %0.1f" % (time_stop - time_start))
if __name__ == "__main__":
cr = CutRequest()
cr.add(8, 660);
cr.add(16, 620);
cr.add(1, 905);
cr.add(2, 442);
cr.add(2, 848);
cr.add(4, 414);
cr.arrangeCuts()