Оптимизация жадного алгоритма для поиска совпадающих строк в файлахPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Оптимизация жадного алгоритма для поиска совпадающих строк в файлах

Сообщение Anonymous »

в настоящее время у меня есть следующий код:

Код: Выделить всё

from collections import defaultdict
import re

# Parameters
X_percent = 0.93  # Desired coverage percentage (e.g., 93%)
lambda_penalty = 500  # Adjusted penalty
max_attack_time = 3600  # Maximum allowed execution time per attack in seconds
max_total_time = 20 * 3600  # Maximum total execution time in seconds (15 hours)
min_new_plains = 10  # Minimum number of new plains an attack must cover
max_plain_weight = 5  # Maximum weight assigned to any plain
set_a_directory = '/root/setA/'  # Directory containing Set A files
file_b_path = '/root/h.txt'  # Path to File B

# Step 1: Read File B and assign unique IDs to plains
plain_to_id = {}
id_to_plain = {}
with open(file_b_path, 'r') as f:
for line in f:
plain = line.strip()
if plain not in plain_to_id:
plain_id = len(plain_to_id)
plain_to_id[plain] = plain_id
id_to_plain[plain_id] = plain

total_plains = len(plain_to_id)
print(f"Total number of plains in File B: {total_plains}")

# Step 2: Process Set A files and build data structures
attack_info = []
plain_to_attacks = defaultdict(set)  # Maps plain ID to set of attack indices

# Regular expression to extract time from file name
time_pattern = re.compile(r'^(\d+)_')

# Iterate over each file in Set A
for file_name in os.listdir(set_a_directory):
file_path = os.path.join(set_a_directory, file_name)

# Extract execution time from file name
time_match = time_pattern.match(file_name)
if not time_match:
continue  # Skip files that don't match the pattern
execution_time = int(time_match.group(1))

if execution_time > max_attack_time:
continue  # Exclude attacks over the maximum allowed time

with open(file_path, 'r') as f:
lines = f.readlines()
if not lines:
continue  # Skip empty files
attack_command = lines[0].strip()
plains_covered = set()

for line in lines[1:]:
parts = line.strip().split(':')
if not parts:
continue
plain = parts[0].strip()
if plain in plain_to_id:
plain_id = plain_to_id[plain]
plains_covered.add(plain_id)
plain_to_attacks[plain_id].add(len(attack_info))  # Index of this attack

attack_info.append({
'command': attack_command,
'time': execution_time,
'plains': plains_covered,
'index': len(attack_info)
})

num_attacks = len(attack_info)
print(f"Total number of attacks in Set A after filtering: {num_attacks}")

# Step 3: Compute the number of attacks covering each plain (f_p)
plain_cover_count = {}
for plain_id in plain_to_id.values():
cover_count = len(plain_to_attacks[plain_id])
plain_cover_count[plain_id] = cover_count

# Step 4: Assign weights to plains with a maximum weight
plain_weights = {}
for plain_id, f_p in plain_cover_count.items():
if f_p > 0:
plain_weights[plain_id] = min(1.0 / f_p, max_plain_weight)
else:
plain_weights[plain_id] = max_plain_weight

# Step 5: Implement the weighted greedy algorithm with adjusted efficiency
total_plains_needed = int(total_plains * X_percent)
print(f"Number of plains needed for {X_percent*100}% coverage: {total_plains_needed}")

covered_plains = set()
selected_attacks = []
remaining_attacks = set(range(num_attacks))
total_execution_time = 0

while len(covered_plains) < total_plains_needed and remaining_attacks:
best_efficiency = -1
best_attack = None

for i in remaining_attacks:
attack = attack_info[i]
new_plains = attack['plains'] - covered_plains
if len(new_plains) < min_new_plains:
continue  # Skip attacks that cover too few new plains
# Calculate W_i (sum of weights of new plains)
W_i = sum(plain_weights[p] for p in new_plains)
# Adjusted Efficiency E_i
efficiency = (W_i * len(new_plains)) / (attack['time'] + lambda_penalty)
if efficiency >  best_efficiency:
best_efficiency = efficiency
best_attack = i

if best_attack is None:
print("No further attacks can improve coverage.")
break

# Check if adding this attack exceeds the maximum total execution time
if total_execution_time + attack_info[best_attack]['time'] > max_total_time:
print("Reached maximum total execution time limit.")
break

# Select the attack with the highest adjusted efficiency
selected_attacks.append(best_attack)
covered_plains.update(attack_info[best_attack]['plains'])
remaining_attacks.remove(best_attack)
total_execution_time += attack_info[best_attack]['time']

# Optional: Print progress
coverage_percentage = (len(covered_plains) / total_plains) * 100
print(f"Selected attack {best_attack}: Coverage {coverage_percentage:.2f}%, "
f"Total Time: {total_execution_time / 3600:.2f} hours")

# Step 6: Output the results
print("\nSelected Attacks:")
for idx in selected_attacks:
attack = attack_info[idx]
print(f"Attack Index: {idx}")
print(f"Command: {attack['command']}")
print(f"Time: {attack['time']} seconds")
print(f"Plains Covered: {len(attack['plains'])}")
print("-----------------------------")

final_coverage = (len(covered_plains) / total_plains) * 100
print(f"Final Coverage: {final_coverage:.2f}%")
print(f"Total Execution Time: {total_execution_time / 3600:.2f} hours")
print(f"Total Attacks Selected: {len(selected_attacks)}")
У меня есть каталог файлов, мы назовем его набором файлов A. Каждый файл имеет среду выполнения, поскольку за именем файла следует _Randstring.txt. Первая строка в каждом файле представляет собой команду/атаку, а остальные строки представляют собой 2 столбца, разделенные знаком «:», которые создаются этой командой/атакой ( результат другой программы), левую часть можно назвать равниной, правую можно игнорировать. У меня есть еще один отдельный файл, который мы можем назвать файлом B. Он содержит 121 тыс. строк полей. Моя цель в этой программе на Python — найти команды/цепочки атак, в которых файлы Plains соответствуют определенному проценту Plains в файле B в кратчайшие сроки. Равнины в файлах набора A сильно перекрываются, и у меня есть 3600 файлов с общим числом 250 миллионов строк, поэтому время/вычисления являются проблемой, отсюда и жадный алгоритм. В настоящее время мой код на Python не дает наилучших результатов, он выбирает слишком много цепочек атак и слишком большое время выполнения. Могу ли я как-нибудь сделать это лучше, чтобы выбранная им цепочка атак была более «оптимальной», я не против подождать несколько часов и иметь 192-ядерный ПК с 256 ГБ памяти. Спасибо


Подробнее здесь: https://stackoverflow.com/questions/791 ... ross-files
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение

Вернуться в «Python»