Это стохастическая матрица?


24

Стохастическая матрица является матрицей вероятностей , используемых в контексте цепей Маркова.

Правая стохастическая матрица представляет собой матрицу , где каждая строка суммы в 1.

Влево стохастическая матрица представляет собой матрицу , где каждый столбец суммы в 1.

Дважды стохастическая матрица представляет собой матрицу , где каждая строка и каждый столбец сумм к 1.

В этой задаче мы будем представлять вероятности в процентах, используя целые числа . В этом случае строка или столбец должны быть суммами, 100а не суммой 1.

Ваша цель состоит в том, чтобы написать программу или функцию, которая, учитывая квадратную матрицу целых чисел в качестве входных данных, выводит одно из четырех значений, указывающих, что матрица является либо стохастической справа, либо стохастической слева, либо стохастической с двойной точностью, либо ни одной из них.

вход

Вы можете использовать любое правильное представление матрицы, которое является естественным для вашего языка для ввода. Например, список списков, строка значений, разделенных запятыми, со строками, разделенными переносами строк и т. Д.

Входная матрица всегда будет квадратной и будет содержать только неотрицательные целые числа. Входная матрица всегда будет как минимум 1×1.

Вы можете передать ввод, используя STDINаргумент функции или что-то подобное.

Выход

Вы должны выбрать четыре различных выхода, которые соответствуют правому стохастику , левому стохастику , дважды стохастическому или ни одному из них . Эти выходы должны быть постоянными независимо от того, какой вход передается. Ваша программа может не возвращать разные выходные данные для одного и того же случая, например, говоря, что любое отрицательное число не соответствует ни одному из этих случаев. , недопустимо.

Короче говоря, между выходными данными и четырьмя возможными случаями должно быть соответствие 1: 1. Некоторые примеры этих четырех выходов будут {1, 2, 3, 4}или {[1,0], [0,1], [1,1], [0,0]}или даже {right, left, doubly, none}.

Пожалуйста, укажите в своем ответе четыре выхода, которые использует ваша программа.

Если матрица является дважды стохастической, то вы должны вернуть результат, соответствующий дважды стохастическому, а не правому или левому стохастику.

Вы можете распечатать вывод STDOUT, вернуть его из функции или чего-либо подобного.

Контрольные примеры

[100]               => Doubly stochastic

[42]                => None of those

[100  0  ]          => Doubly stochastic
[0    100]

[4   8   15]
[16  23  42]        => Left stochastic
[80  69  43]

[99  1 ]            => Right stochastic
[2   98]

[1   2   3   4 ]
[5   6   7   8 ]    => None of those
[9   10  11  12]
[13  14  15  16]

счет

Это , поэтому выигрывает самый короткий ответ в байтах.


Могу ли я сначала принять данные, определяющие размер матрицы?
HyperNeutrino

@AlexL. Нет, было бы несправедливо менять спецификации на данный момент.
Роковая

Ответы:


9

05AB1E , 13 11 10 байт

Стохастик справа: Стохастик [0,1]
слева : Стохастик [1,0]
вдвойне: [1,1]
Ни один из них: [0,0]

Dø2FOTnQPˆ

Попробуйте онлайн!

объяснение

D            # duplicate input
 ø           # transpose the copy
  2F         # 2 times do (once for each matrix)
    O        # sum of the rows
     TnQ     # is equal to 100
        P    # product
         ˆ   # add to global list
             # implicitly print global list at the end of the program

14

Haskell, 57 55 байт

import Data.List
s a=all((==100).sum)<$>[transpose a,a]

Ввод типа (Eq a, Num a) => [[a]]. Вывод логического списка[left-stochastic, right-stochastic]

Спасибо @proudhaskeller за сохранение 2 байта


Не могли бы вы сохранить несколько байтов, сделав функцию безусловной? например, с [transpose,id]<*>(тогда вы могли бы опустить, так s a=как разрешены любые функции)
flawr

@flawr , возможно, но [transpose,id]<*>имеет тип [[[a]]]->[[[a]]], который нуждается в другом слое mapи pure/ return/ (:[])или вводе типа [[[Int]]], которая не является естественным. Лучшее, что я получилmap(all(==100).map sum).(<$>[transpose,id]).flip id
Angs

Ах да, спасибо за объяснение!
Flawr

Как насчет all((==100).sum)вместо all(==100).map sum?
гордый haskeller

@proudhaskeller конечно! allделает отображение в себе.
Angs

11

R, 55 байт

function(m)c(all(colSums(m)==100),all(rowSums(m)==100))

Безымянная функция, где mпредполагается R-матрица.

Выход:

  • [1] TRUE FALSE: Левый стохастик
  • [1] FALSE TRUE: Правильный стохастик
  • [1] TRUE TRUE: Вдвойне
  • [1] FALSE FALSE: Никто

any(colSums(m)-100)и аналогичным образом, rowSumsпри сбросе всех выходных данных вы потеряете два байта, поэтому, если вы хотите сохранить их, вы всегда можете поставить !перед -1байтом нетто .
Джузеппе

7

Октава, 35 34 32 31 байт

@(n)any([sum(n);sum(n')]-100,2)

Назовите это так:

f(100)
f(42)
f([4,8,15; 16,23,42; 80,69,43])
f([99,1;2,98])
f([1,2,3,4;5,6,7,8;9,10,11,12;13,14,15,16])

Проверьте это здесь.

Изначально, благодаря flawr, сэкономили 2 байта, но выбрали другой подход, который был на 1 байт короче.

Это выводит следующее для разных случаев:

0    Doubly
0    

1    None
1

0    Left
1

1    Right
0

Последнее ,2было бы ненужным, если бы не были включены однозначные цифры. Кроме того, если бы это суммировалось 1вместо 100(как могло бы быть), это сохраняло бы другие 4байты.


6

Mathematica 29 байт

{}⋃Tr/@#=={100}&/@{#,#}&

заменяя символ U = U + F3C7 = [\ Transpose]. Этот фрагмент кода будет правильно вставлен в Mathematica.

То же соглашение об истинности с {lefttruth, righttruth} как выход


{}⋃сохраняет один байтUnion@
A Simmons

@ASimmons, спасибо за совет! Вставьте его и исправьте ошибку в моей сумме байтов.
Келли Лоудер

Также я думаю, что если вы сделаете вывод {righttruth, lefttruth}, то замена Total@на Tr/@сэкономит еще 2 байта.
Симмонс

Или эквивалентно поменять местами две матрицы, так что решение становится{}⋃Tr/@#=={100}&/@{#,#}&
Симмонс

@ASimmons, да, это спасло еще 2. Спасибо!
Келли Лоудер

6

k, 21 19 байтов

{min'100=+/'(x;+x)}

Выход

  • 00b никто
  • 10b слева
  • 01b правильно
  • 11b и то и другое

Пример:

k)f:{min'100=+/'(x;+x)} //store function as f
k)f(100 0;98 2)
01b

редактировать: уменьшить количество байтов на 3 - функция не должна быть заключена в лямбду

редактировать: уменьшить счет на 2 - H / T @Simon Major


1
На самом деле вы можете сохранить байт, заключив его в лямбду: {min'100 = + / '(x; +: x)}
Симон Майор

5

MATL , 12 байт

sG!sv!100=XA

Выход - два ноль / одно значение. Первый указывает, является ли матрица лево-стохастической, второй - если она стохастическая.

Попробуйте онлайн! Или проверьте все тестовые случаи

s      % Implicitly input N×N matrix. Sum of each column. Gives a 1×N vector
G!     % Push input transposed
s      % Sum of each column. Gives a 1×N vector
v      % Concatenate vertically. Gives a 2×N matrix
!      % Transpose. N×2
100=   % Does each entry equal 100?
XA     % True for columns that contain only "true". Gives 1×2 vector. Implicitly display

Человек 100 был дорогим, хороший ответ, хотя.
Волшебная Урна Осьминога

5

Mathematica, 46 43 байта

AllTrue[#==100&]/@Apply[Plus,{#,#},{1}]&

Как и с другими ответами, результаты

{False, False} для нестохастических

{True, False} для левой стохастики

{False, True} для правильного стохастика

{True, True} для дважды стохастического

Сохранено 3 байта путем переключения на операторную форму AllTrue


Используйте U + F3C7 (частное использование) для\[Transpose]
u54112

Я подумал об этом, но подумал, что это было менее поучительно
Симмонс

Также есть дополнительный @в конце
u54112

4

PHP, 104 байта

function($a){for($s=array_sum;$a[+$i];)$o|=$s($a[+$i])!=100|($s(array_column($a,+$i++))!=100)*2;echo$o;}

Анонимная функция, которая отображает 0 => оба, 1 => слева, 2 => справа, 3 => ни того, ни другого.
Используйте как:

php -r "$c=function($a){for($s=array_sum;$a[+$i];)$o|=$s($a[+$i])!=100|($s(array_column($a,+$i++))!=100)*2;echo$o;};$c(json_decode($argv[1]));" "[[4,8,15],[16,23,42],[80,69,43]]"

Версия программы командной строки в 114 байтов:

for($a=json_decode($argv[1]);$a[+$i];)$o|=($s=array_sum)($a[+$i])!=100|($s(array_column($a,+$i++))!=100)*2;echo$o;

Используется как:

 php -r "for($a=json_decode($argv[1]);$a[+$i];)$o|=($s=array_sum)($a[+$i])!=100|($s(array_column($a,+$i++))!=100)*2;echo$o;" "[[4,8,15],[16,23,42],[80,69,43]]"

4

Python 2, 70 64 байта

В этом нет ничего сумасшедшего, просто использование сплаттинга zipдля транспонирования матрицы :) Выводы следующие:

0 - not stochastic
1 - right stochastic
2 - left stochastic
3 - doubly stochastic

А вот и код :)

k=lambda m:all(sum(x)==100for x in m)
lambda n:k(n)+2*k(zip(*n))

Является ли звезда в (* на ошибку?
Hhh

1
@hhh Нет, это splatоператор :) По сути, это то, что позволяет мне транспонировать матрицу :)
Kade

4

C #, 205 203 183 байта

Golfed:

int F(int[,]m){int x,i,j,r,c,e,w;x=m.GetLength(0);e=w=1;for(i=0;i<x;i++){r=c=0;for(j=0;j<x;j++){r+=m[i,j];c+=m[j,i];}if(r!=100)e=0;if(c!=100)w=0;}return e==1&&w==1?3:e==1?1:w==1?2:4;}

Разоблаченный с комментариями:

    int F(int[,] m)
    {
        //x - matrix size
        //i, j - loop control variables
        //r, c - row/column sum
        //e, w - east/west, pseudo-bool values indicate right/left stochastic
        int x, i, j, r, c, e, w;
        x = m.GetLength(0);
        e = w = 1;

        for (i = 0; i < x; i++)
        {
            r = c = 0;

            for (j = 0; j < x; j++)
            {
                r += m[i, j];
                c += m[j, i];
            }

            if (r != 100)
                e = 0;

            if (c != 100)
                w = 0;
        }

        return e == 1 && w == 1 ? 3 : e == 1 ? 1 : w == 1 ? 2 : 4;
    }

Выходной ключ: 1 - правый стохастик 2 - левый стохастик 3 - двойной стохастик 4 - нет

Попробуйте это: http://rextester.com/PKYS11433

EDIT1: r=0;c=0; =>r=c=0;

EDIT2: вложенные троичные операторы. Кредиты идут в @ Йодле.


2
if(e==1&&w==1)return 3;if(e==1)return 1;return w==1?2:4;Поскольку eи wможет быть только 1 или 0, его можно изменить return w<<1|e;и переопределить none == 0.
Ссылка Ng

1
Вы можете сократить свой на 30, если превратите некоторые из этих ifоператоров в троичные операции и просто вернете целое число в конце. Не знаю, если я должен опубликовать свое решение, так как оно очень похоже.
Йодль

@LinkNg Очень мило. Я не хочу писать код без понимания. Я не знаком с бинарными операторами.
Paldir

@Yodle Спасибо, я изменил свое решение. Не стесняйтесь размещать свои, даже если это очень похоже.
Paldir

3

JavaScript (ES6), 83 байта

a=>[a.some(a=>a.reduce((l,r)=>l-r,100)),a.some((_,i)=>a.reduce((l,a)=>l-a[i],100))]

Наоборот, это не только выводит правосторонний стохистический результат слева, но и логические значения также инвертируются, поэтому вывод [false, true]все еще означает правостороннюю стохистику.


3

C # 6, 130 байт

using System.Linq;bool[]F(int[][]a)=>new[]{a.Where((_,i)=>a.Select(x=>x[i]).Sum()==100).Count()==a.Length,a.All(x=>x.Sum()==100)};

{False, False}для нестохастического
{True, False}для левого стохастического
{False, True}для правого стохастического
{True, True} для дважды стохастического

repl.it demo

Ungolfed

bool[]F(int[][]a)=>
    // Return new array of two bools. Array type is inferred from arguments
    new[]
    {
        // Left:
        // Count the no. of columns which sums up to 100
        a.Where((_,i)=>a.Select(x=>x[i]).Sum()==100).Count()
            // Then check if no. of such columns equal to total column count
            ==a.Length,
        // Right: Do all rows sum up to 100?
        // Can't use this trick for left because no overload of All() accept Func<TSource,int,bool> like Where() does
        a.All(x=>x.Sum()==100)
    };


2

Пип , 17 байт

В неожиданном повороте это представление является функцией.

{[h]=UQ$+_M[Zaa]}

Возвращает список из двух 0/ 1значений: [0 0]= не стохастический [0 1]= влево стохастический [1 0]= правые стохастической [1 1]= бистохастический. Попробуйте онлайн!

объяснение

{               }  A function:
              a    Function argument (nested list)
           [Za ]   Create a list containing a's transpose and a
          M        Map this function to each of the above:
       $+_           Sum down the columns
     UQ              Get unique elements
 [h]=                If stochastic, the result should be [100]

2

Дьялог АПЛ , 16 байт

{∧/100=+/↑⍵(⍉⍵)}

{ }прямое определение функции (он же "dfn"), является аргументом

⍵(⍉⍵) матрица наряду с ее транспозицией

смешать их в один массив 2 × n × n

+/ сумма по последней оси, получить матрицу 2 × n

100= какие элементы равны 100 (логические 0 0)

∧/ «и» -редукция по последней оси, получить 2 логических значения для левой, правой стохастической


2

С ++ 14, 139 136 133 130 байт

-3 байта для s=M.size(), -3 байта для возврата по ссылочному параметру, -3 байта для безымянной лямбды

[](auto M,int&r){int a,b,i,j,s=M.size();r=3;for(i=-1;++i<s;){for(j=-1,a=b=0;++j<s;a+=M[i][j],b+=M[j][i]);r&=(a==100)+2*(b==100);}}

Предполагается, что ввод будет похож vector<vector<int>>. Возвращает 3,2,1,0 для дважды, слева, справа, без стохастики.

Ungolfed:

auto f=
[](auto M, int& r){
  int a,b,i,j,s=M.size();
  r=3;
  for(i=-1;++i<s;){
    for(j=-1,a=b=0;++j<s;
      a+=M[i][j],
      b+=M[j][i]);
    r&=(a==100)+2*(b==100);
  }
}
;
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.