পাইথন 3, স্কোর = 4/3 = 1.33… (এন = 4) স্কোর = 1.4 (এন = 7)
আপডেট: "স্থিতিশীল" সলভার সেটগুলিতে ব্রুট-ফোর্স অনুসন্ধান কার্যকর করা হয়েছে এবং একটি নতুন ফলাফল পেয়েছে
আমি মনে করি গতিশীল সমাধানকারীদের অনুসন্ধান করে এটি আরও উন্নত করা যেতে পারে, যা আরও সিদ্ধান্তের জন্য ভারী ফলাফল ব্যবহার করতে পারে।
এখানে একটি পাইথন কোড রয়েছে যা ছোট n
মানগুলির জন্য সমস্ত স্ট্যাটিক সলভারগুলির মাধ্যমে অনুসন্ধান করে (এই সমাধানকারীরা সর্বদা একই মুদ্রা সেটগুলি ওজন করে, সুতরাং "স্থিতিশীল" নাম) এবং তাদের পরিমাপের ফলাফলগুলি কেবলমাত্র একটি মিলে যাওয়া মুদ্রাকে অনুমতি দেয় তা পরীক্ষা করে তাদের সবচেয়ে খারাপ পদক্ষেপের সংখ্যা নির্ধারণ করে by সব ক্ষেত্রে সেট। এছাড়াও, এটি এ পর্যন্ত পাওয়া সেরা স্কোর এবং প্রাথমিক প্রুনেস সলভারগুলির উপর নজর রাখে যা দেখিয়েছিল যে তারা অবশ্যই আগের চেয়ে বেশি খারাপ ছিল। এটি একটি গুরুত্বপূর্ণ অপটিমাইজেশন ছিল, অন্যথায় আমি n
= 7 দিয়ে এই ফলাফলের জন্য অপেক্ষা করতে পারিনি ((তবে এটি স্পষ্টভাবে এখনও খুব ভালভাবে অনুকূলিত হয়নি)
এটি কীভাবে কাজ করে তা পরিষ্কার না থাকলে প্রশ্ন জিজ্ঞাসা করতে নির্দ্বিধায় ...
#!/usr/bin/env python3
import itertools
from functools import partial
def get_all_possible_coinsets(n):
return tuple(itertools.product(*itertools.repeat((-1, 1), n)))
def weigh(coinset, indexes_to_weigh):
return sum(coinset[x] for x in indexes_to_weigh)
# made_measurements: [(indexes, weight)]
def filter_by_measurements(coinsets, made_measurements):
return filter(lambda cs: all(w == weigh(cs, indexes) for indexes, w in made_measurements), coinsets)
class Position(object):
def __init__(self, all_coinsets, coinset, made_measurements=()):
self.all_coinsets = all_coinsets
self.made_measurements = made_measurements
self.coins = coinset
def possible_coinsets(self):
return tuple(filter_by_measurements(self.all_coinsets, self.made_measurements))
def is_final(self):
possible_coinsets = self.possible_coinsets()
return (len(possible_coinsets) == 1) and possible_coinsets[0] == self.coins
def move(self, measurement_indexes):
measure_result = (measurement_indexes, weigh(self.coins, measurement_indexes))
return Position(self.all_coinsets, self.coins, self.made_measurements + (measure_result,))
def get_all_start_positions(coinsets):
for cs in coinsets:
yield Position(coinsets, cs)
def average(xs):
return sum(xs) / len(xs)
class StaticSolver(object):
def __init__(self, measurements):
self.measurements = measurements
def choose_move(self, position: Position):
index = len(position.made_measurements)
return self.measurements[index]
def __str__(self, *args, **kwargs):
return 'StaticSolver({})'.format(', '.join(map(lambda x: '{' + ','.join(map(str, x)) + '}', self.measurements)))
def __repr__(self):
return str(self)
class FailedSolver(Exception):
pass
def test_solvers(solvers, start_positions, max_steps):
for solver in solvers:
try:
test_results = tuple(map(partial(test_solver, solver=solver, max_steps=max_steps), start_positions))
yield (solver, max(test_results))
except FailedSolver:
continue
def all_measurement_starts(n):
for i in range(1, n + 1):
yield from itertools.combinations(range(n), i)
def next_measurement(n, measurement, include_zero):
shifted = filter(lambda x: x < n, map(lambda x: x + 1, measurement))
if include_zero:
return tuple(itertools.chain((0,), shifted))
else:
return tuple(shifted)
def make_measurement_sequence(n, start, zero_decisions):
yield start
m = start
for zero_decision in zero_decisions:
m = next_measurement(n, m, zero_decision)
yield m
def measurement_sequences_from_start(n, start, max_steps):
continuations = itertools.product(*itertools.repeat((True, False), max_steps - 1))
for c in continuations:
yield tuple(make_measurement_sequence(n, start, c))
def all_measurement_sequences(n, max_steps):
starts = all_measurement_starts(n)
for start in starts:
yield from measurement_sequences_from_start(n, start, max_steps)
def all_static_solvers(n, max_steps):
return map(StaticSolver, all_measurement_sequences(n, max_steps))
def main():
best_score = 1.0
for n in range(1, 11):
print('Searching with N = {}:'.format(n))
coinsets = get_all_possible_coinsets(n)
start_positions = tuple(get_all_start_positions(coinsets))
# we are not interested in solvers with worst case number of steps bigger than this
max_steps = int(n / best_score)
solvers = all_static_solvers(n, max_steps)
succeeded_solvers = test_solvers(solvers, start_positions, max_steps)
try:
best = min(succeeded_solvers, key=lambda x: x[1])
except ValueError: # no successful solvers
continue
score = n / best[1]
best_score = max(score, best_score)
print('{}, score = {}/{} = {}'.format(best, n, best[1], score))
print('That\'s all!')
def test_solver(start_position: Position, solver, max_steps):
p = start_position
steps = 0
try:
while not p.is_final():
steps += 1
if steps > max_steps:
raise FailedSolver
p = p.move(solver.choose_move(p))
return steps
except IndexError: # solution was not found after given steps — this solver failed to beat score 1
raise FailedSolver
if __name__ == '__main__':
main()
আউটপুট:
Searching with N = 1:
(StaticSolver({0}), 1), score = 1/1 = 1.0
Searching with N = 2:
(StaticSolver({0}, {0,1}), 2), score = 2/2 = 1.0
Searching with N = 3:
(StaticSolver({0}, {0,1}, {0,1,2}), 3), score = 3/3 = 1.0
Searching with N = 4:
(StaticSolver({0,1}, {1,2}, {0,2,3}, {0,1,3}), 3), score = 4/3 = 1.3333333333333333
Searching with N = 5:
Searching with N = 6:
Searching with N = 7:
(StaticSolver({0,2}, {0,1,3}, {0,1,2,4}, {1,2,3,5}, {0,2,3,4,6}), 5), score = 7/5 = 1.4
Searching with N = 8:
Searching with N = 9:
(I gave up waiting at this moment)
এই লাইনটি
(StaticSolver({0,2}, {0,1,3}, {0,1,2,4}, {1,2,3,5}, {0,2,3,4,6}), 5), score = 7/5 = 1.4
পাওয়া সেরা সমাধানকারীটিকে উন্মোচিত করে। {}
ধনুর্বন্ধনী মধ্যে সংখ্যা হ'ল প্রতিটি পদক্ষেপে ওজন ডিভাইস রাখা কয়েন সূচক।