477. Total Hamming Distance

本文介绍了一种计算一组整数中所有不同整数对之间的汉明距离总和的方法。通过位运算来统计每一对整数在相同位置上不同比特的数量,并提供了具体的实现代码。

The Hamming distance between two integers is the number of positions at which the corresponding bits are different.

Now your job is to find the total Hamming distance between all pairs of the given numbers.

Example:

Input: 4, 14, 2

Output: 6

Explanation: In binary representation, the 4 is 0100, 14 is 1110, and 2 is 0010 (just
showing the four bits relevant in this case). So the answer will be:
HammingDistance(4, 14) + HammingDistance(4, 2) + HammingDistance(14, 2) = 2 + 2 + 2 = 6.

Note:

  1. Elements of the given array are in the range of to 10^9
  2. Length of the array will not exceed 10^4.

int totalHammingDistance(vector<int>& nums) {
      int i,j,n=nums.size();
      if(!n) return 0;
      int sum=0;
      while(maxnum(nums))
      {
          int c0=0,c1=0;
          for(i=0;i<n;i++)
          {
              if(nums[i]&1)
              c1++;
              else c0++;
              nums[i]>>=1;
          }
          sum+=c1*c0;
      }
      return sum;
    }
    int maxnum(vector<int>nums)
    {
        int r=nums[0];
        for(auto i:nums)
        r=max(r,i);
        return r;
    }

f = { 0: { '0': 2, '1': 1 }, 1: { '00': 2, '01': 3, '10': 2, '11': 0 }, 2: { '000': 0, '001': 1, '010': 1, '011': 0, '100': 2, '101': 0, '110': 0, '111': 0 } } import random def generate_sequence(N): # TODO ''' generates an N random bits (0, 1) sequence Parameters: ----------- N : number of bits in the sequence Returns: -------- sequence: sequence of N bits ''' sequence=[] for i in range(N) : sequence.append(random.choice(['0', '1'])) # generate a random sequence of N bits (0, 1) return sequence def compute_fitness(sequence, K): # TODO ''' computes the fitness of sequence, with respect to K, according to table f Parameters: ----------- sequence : N-bits sequence K : parameter K (0, 1, or 2) Returns: -------- fitness: fitness value of sequence ''' seq = str(sequence) N = len(seq) fitness = 0 if K == 0: # f0: 0->2, 1->1 for bit in seq: fitness += 2 if bit == '0' else 1 elif K == 1: # f1: 00->2, 01->3, 10->2, 11->0 for i in range(N): pair = seq[i] + seq[(i+1) % N] if pair == '00': fitness += 2 elif pair == '01': fitness += 3 elif pair == '10': fitness += 2 elif K == 2: # f2: 000->0 001->1 010->1 011->0 100->2 101->0 110->0 111->0 for i in range(N): triple = seq[i] + seq[(i+1) % N] + seq[(i+2) % N] if triple == '001' or triple == '010': fitness += 1 elif triple == '100': fitness += 2 return fitness def neighbors(sequence): ''' returns all neighbors of sequence () Parameters: ----------- sequence : N-bits sequence Returns: -------- generator of neighbors of sequence ''' for i in range(len(sequence)): if sequence[i] == '0': new = '1' else: new = '0' yield (sequence[:i] + new + sequence[i + 1:]) # generate all neighbors that differ in 1 bit def mean_steps(samples): ''' returns mean of steps taken to find solution (for deterministic) Parameters: ----------- samples : samples of deterministic_hillclimb runs Returns: -------- mean steps ''' # get mean of steps needed to find solution (sum of samples' steps/number of samples) return sum(x[2] for x in samples)/len(samples) def generate_samples(hillclimb_method, K): ''' generates 50 samples (solutions) for the hillclimb method (deterministic/probabilistic) Parameters: ----------- hillclimb_method : deterministic_hillclimb/probabilistic_hillclimb K : parameter K (0, 1, or 2) Returns: -------- generator of samples/solutions (sequence, fitness, number of steps) ''' if K not in [0, 1, 2]: raise Exception("Invalid K") # run for 50 times to get 50 samples/solutions for i in range(50): # generate initial sequence initial_sequence = generate_sequence(N=21) # get solution, its fitness, number of steps taken to find solution x, f_x, s = hillclimb_method(initial_sequence, K) yield (x, f_x, s) def deterministic_hillclimb(sequence, K): # TODO ''' performs deterministic_hillclimb Parameters: ----------- sequence : N-bits sequence K : parameter K (0, 1, or 2) Returns: -------- sequence : optimal/fittest sequence found max_fitness : fitness value of sequence steps: steps it took to reach optimum ''' current_solution = sequence current_value = compute_fitness(current_solution, K) steps = 0 # 记录每次迭代的最佳值 best_values = [current_value] # 迭代寻找更好的解 for i in range(50): # 最多迭代50次 # 生成邻近解 neighbor = neighbors(current_solution,K) neighbor_value = compute_fitness(neighbor, K) # 如果邻近解更优,则更新当前解 if neighbor_value < current_value: current_solution = neighbor current_value = neighbor_value else: pass # 没有改进,保持当前解不变 best_values.append(current_value) # 记录当前最佳值 return current_solution, current_value, best_values # dictionary to save deterministic_hillclimb samples (sequence, max_fitness, steps) deterministic_samples = {} # dictionary to save number of steps to perform probabilistic hillclimb probabilistic_steps = {} # run deterministic_hillclimb, get mean steps for K in [0, 1, 2]: # for each K, generate 50 deterministic_hillclimb solutions, and save them deterministic_samples[K] = list(generate_samples(deterministic_hillclimb, K)) # for each K, save the number of steps to take (10*mean steps taken for deterministic_hillclimb) probabilistic_steps[K] = 10*round(mean_steps(deterministic_samples[K])) def probabilistic_hillclimb(sequence, K): # TODO ''' performs probabilistic_hillclimb Parameters: ----------- sequence : N-bits sequence K : parameter K (0, 1, or 2) Returns: -------- sequence : optimal/fittest sequence found max_fitness : fitness value of sequence steps: steps corresponding to parameter K ''' current_solution = sequence current_value = compute_fitness(current_solution, K) steps = 0 max_iterations = probabilistic_steps[K] import numpy as np for _ in range(max_iterations): # Generate all neighbors neighbor_list = [] for i in range(len(current_solution)): neighbor = list(current_solution) neighbor[i] = '1' if neighbor[i] == '0' else '0' neighbor_list.append(''.join(neighbor)) neighbor_values = [compute_fitness(neighbor, K) for neighbor in neighbor_list] # Calculate selection probabilities (higher fitness gets higher probability) total = sum(neighbor_values) if total == 0: probabilities = [1/len(neighbor_values)] * len(neighbor_values) else: probabilities = [v/total for v in neighbor_values] # Randomly select a neighbor based on probabilities selected_index = np.random.choice(len(neighbor_list), p=probabilities) selected_neighbor = neighbor_list[selected_index] selected_value = neighbor_values[selected_index] # Update current solution if better if selected_value > current_value: current_solution = selected_neighbor current_value = selected_value steps += 1 return current_solution, current_value, steps # dictionary to save probabilistic_hillclimb samples (sequence, max_fitness, steps) probabilistic_samples = {} # run probabilistic_hillclimb for K in [0, 1, 2]: # for each K, generate 50 probabilistic_hillclimb solutions, and save them probabilistic_samples[K] = list(generate_samples(probabilistic_hillclimb, K)) def hamming_distance(sequence1, sequence2): # TODO ''' returns hamming distance between sequence1 and sequence2 Parameters: ----------- sequence1 : N-bits sequence sequence2 : N-bits sequence Returns: -------- distance : hamming distance between sequence1 and sequence2 ''' xor_result = sequence1 ^ sequence2 return bin(xor_result).count('1') import matplotlib.pyplot as plt # 分析并绘制汉明距离 def analyze_and_plot_hamming(N=21, num_runs=50): # 存储结果 hamming_results = {} for K in [0, 1, 2]: print(f"处理 K={K}") hamming_results[K] = {'deterministic': [], 'probabilistic': []} # 存储解 det_solutions = [] prob_solutions = [] # 运行实验 for run in range(num_runs): seq = generate_sequence(N) # 确定性爬山 det_sol, _, _ = deterministic_hillclimb(seq, K) det_solutions.append(det_sol) # 概率性爬山 prob_sol, _, _ = probabilistic_hillclimb(seq, K) prob_solutions.append(prob_sol) # 计算汉明距离 hamming_results[K]['deterministic'] = get_all_hamming_distances(det_solutions) hamming_results[K]['probabilistic'] = get_all_hamming_distances(prob_solutions) # 绘制结果 plot_hamming_results(hamming_results) return hamming_results # 计算所有解对之间的汉明距离 def get_all_hamming_distances(solutions): distances = [] n = len(solutions) for i in range(n): for j in range(i+1, n): dist = hamming_distance(solutions[i], solutions[j]) distances.append(dist) return distances 这是我的全部的代码,请编写 Plot and analyze pairwise hamming distances for all methods and K values的答案代码
最新发布
09-24
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值